Creating a Gmod Lua Timer - timer

I was wondering how to create a timer in lua that works also in servers with no players on.
Timer.Simple or Timer.Create don't work, they need CurTime().
How could I do it?

Well one option is always to set the convar sv_hibernate_think to 1.
That is also the option provided on the official Wiki as shown here.

Depends on what's available. You likely can't import any extra libs, and Lua's capabilities have 'prolly been nerfed.
If standard clock capabilities still exist, you can do something with
local init, pause = os.clock(), 3
while os.clock() -init < pause do end
I don't know your exact use; could be made into a function if need be. That will eat up clock cycles. If coroutines exist, you might be able to have another script runing in the background while occasionally checking on timer.

Related

How to call an event after x minutes while still running?

I'm quite new in programming, so please bear with me.
I'm working with a microcontroller, therefore I'm using Microchip Studio.
My code is simplified build up like this:
While(1){
if(ErrorFlag==1)
timer_restart++;
else
timer_restart=0;
if (time_restart == 600000)
restart()
//Remaining code
} // EndWhile
My problem is that I would like to call restart() after around 5 minutes. Right now I have no clue how long it takes. Is there a better way to implement that?
I've tried to find out what time one-WhileLoop-Rotation requires with the clock() function. But I'm getting a ErrorMessage "undefined reference". I think that Microchip Studio does not know those functions.
I maybe could use something like:
while(1){
while(ErrorFlag==1){
delay_ms(5000);
restart();
ErrorFlag=0;
}}
But then the rest of the code is interrupted. Is there any advice someone can give me?
"Busy-while" or "busy-delay" are rarely ever the correct solution. Apart from being inaccurate, they also lock up your CPU at 100% and consuming current needlessly.
You need to use the actual on-chip hardware peripheral timers, either by polling a timer flag on regular basis or by using interrupts. As for how to do that, it depends on the specific MCU.

U-Boot prompt timeout

I'm accessing U-boot's console via serial connection and when u-boot prompt me to enter commands, it seems that I have limited time to do that. I want to enter several commands, but I need more time.
Does anyone experienced such an issue and how can I increase that time (if that is the problem)?
U-Boot's Boot Retry Mechanism, AKA, Preventing Eternally Hung Boot
Having the U-Boot command prompt timeout can actually be desirable behavior, as without this an inadvertent interruption of the boot could leave a system permanently stuck at the U-Boot prompt until the next power cycle.
Given this, in addition to the hardware watchdog possibility mentioned by Tom Rini, it is also possible that your U-Boot build could be set up with the "Boot Retry" feature - and not unlikely that others finding this page will (as I was) be seeking a way to intentionally cause such behavior.
If you see the following, you likely have boot retry:
Timeout waiting for command
resetting ...
Three build-time configuration options and one run-time variable govern boot retry:
CONFIG_BOOT_RETRY_TIME is the default number of seconds without a valid command, after which the (still interruptible) auto boot sequence will be automatically re-run.
bootretry is an environment variable containing the current delay in effect. Negative values mean boot retry will not occur. Unfortunately, this value is only sampled on startup - changing it will not prevent boot retry in the current session.
CONFIG_BOOT_RETRY_MIN is a safety limit on the above environment variable, however it appears that negative or disabling values get a pass through the check. This makes it harder to deduce the intended usage of this setting; if not explicitly set in the config it is assigned the value of CONFIG_BOOT_RETRY_TIME.
CONFIG_RESET_TO_RETRY is an option which means that instead of directly resuming the autoboot sequence, the processor will reboot. This may in fact be the only supported way of using boot retry; it seems that a build error asking you to set it results if you do not.
Critical note: Except in a few patched forks, these are not KConfig options which you can put in your board_defconfig, but rather #define's which must go in a C header file of the code itself, specifically one applicable to the system configuration which you build.
Disable Boot Retry
If you saw the above timeout message and suspect that boot retry is at fault, there are a few possible ways to stop it.
First, if your u-boot supports saving environment variables persistently, you could
u-boot> setenv bootretry -1
u-boot> saveenv
and then reboot. A few systems may still have an ancient bug which prevents parsing a negative value, in which case you could use a large positive one, such as 3600 seconds (one hour).
But unfortunately, you cannot do this without saving the environment variable, as it is only read on startup. To enable using the environment variable as a temporary override for maintenance, you could do something like this to re-evaluate it each time the timeout is reset by a valid command:
--- a/common/bootretry.c
+++ b/common/bootretry.c
## -39,6 +39,7 ## void bootretry_init_cmd_timeout(void)
*/
void bootretry_reset_cmd_timeout(void)
{
+ bootretry_init_cmd_timeout(); //pickup any environment change
endtime = endtick(retry_time);
}
This seems to work, in that you can set the bootretry to -1 for extended manual maintenance. It also seems you can set the bootretry to longer than default, but for reasons not understood, trying to set it shorter does not seem to work.
There does appear to be at least part of designed in mechanism where using configuring CONFIG_AUTOBOOT_STOP_STR and then entering it is supposed to stop the boot retry mechanism, but I couldn't get that to work or find any useful hits when searching on it.
To remove boot retry feature entirely
To remove the boot retry feature entirely, find where it is being defined in code applicable to your board (grep -r CONFIG_BOOT_RETRY * or similar), remove that, rebuild and reflash.
To achieve boot retry as a desired feature
First, put the necessary #define in a header applicable to your specific board, for example, if you had an Allwinner SoC you might do:
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
## -16,6 +16,8 ##
#include <asm/arch/cpu.h>
#include <linux/stringify.h>
+#define CONFIG_BOOT_RETRY_TIME 60 //command prompt will timeout
+#define CONFIG_RESET_TO_RETRY //required for above on this chip
+
#ifdef CONFIG_OLD_SUNXI_KERNEL_COMPAT
/*
* The U-Boot workarounds bugs in the outdated buggy sunxi-3.4 kernels at the
Then rebuild u-boot, probably something like this:
make CROSS_COMPILE=~/path/to/gcc-xxx-yyy-zzz-/bin/xxx-yyy-zzz- clean
make CROSS_COMPILE=~/path/to/gcc-xxx-yyy-zzz-/bin/xxx-yyy-zzz- your_board_defconfig
make CROSS_COMPILE=~/path/to/gcc-xxx-yyy-zzz-/bin/xxx-yyy-zzz-
Repackage the result appropriately and flash it to your board
Warning: Always make sure you have a backup means of booting or flashing before over-writing the existing U-Boot!
Depending on your board, that might be something like the ability for the hardware itself to boot from an SD card or USB stick, to push code via a USB utility, or the or the ability to start the board via JTAG or similar. In a pinch some SoC's will release the lines to an SPI flash if you hold them in reset, allowing you to use an external programmer - but others will not release the lines, meaning you have to desolder the flash chip. Loading a bad U-Boot into a board where you have no other way of injecting code but through U-Boot itself can result in a brick!.
Without more details (such as platform, config and version), it's hard to say. Under normal circumstances the only timeout you have is to stop the automatic boot. If the board is resetting reliably after N seconds of being on it is likely that a watchdog is being triggered and U-Boot is not configured to know about and either disable or periodically pet the watchdog to keep the system from resettting.
I don't understand why these CONFIG options are part of Kconfig so that one can configure with "make menuconfig" and also save the settings in _defconfig files.
That makes the most sense rather than having to add and customise header files.
It's 2021 now. I wonder if it's worth submitting a patch?

Repeating function invoking like NSTimer in C

I find myself in need for a repeating block of code I can execute. If I were in an object I could simply pass self to the NSTimer scheduling. I am in a pure C project at the moment and I don't see any obvious NSTimer analogs. Is there a correct way to approach this?
If you really want the CF way of doing this:
CFRunLoopTimer is the CoreFoundation counter-part you're probably looking for.
You'll need to construct a separate CFRunLoop on a different thread if you want the timer to fire an asynchronous job. Otherwise, you can use use the main application thread by calling CFRunLoopGetCurrent() and set that to be the "parent loop" (called a "mode") that responds to the timer's events.
Here's what you do:
Initialize a CFRunLoopTimerContext struct (on the stack is fine)
Calculate the next time at which the run loop fires using type CFAbsoluteTime and CFAbsoluteTimeGetCurrent() plus some CFTimeInterval (can be a double aka CGFloat)
Create the run loop timer with CFRunLoopTimerCreate, passing in the next fire time and the callback function pointer
Add the run loop timer to either a runloop on a separate thread or the main thread of the executable (see above)
I don't know much of anything about the foundation framework but you can hack together a timer using the mach/POSIX APIs which allow you to tap into kernel services and processes for your C application.
Using a combination of mach_absolute_time() and nanosleep() system calls may allow you to emulate a timer. It's a bit nasty if you've never done any systems programming on a *NIX like platform.
On Linux, it's much easier to implement a POSIX timer or make use of clock_gettime() and clock_nanosleep (POSIX functions) which are not available on the mac.
There's lots of info on Linux/Unix systems programming in C but not so much on a mac, so I'd recommend having a look at this question.
Also, I made my own little emulation of clock_gettime() and clock_nanosleep for the mac (shameless plug) Find it here

How to use delays in Arduino code?

Is there a way I can use the delay command and have something else running in the background?
Kinda, if you use interrupts. delay itself uses these. But it's not as elegant as a multi-threaded solution (which is probably what you're looking for). There is a Multi-Threading library for Arduino but I'm not sure how well, or even if, it works.
The Arduino is only capable of running a single thread at a time meaning it can only do one thing at a time. You can use interrupts to literally interrupt the normal flow of your code but it's still technically not executing at the same time. The library I linked to attempts to implement what you might call a crude "hyper-threaded" solution. Two threads executing in tandem on a single physical processing core.
If you need other code to execute, you need to learn how to program with millis(). This involved converting your code from "step by step" execution to a time-based state machine.
For example if you want a LED to flash, you have two states for that LED: On and Off. You change the state when enough time has elapsed.
Here are a series of examples of how to convert delay()-based code into millis()-based code:
http://www.cmiyc.com/blog/2011/01/06/millis-tutorial/
Usually all you need is a timer and a ISR routine. You won't manage to live without Interrupts :P Here you can find a good explanation about this.
I agree with JamesC4S, state machine is probably the right formalism to use in your case. You could for example try the ThingML language (which uses components, state machines, etc), and which compiles to Arduino code. A simple example can be found here.

How to solve "BUG: scheduling while atomic: swapper /0x00000103/0, CPU#0"? in TSC2007 Driver?

I found tsc2007 driver and modified according to our needs. Our firm is producing its own TI DM365 board. In this board we used TSC2007 and connected PENIRQ pin to GPIO0 of DM365. It is being seen OK on driver. when i touch to touchscreen cursor is moving but at the same time i am getting
BUG: scheduling while atomic: swapper /0x00000103/0, CPU#0
warning and embedded Linux is being crashed. there are 2 files that i modified and uploaded to http://www.muhendislikhizmeti.com/touchscreen.zip one is with timer the other is not. it is giving this error in any case.
I found a solution on web that i need to use work queue and call with using schedule_work() API. but they are blur for me now. Is anybody have any idea how to solve this problem and can give me some advice where to start to use work queue.
"Scheduling while atomic" indicates that you've tried to sleep somewhere that you shouldn't - like within a spinlock-protected critical section or an interrupt handler.
Common examples of things that can sleep are mutex_lock(), kmalloc(..., GFP_KERNEL), get_user() and put_user().
Exactly as said in 1st answer, scheduling while atomic happens when the scheduler gets confused and therefore unable to work properly and this because the scheduler tried to perform a "schedule()" in a section that contains a schedulable code inside of a non schedulable one.
For example using sleeps inside of a section protected by a spinlock. Trying to use another lock(semaphores,mutexes..) inside of a spinlock-proteced code may also disturb the scheduler. In addition using spinlocks in user space can drive the scheduler to behave as such. Hope this helps
For anyone else with a similar error - I had this problem because I had a function, called from an atomic context, that used kzalloc(..., GFP_KERN) when it should have used GFP_NOWAIT or GFP_ATOMIC.
This is just one example of a function sleeping when you don't want to, which is something you have to be careful of in kernel programming.
Hope this is useful to somebody else!
Thanks for the former two answers, in my case it was enough to disable the preemption:
preempt_disable();
// Your code with locks and schedule()
preempt_enable();

Resources