FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [June 2015 Threads] One Shot TimersPosted by marshallbrown on June 16, 2015 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){
uint32t ledindex = ( uint32t ) pvTimerGetTimerID( arg );
BoardLEDSet(ledindex, 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 TimersPosted by davedoors on June 16, 2015 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 TimersPosted by marshallbrown on June 17, 2015 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 TimersPosted by rtel on June 17, 2015
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 TimersPosted by marshallbrown on June 18, 2015 Hi thanks for the ongoing support and please excuse my slowness on this front.
I have a lot of LEDs/timers and they all blink away at different times, so I would prefer to delete the timer.
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);
}
~~~~~~
- 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 TimersPosted by davedoors on June 18, 2015 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 TimersPosted by marshallbrown on June 18, 2015 I'll try it right now! and let you know how I get on.
Thanks for this,
Regards
One Shot TimersPosted by marshallbrown on June 18, 2015 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
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|