I'm trying to understand how the timer works. I have implemented a timer handler which flashes a LED. It then implements the timer again. I expect the timer to fire again and flash the led but it only ever fires the timer once.
The basic code I'm using is dialog_beacon 3.40.6
1) I've added APP_MY_TIMER to APP_MSG in app_api.h
2) I've added {APP_MY_TIMER, (ke_msg_func_t)app_my_timer_handler}, to app_task_handler.h
3) I've added the following handler to app.c
int app_my_timer_handler(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
//code to flash LED removed for clarity (but it works ok)
ke_timer_set(APP_MY_TIMER, TASK_APP, 100); // 100 is 1 sec - reset timer
return (KE_MSG_CONSUMED);
}
I've added an initial timer to app_init in app.c, set with the following line of code:
ke_timer_set(APP_MY_TIMER, TASK_APP, 300); // 100 is 1 sec
When the system starts up it gets to app_init and executes the line above for a 3 seconds timer, before carrying on with whatever the beacon project does next.
After about 3 seconds this timer must expire and execute the timer handler because my led flashes. I have put a break point in the timer handler so I know it gets there.
It should then execute the line that sets the next timer interval for 1 second.
It then never retriggers the timer handler (but is still operating as it still sends advertising packets)
Why does it never retrigger the timer that was set in the timer handler?
Hi DrNick1,
You dont need anything else in order for the timer to function. Try to set your timer when the BLE finishes its configuration (app_set_dev_config_complete_func). In the app_init() function your timer doesn't work because is outside of the main loop. So when the scheduler is called there is a reset and all pending commands, because of the reset all the pending messages are cancelled.
Thanks MT_dialog
Ok thanks. I've done this (setting the timer in app_set_dev_config_complete_func) and this does allow the timer to work.
I'm setting a 1 second timeout as an example. However, there is still an issue.
Once the program is started, it correctly sets the timer and after the correct timer period, the timer fires and the handler catches it. The handler then sets another timer (for 1 second), which also fires after the correct period of time, which once again sets another timer for 1 second. This time there is a delay of several seconds before the timer fires again. After this I get a regular 1 second firing, so its just this third time though. Heres the handler code - its very simple
int app_my_timer_handler(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
//code to flash LED - removed for clarity
ke_timer_set(APP_MY_TIMER, TASK_APP, 100); // 100 is 1 sec
return (KE_MSG_CONSUMED);
Why would this work twice accurately, then have a big pause before then working as expected?
Hi DrNick1,
I ve implemented the same code in the beacon reference design and all the timer intervals occured after one second, can you please use the arch_set_pxact_gpio() in your timer handler and measure the time with smart snippets in order to make sure about the timing of succesive timer endings.
Thanks MT_dialog
So the issue appears to have been the line
app_timer_set(APP_FLASH_POWEROFF_TIMER, TASK_APP, APP_SPI_POWEROFF_TIMEOUT); //5 sec in app_set_dev_config_complete_func
Disabling this made everything work as expected.
The reason this was being called was because I'd set HW_CONFIG_BEACON_REF as this appeared to be the closest thing to my requirement, but this has the SPI_FLASH enabled as default. I don't require SPI_FLASH so I have now undefined it. Seems ok at the moment!