One Shot Timers

Hi there Previously before using FreeRTOS I had my own timer implementation that had periodic and oneshot timers. On expiry of the oneshot timer, the timer handler would load the call back function into a function queue, and delete the timer. Is this the case with the FreeRTOS timers? Or will my code (below) keep creating timers and then when they expire they hang around until I have thousands of expired timers and it crashes. If it is the latter, How can I pass the timer handle into my led_off function, so that my callback function can delete the timer. Thanks and Regards Marshall ~~~~~ //this is called from a callback set in multiple timers to turn off the indication leds on timeout. //the argument is the LED number. void ledoff(TimerHandlet *arg){ uint32_t led_index = ( uint32_t ) pvTimerGetTimerID( arg ); Board_LED_Set(led_index, false); } //turn the led on here and set up a timer on which to turn it off void ledblink(uint32t led_index){
    TimerHandle_t BlinkTimer = NULL;

    Board_LED_Set(led_index, true);
    /* Create the software timer that performs the 'check' functionality,
    as described at the top of this file. */
    BlinkTimer = xTimerCreate( "BLINK_OFF",                     /* A text name, purely to help debugging. */
                                ( LED_BLINK_ON_TIME_MSEC ),     /* The timer period, in this case 3000ms (3s). */
                                pdFALSE,                        /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
                                (void *) led_index,             /* The ID is used, as the LED number so set it to that. */
                                (TimerCallbackFunction_t) led_off   /* The callback function that inspects the status of all the other tasks. */
                              );

    /* If the software timer was created successfully, start it.*/
    if( BlinkTimer != NULL ){
        xTimerStart( BlinkTimer, mainDONT_BLOCK );
    }
} ~~~~~

One Shot Timers

You only need to create the timer once. You can then restart it as many times as you need. Look at the parameter of your led_off function. The handle is already passed in.

One Shot Timers

Thanks Dave – It isn’t really handle to the timer. I set it as the TimerHandlet type to stop compiler warnings but in the ledblink function I’m passing the index of the LED. I really didn’t want to have expired timers hanging around (it seems kind of messy) it means that I have store a handle for all these exipired timers somewhere, and then when I want to use them I additionally have to check that the timer is actually existent before restarting it. It would be far simpler to just create a new timer. I could create a struct that has the handle to the timer and the LED index, and then forcibly delete the timer in the LED_off function, but it might be unnecessary? if the timers are actually deleting themselves on expiration. Regards Marshall

One Shot Timers

It isn’t really handle to the timer
It is really a timer handle. If it weren’t you would not be able to use it in a call to pvTimerGetTimerID(), as you are doing. What you are setting to the LED number is the timer’s ID.
I really didn’t want to have expired timers hanging around (it seems kind of messy) it means that I have store a handle for all these exipired timers somewhere,
How are you using the timer? If it is a one shot timer, can more than one timer be running at once? If not, then just re-use the same timer over and over, so you only ever create one. If multiple timers run at the same time then you can always delete the timer in the timer’s callback function.

One Shot Timers

Hi thanks for the ongoing support and please excuse my slowness on this front.
  1. I have a lot of LEDs/timers and they all blink away at different times, so I would prefer to delete the timer.
  2. I added the pointer to the timer into the ID field supplied, along with the LED 1 in the form of a struct
~~~~~~ struct timerargs{ uint8t ledindex; TimerHandlet led_timer; };
void led_blink(uint32_t led_index){
            struct timer_args blink_info;
    blink_info.led_timer = NULL;
    blink_info.led_index = led_index;

    Board_LED_Set(led_index, true);

    blink_info.led_timer = xTimerCreate( "BLINK_OFF",
                            ( LED_BLINK_ON_TIME_MSEC ),
                            pdFALSE,
                            (void *) led_index, //FILL THE ID WITH THE LED INDEX
                            (TimerCallbackFunction_t) led_off
                            );



    vTimerSetTimerID(blink_info.led_timer, &blink_info);

    /* If the software timer was created successfully, start it.  It won't
    actually start running*/
    if( blink_info.led_timer != NULL ){
        xTimerStart( blink_info.led_timer, mainDONT_BLOCK );
    }

}




void led_off(TimerHandle_t *arg){
    struct timer_args *led_off_info;
    led_off_info =  (struct timer_args*) pvTimerGetTimerID( arg );
    Board_LED_Set(led_off_info->led_index, false);

    //now delete the timer 
    xTimerDelete( led_off_info->led_timer);
}
~~~~~~
  1. I’m currently using the ID field in the timer to pass in an argument for the callback function, in this case it is the LED Index, so that I can have a generic callback to turn off any LED.
So I suppose my question is: how do I pass a struct, and then unwrap it in LED_off, as per the above example. Thanks again, I’m sure that it is getting close. Regards Marshall

One Shot Timers

You have made your code over complex. Try ~~~~ void ledtimer( TimerHandlet Timer ) { // Get LED from ID of timer int Led = (int) pvTimerGetTimerID( Timer ); // Should be 5 configASSERT( Led == 5 ); // Delete the timer xTimerDelete( Timer, 0 ); } void main(void) { TimerHandle_t Timer; int Led = 5; // Led number is 5 // Store LED in ID of timer Timer = xTimerCreate( “timer”, 100, pdFALSE, (void*) Led, led_timer ); xTimerStart( Timer, 0 ); vTaskStartScheduler(); } ~~~~

One Shot Timers

I’ll try it right now! and let you know how I get on. Thanks for this, Regards

One Shot Timers

Yep that works a treat, thanks for this. It was my misunderstanding of what was actually being passed to the callback, I thought only the ID was being passed, but it is the pointer to the Timer! so it all makes sense now. Regards Marshall