I have multiple threads that try to read from a message queue via
osMessageQueueGet(MsgQueue, &msg, NULL, 0U)
The Event Recorder show me very frequent "Host Buffer Overflows". According to https://www.keil.com/support/man/docs/uv4/uv4_db_dbg_evr_view.htm this happens due to too frequent buffer writes, but it also happens when the queue is empty and nothing is actually written to the message buffer. When I set the timeout of osMessageQueueGet() to 1ms or more, the overflows get less fequent, but that also makes the algorithm less responsive.
Does someone have an idea why this happens? The code is running on a Cortex-M3. Is it too slow?
I followed the documentation and there it is described exactly as I have implemented it. The event switching doesn't look good.
Your code is spinning, which is causing too many messages for the debug link to handle. Find a way to slow down the calls to osMessageQueueGet(). For example, wait on an event to check the queue. Or, modify the event recorder message filter so that only the messages you want make it to the debugger.
Well that is what I've been thinking. The problem is that I can't start or suspend threads from ISRs. It reads the message queue that a UART ISR fills.
Does it mean that it is only an issue with the debug link? Then I could just leave it for now, since it is not crucial. I would then see if I can improve this later.
You can send an event from the UART ISR that fills the message queue (put the new message then send an event). The receiving thread is launched from main() or another thread -- anywhere that isn't an ISR.
In the receiving thread, loop like this:
The thread event flags are a free resource, in that you don't have to create an event flag.
I just tried that. Unfortunately it breaks the functionality. It seems like frames are missing, because the thread is not switched on fast enough.
Sorry for the late reply. I was busy with other issues and this was not a priority. I would really like to optimize this though. Leaving all threads turned on and spinning all the time is ugly.
No need to apologize for the delay.
I'm surprised you're dropping frames (but not dropping bytes from the frames?). Have you tried: increasing the depth of the message queue and/or exhausting the queue when the thread wakes up to process it? How many frames per second do you need to process? (Order of magnitude?)
I am actually not sure. That was just my assumption since it breaks the functionality. The UART port runs a 2 MBd and has a trigger level of 14 bytes. The length of the message queue are 14 bytes as well. I just realized that the osMessageQueueGet() always reads successfully, also when the queue is empty/contains only zeros. I have not tried increasing the depth yet. What do you mean by exhausting the queue when thread wakes up?One UART frame consists of 8 data bis, 1 start, 1 stop and no parity bit. So I have 10 bits per frame. So with 2 MBd I have 200k frames/s. If I consider a message queue length of 14 bytes = 112 bits. It might not be optimal for the 10 bits per frame. Better to take 8 bytes that result in 80 bits and have no residue of two bits per queue as 112 mod 10 does. But that is just an assumption.By order of magnitude you mean the speed of the processor I assume? I am using a Cortex-M3 and have investigated a little. The processor runs at 120 MHz, can handle one instruction per cycle and has thus 120 MIPS. According to a book I have it has 1.25 Dhrystone MIPS/MHz so in total 150 DMIPS. The interrupt latency is 12 cycles.So well the order of magnitude is 1.5 x 10^8I don't really know what to make of this, since I am very new to the topic. I have severe doubts though that the hardware is capable of the intended task. Since I am writing my thesis about this at the moment, I would like to verify this.
View all questions in Keil forum