I'd like to create a simple watchdog timer in Windows, which will invoke a callback if certain time elapses since the last timer reset.
I thought of using a timer queue timer, but it seems that I need to call DeleteTimerQueueTimer each time I want to "postpone" the timer:
// This is called whenever data is received from a device.
// If not called within a certain period, timerCallbackFn will
// be invoked on a separate thread.
void resetWatchdog(void)
{
if (_timer->handle != NULL)
{
// cancel previous timer
DeleteTimerQueueTimer(NULL, (HANDLE)_timer->handle, NULL);
_timer->handle = NULL;
}
// create new "one shot" timer
CreateTimerQueueTimer(&_timer->handle,
NULL,
timerCallbackFn,
_timer,
_timer->intervalMs, // fire once, after the specified interval
0, // not periodic
0);
}
Is this the correct approach? Do I need to use delete/create each time? Or is this the wrong timer for the job altogether?
Related
I'm basically trying to get a LED to light up after I push a button. Below is the snippet of the code that's supposed to handle this:
void task_player1(void *pvParameters)
{
while (1)
{
if (xSemaphoreTake(player1_signal, portMAX_DELAY))
{
printf(">>>Semaphore taken\n<<<");
ioport_set_pin_level(L1, HIGH);
xSemaphoreGive(player1_signal);
}
else
{
ioport_set_pin_level(L1, LOW);
}
}
}
void task_ctrl(void *pvParameters)
{
bool button1 = 0;
while (1)
{
button1 = ioport_get_pin_level(B1);
if (button1)
{
xSemaphoreGive(player1_signal);
printf("Semaphore given\n");
}
}
}
The way I'm envisioning this is that task_ctrl gives the semaphore on button press. Task_player1 is blocked until it takes the semaphore after which it should turn on the LED.
The problem is it never seems to take the semaphore. I'm running the printf statements to show me how far the program reaches and it never gets into the part where the LED lights up. But when I run xSemaphoreGive without the button press in task_ctrl the semaphore is taken.
The weird part is that "Semaphore given\n" statement gets printed out on button click which should mean that the semaphore is given as well but never gets taken.
The tasks work on their own, I've even managed to give the semaphore without the button press if-statement like I stated above.
I'm guessing it's something with the button press code, which also works on it's own outside the tasks. So what am I doing wrong? Am I not using the FreeRTOS correctly?
Edit: Including the task creation code
#define TASK_STACK_SIZE (2048/ sizeof(portSTACK_TYPE))
xTaskCreate(task_ctrl, (const signed char * const) "Control", TASK_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(task_player1, (const signed char * const) "Player1", TASK_STACK_SIZE, NULL, 1, NULL);
Edit 2: Probably something I should have mentioned is that I'm using FreeRTOS 7.3 since Atmel Studio doesn't have any newer versions. So no yield functions are available, as far as I can tell.
task_ctrl never blocks - which will prevent any task of equal or lower priority from ever running. So if task_player is equal or lower priority the the task will never be scheduled even when the semaphore is given.
It appearing to work without the button polling is harder to explain, but you have not shown that code so I cannot comment.
You should do two things:
Ensure that task_ctrl has lower priority that at least task_player1 (and lower than any task if it does not block - the idle task will never run in this case).
Ensure that task_ctrl blocks - even if that is just a polling delay, so that it does not eat up all available CPU cycles.
while (1)
{
button1 = ioport_get_pin_level(B1);
if (button1)
{
xSemaphoreGive(player1_signal);
printf("Semaphore given\n");
vtaskDelay( 1 ) ; // at least 1 tick
}
}
One possible problem with task_ctrl is that it will give the semaphore continuously and repeatedly while the button is held. Some sort of state change detection and switch de-bounce rather then level polling might be preferable.
An alternative solution to a polling task is to use a hardware interrupt for teh button and have either the polling task block on an event from the ISR, or have the ISR give the semaphore directly - in either case you will have to deal with debounce.
How can I set up a timer when playing a log file. The timer should start when the log file starts. At a certain event the timer should be printed out in the write window.
There are som built in functions in CAPL do you know how they work?
For example TimeToElapse
Thanks
First insert a replay block in your measurement configuration. In the replay block select your log file and uncheck "Start replay on measurement start" if you want to start the replay from CAPL code.
In the following example I bound the procedure to two on key events:
on key 'a' {
replayStart("ReplayBlockName");
setTimer(mytimer, mytime);
}
on timer mytimer {
// on timer event needed so that setTimer function works properly
}
on key 's' {
write("time to elapse = %d", timeToElapse(mytimer));
}
So basically hit the key 'a' during measurement and afterwards key 's' to see how much time is left. Keep in mind that the output is dependent on your timer. When declaring a regular timer, timeToElapse returns whole seconds. When declaring a msTimer, timeToElapse returns milli seconds.
in the libev ,I have initilized the io watcher to catch events and this event causes to store certain value in some cache. I have another timer watcher which runs every 10 sec, reads the cache value. In such case I suppose there is a race condition. do I need to use lock in two different libev watcher or libev handles it.
eg:
TCP_CACHE_TIMEOUT = g_hash_table_new_full(g_str_hash, g_int_equal, key_destroy_cb, value_destroy_timeoutcb);
zlog_info(_c,"TCP Server started at _port: %d",_port);
int fd =setup_tcp_socket(_port);
if(fd<0)
{
return NULL;
}
struct ev_loop *loop = EV_DEFAULT;
struct _sock_ev_serv server;
server.fd = fd;
ev_io_init(&server.io, event_server, server.fd, EV_READ);
ev_io_start(EV_A_ &server.io);
ev_timer_init (&timeout_watcher, timeout_idle_fd, 0, 10.);
ev_timer_again (loop,&timeout_watcher);
ev_loop(loop, 0);
here I have loop and initilizes io watcher to accept server event, and timer watcher to look in the cache every 10 sec. In such case Do I need to handle the race condition myself or the two watcher io and timer running time is managed by libev?
Short answer: There is no race condition, you don't need a lock.
Longer answer:
The reason that there is no race condition, is because libev is in a loop checking the io watcher, then the timer, then the io, then the timer.....
Whichever one is triggered first, is run first. There is no overlap between the two callbacks.
If however, you were using a threaded event loop (possible, but unlikely judging by your code), and you were reading from the same file in two different threads, then there would be a race condition and you would need a lock.
Example:
If you get data in the io watcher after 0.9 seconds, and your callback for that watcher takes 0.2 seconds to run, your timer will be invoked after the io callback has already finished (at ~10.1 seconds).
I'm writing a Windows (Win32) program in C, which features a worker thread to process data from a USB hardware device. The thread handling all works well, however I now need to add a timer to handle a timeout function. I don't need a callback function, just the ability to start a single shot timer, and to be able to test weather it's complete without sleeping, something like this:
start_timout(1000); // 1 second
while (timer_is_running())
{
doing stuff while waiting...
.
.
.
}
do stuff after timer is finished...
.
.
.
This would be running inside the worker thread.
I've looked at SetTimer(), and have tried creating a callback function that simply sets a global flag, then test for the flag, but that never gets set. I'm not sure if this is because I don't have a message handler inside my thread.
Any suggestions welcome.. Cheers!
Thanks for your reply, I had something working quite quickly. Here's a distillation of my working code:
#include <windows.h>
static void func(void)
{
HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime;
liDueTime.QuadPart = -5000000LL; // 0.5 seconds
//liDueTime.QuadPart = -20000000LL; // 2 seconds
//liDueTime.QuadPart = -100000000LL; // 10 seconds
hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0);
while (WaitForSingleObject(hTimer, 0) == WAIT_TIMEOUT)
{
do stuff
}
}
Regards,
Toonie.
SetTimer requires you to catch the WM_TIMER event in a window and on top of that, is not very accurate. I wouldn't advise to use it.
Instead you could simply create another thread, let it do nothing but Sleep() for the specified time period (you could pass the time as parameter upon thread creation). You can then WaitForSingleObject(sleeper_thread, 0) to check if the timeout has elapsed.
I can't for the life of my work out why this is happening. I have in a class derived from CCLayer. I am scheduling a method call like so when initialising the class
//create an update method for keeping track of how long its been since an animation has played
[self schedule:#selector(playIdleAnimation:)];
And the method is
//an update method that will play an idle animation after a random period of idleness
-(void) playIdleAnimation:(ccTime) dt {
//if the user isn't playing an animation, increment the time since last animation variable
if ([bodySprite numberOfRunningActions] == 0) {
timeSinceLastAnimation += (float)dt;
//now check to see if we have surpassed the time set to cause an idle animation
if (timeSinceLastAnimation > (arc4random() %14) + 8) {
//reset the cooldown timer
timeSinceLastAnimation = 0;
[bodySprite stopAllActions];
//play the idle animation
//[bodySprite runAction:[CCAnimate actionWithAnimation:waitAnimation restoreOriginalFrame:NO]];
NSLog(#"PLAYING IDLE ANIMATION");
}
}
//player is currently playing animation so reset the time since last animation
else
timeSinceLastAnimation = 0;
}
But yet, when I go to run the program the console statements show the condition is being passed twice each cooldown
012-06-29 09:52:57.667 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:52:57.701 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:53:05.750 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:53:05.851 Test Game[5193:707] PLAYING IDLE ANIMATION
I am trying to fix a bug where the game crashes when I finish playing the idle animation, and I'm certain this has something to do with it.
I don't see where you are unscheduling the selector. I bet that it's normal behavior to be called ever frame kicks in, and you see it being triggered twice because it takes a frame for the layer to be deallocated.
If you want a one-time method call, do this:
-(void) playIdleAnimation:(ccTime) dt {
[self unschedule:_cmd];
// rest of the code here
}
Cocos2d 2.0 has a scheduleOnce method that you can use instead.