while investigating a complex problem I saw that in some cases my threads are stopping without obviuous reason.
If I pause the debugger at that moment, I see that the SW is constantly calling VectorD4(). The vector in its turn calls the serve_interrupt(). This is generally correct, but the value of the status register is 0x98 (152). This means that the overflow flag is set - ok, I am running at 921Kbps with USART interrupt at the highest priority (4).
In fact the problem is that the code in the serve_interrupt() cannot handle this specific case. Stepping inside I saw that it does not enter in any of the If's, even the expected block:
Code: Select all
/* Data available.*/
chSysLockFromIsr();
while (sr & USART_SR_RXNE) {
/* Error condition detection.*/
if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE))
set_error(sdp, sr);
sdIncomingDataI(sdp, u->DR);
sr = u->SR;
}I set a breakpoint at the "set_error()" line to verify if it gets called at least once. But the debugger does not stop there at all (even after starting new debug session and observing long period of normal operation of the SW and reaching to the hanging point after that).
I am using F401 and so I checked the reference manual - RM0368, DocID025350 Rev 2. At page 535, point 19.6.1 Status register (USART_SR), I see that there are different sequences to reset (ack) different bits. For ORE bit this is done with sequence of reading of SR then DR. Some other bits are cleared by reading just SR.
I am not sure if the current code is wrong, maybe the used sequence will fit all the possible bits.
But I still face my original problem and I don't see how the serve_interrupt() will handle my case (SR=0x98) to get out of the overrun - and unlock my threads.
I desperately need some advice - I will try to patch the serve_interrupt() to be able to continue my work.
Thanks in advance!