Hi everyone,
I was investigating a bug in my program and finally found it after lots of head scratching. It turns out the reason is that you cannot safely call read() on AnalogIn from an interrupt, such as a Ticker. When you do, and a main program happens to be inside the read() call as well, then mbed totally freezes - both the main program flow and all the mbed interrupts (the ones used by Ticker, Timeout, etc.) stop.
Here is the simplest program I've written to reproduce it:
#include "mbed.h"
AnalogIn in(p15);
DigitalOut led1(LED1), led2(LED2);
Ticker ticker1, ticker2;
void read_analog_in() {
float v = in.read();
}
void test_led2() {
led2 = !led2;
}
int main() {
ticker1.attach(&read_analog_in, 0.001);
ticker2.attach(&test_led2, 0.5);
while(1) {
led1 = 1;
wait(0.05);
led1 = 0;
wait(0.05);
read_analog_in();
}
}
The programs makes LED1 blink once/sec from main program, and LED2 10 times/sec from ticker2. It will work for a couple of seconds and then blinking of both LEDs will stop. If you increase the ticker1 frequency (to say 0.0001) it will only work for a fraction of second after reset, and if you decrease it to 0.01 it will work much longer but it will eventually freeze as well after a minute or so. LED1 will always be off when it freezes, while LED2 state will be random. So clearly, main program is inside a call to read() while the ticker1 interrupt arrives, causes a second call to read() and it totally freezes mbed.
My question: Is it a bug or a feature? If so, is this documented anywhere and are there any other functions in mbed library with the same limitation (basically not being re-entrant)?
Hi everyone,
I was investigating a bug in my program and finally found it after lots of head scratching. It turns out the reason is that you cannot safely call read() on AnalogIn from an interrupt, such as a Ticker. When you do, and a main program happens to be inside the read() call as well, then mbed totally freezes - both the main program flow and all the mbed interrupts (the ones used by Ticker, Timeout, etc.) stop.
Here is the simplest program I've written to reproduce it:
The programs makes LED1 blink once/sec from main program, and LED2 10 times/sec from ticker2. It will work for a couple of seconds and then blinking of both LEDs will stop. If you increase the ticker1 frequency (to say 0.0001) it will only work for a fraction of second after reset, and if you decrease it to 0.01 it will work much longer but it will eventually freeze as well after a minute or so. LED1 will always be off when it freezes, while LED2 state will be random. So clearly, main program is inside a call to read() while the ticker1 interrupt arrives, causes a second call to read() and it totally freezes mbed.
My question: Is it a bug or a feature? If so, is this documented anywhere and are there any other functions in mbed library with the same limitation (basically not being re-entrant)?