Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
7 years, 10 months ago.
Is it possible to call RtosTimer::start()/stop() inside of a ISR?
Hi, just trying to confirm my findings and maybe to save some time to other developers. I had the intention of triggering a RtosTimer (i.e. calling start/stop method) inside of a ISR function. As it didn't seem to work properly(the timer wasn't started/stoped at all), I prepared a test case. In it, I'm trying the RtosTimer::start()/stop() methods in the main() function where it works properly. Also I'm trying both methods in the ISR and they didn't work.
1 Answer
7 years, 10 months ago.
May be another way of doing it is :
Set as volatile int global flag.
Create an another thread that loops checking the value of this volatile int.
Inside your isr, juste set the volatile int to an value or an other.
pseudo code
volatile int startStop=0; void increment() { count_button ++; if(state_timer==0) { myled = 1 - myled; startStop=1; } else{ startStop=0; myled = 1 - myled; } state_timer = 1 - state_timer; } void CheckStartStop( void const *arg) { while(1) { if (startStop==0) timer->stop(); if (startStop==1) timer->start(1000); } } int main() { .... Thread thread(CheckStartStop); }
Thanks a lot Raph that's a practical way of overcoming this issue, just I see one caveat: it's actively checking the status of startStop, and I would like to save cpu cycles.
For the record, I resorted to using an EventQueue (mbed_events supported in mbed OS >= 5.2), quite a useful stuff. It is simple and doesn't require active polling. With it you can force a call of any function or method in a safe way from an ISR, and it also supports passing arguments. I found an example here: https://developer.mbed.org/blog/entry/Simplify-your-code-with-mbed-events/ Thanks a lot for your help.
posted by 04 Jan 2017
Due to problems with the spam filter, I'm posting it in fragments :-D
This the test case I'm trying
And this is the result:
- count_timer: 0 count_button 0
- count_timer: 0 count_button 0
- count_timer: 0 count_button 0
- count_timer: 0 count_button 0
- count_timer: 0 count_button 1 <== there is one interrupt(count_button increments), and the timer should start but it doesn't
- count_timer: 0 count_button 1
- count_timer: 0 count_button 2
- count_timer: 0 count_button 4
- count_timer: 0 count_button 5
- count_timer: 0 count_button 6
- count_timer: 0 count_button 7
- count_timer: 0 count_button 8
- count_timer: 0 count_button 9
- count_timer: 0 count_button 10 <==when count_button hits 10, the main loop starts the timer. count_timer is incremented accordingly
- count_timer: 2 count_button 10
- count_timer: 4 count_button 10
- count_timer: 6 count_button 11 <==although there are further interrupts, they fail to call the stop method, as *count_timer keeps on incrementing
- count_timer: 8 count_button 12
- count_timer: 10 count_button 12
- count_timer: 12 count_button 12
- count_timer: 14 count_button 14
- count_timer: 16 count_button 14
- count_timer: 18 count_button 14
- count_timer: 21 count_button 15
- count_timer: 23 count_button 15
- count_timer: 25 count_button 17
- count_timer: 27 count_button 18
- count_timer: 29 count_button 20 <== when count_button reaches 20, the timer is stopped at the main loop
- count_timer: 29 count_button 20
- count_timer: 29 count_button 20
- count_timer: 29 count_button 21
- count_timer: 29 count_button 21
- count_timer: 29 count_button 24
posted by Carlos López Molina 04 Jan 2017I got the answer digging in rtos code of RtosTimer constructor() and start(). They are using mbed's osTimerCreate and osTimerStart, and if you read the lines 3, 14, 20 of that code, there states clearly that it is not allowed in ISR. Lesson learned: one can find many answers and learn a lot reading the source code of mbed. Also it's worth checking the return codes of system calls :-D
This is the code