Description
Description
My program has several threads that need to (aperiodically) consume information from other threads, and periodically perform some task.
In order to implement this these processes consume a Queue to which other threads can post relevant information. A Ticker periodically posts a message to the same Queue to indicate a periodic event.
This works well, except that when I have more than one such thread, and use a breakpoint to debug the program the ISR queue overflows. (trace at the bottom)
My findings so far:
- The stack trace shows that the call to Queue.put() causes the ISR queue overflow
- When using a signal instead of a queue, the problem appears even with a single thread, queue and ticker.
- Using a single ticker to post to two processes' queues breaks.
- Using multiple tickers to post to the same process' queue works.
- The LED's don't blink while in a breakpoint so both the threads and the ticker handler are actually stopped.
My current theory is that something fills the ISR queue while in a breakpoint, and the next call to the ticker callback ends up triggering the ISR queue overflow.
At this point I'm not sure what else I can do to debug the issue.
Board: NUCLEO_F767ZI
IDE: SW4STM32
mbed --version 1.2.2
Compiler: arm-none-eabi-g++ (GNU Tools for ARM Embedded Processors 6-2017-q2-update) 6.3.1 20170620 (release) [ARM/embedded-6-branch revision 249437]
mbed-os version: 03196b2 Merge pull request #7228 from ARMmbed/release-candidate
I've also tried to use an external Segger JLink instead of the onboard ST-link, to the same result.
Reproduce by running the following code, entering a breakpoint, and exiting the breakpoint.
#include "mbed.h"
mbed::DigitalOut led1(LED1);
mbed::DigitalOut led2(LED2);
mbed::DigitalOut led3(LED3);
rtos::Queue<int, 16> queue1;
rtos::Queue<int, 16> queue2;
rtos::Thread thread1;
rtos::Thread thread2;
int t1 = 0;
int t2 = 0;
void cb_1() {
led3 = !led3;
queue1.put(&t1);
}
void cb_2() {
queue2.put(&t2);
}
void thread_1() {
while(true) {
queue1.get();
led1 = !led1;
}
}
void thread_2() {
while(true) {
queue2.get();
led2 = !led2;
}
}
// main() runs in its own thread in the OS
int main() {
thread1.start(callback(thread_1));
thread2.start(callback(thread_2));
mbed::Ticker sticker;
mbed::Ticker cticker;
cticker.attach_us(callback(cb_1), 50000);
sticker.attach_us(callback(cb_2), 50000);
while (true) {
Thread::wait(10000);
}
}
Thread #1 (Suspended : Signal : SIGINT:Interrupt)
mbed_halt_system() at mbed_error.c:63 0x8002118
mbed_error() at mbed_error.c:202 0x8002118
osRtxErrorNotify() at mbed_rtx_handlers.c:54 0x8002ccc
isrRtxMessageQueuePut() at rtx_msgqueue.c:857 0x8003fae
osMessageQueuePut() at rtx_msgqueue.c:950 0x8003fae
rtos::Queue<int, 16ul>::put() at Queue.h:110 0x800031e
cb_1() at main.cpp:19 0x800031e
ticker_irq_handler() at mbed_ticker_api.c:297 0x8001c9e
<signal handler called>() at 0xfffffffd
osKernelStart() at rtx_kernel.c:592 0x80036d4
<...more frames...>
Issue request type
[ ] Question
[ ] Enhancement
[X] Bug