I 'm got started coding the RTOS program by using RTX. And I encountered The error "OS_ERROR_TIMER_OVF" . According to the following program,It is occurred "due to User Timer Callback Queue overflow detected". So, I changed the OS_TIMERCBQS value from 4 to 25. But the error is not disappeared.
void os_error (uint32_t error_code) { /* HERE: include optional code to be executed on runtime error. */ switch (error_code) { case OS_ERROR_STACK_OVF: /* Stack overflow detected for the currently running task. */ /* Thread can be identified by calling svcThreadGetId(). */
tid_overstack = svcThreadGetId(); break; case OS_ERROR_FIFO_OVF: /* ISR FIFO Queue buffer overflow detected. */ break; case OS_ERROR_MBX_OVF: /* Mailbox overflow detected. */ break; case OS_ERROR_TIMER_OVF: /* User Timer Callback Queue overflow detected. */ break; default: break; } for (;;); } How should I do to resolve the error? If you know the solution ,Please let me know.
Don't put more items into the Timer_Callback queue then there are spaces in the Queue.
Items are put into the Queue every time a timer expires (this is the 4/25 OS_TIMERCBQS)
These items are removed from the queue by the "Timer Thread", which is typically running at the highest thread priority on the system. So, while the callbacks are running, no other threads are running.
Until the current timer callback completes, no other callback items are removed from the Queue. If items are put into the queue faster than they can be processed, you will get an overflow.
Here are some possible issues / concerns / solutions.
1) put less code in your callbacks so they finish quicker. Consider these very similar to ISR processing routines and keep then very short.
2) Make the OS_TIMERCBQS large enough to hold the maximum number of "active callback functions". This is actually required that this be large enough to hold the maximum number or you will get TIMER overflows. Timer Queue overflows is not a recoverable error.
3) Making timers periodic can cause an unexpected / unplanned number of callbacks to be put into the queue. A periodic timer is rescheduled as soon as it is put into the TimerCallback queue and this means that another item my be put into the queue before the callback even starts to execute. You MAY want to reconsider making these items periodic and instead have the callback function add the timer when it is complete. This will assure that you never have the same timer callback function queue more than once.
You are going to need to determine the maximum number of active callbacks that your system may have at any moment. Your OS_TIMERCBQS needs to be at least this size. You do not need to make it larger than the maximum number of active callbacks, that size is actually the perfect size. Making it larger than this number may actually hide a bug in your code. This is not always easy to calculate, but it is required if you want to be sure you will never overflow the queue. If your design does not allow you to know for sure what this number is, you will need to change your design so that you can know.
Dear Mr. Robert McNamara
Thank you for your valuable comment.
I understood the meaning of OS_TIMERCBQS and I don't change it to extra size.
As you mentioned , I use one-shot or a periodic timer and add the while loop in the timer thread not to use queue.
Hello,
I am experiencing a similar issue where I get the OS_ERROR_TIMER_OVF error. I only get this error when I put my device, STM32L476 into STOP mode and then wake the device back up. I understand that my error is likely application specific but I have spent more than a week trying to debug it.
My question is how to I watch the timer callback queue? I think that when I enter STOP mode there is a callback being left in the queue that causes and overflow upon waking up. I have tried many things in order to find the address of the queue with no luck.
Please help, Tim
The queue is called "osMessageQId_osTimerMessageQ"
Just as a test, you may want to remove any periodic timers that you have and make them 1-shot timers. Have to Code the processes the timer Start the timer. If you use the periodic timer, it is possible to have the same timer object queued many times. If you use the 1-shot and queue it in the routine that processes the timer then you can have at most 1 in the queue. You should be able to make sure your timerQ is large enough to hold 1 of every timer object you have.
This may not be logically what you want, but I am sure you don't want any cases that are terminal failures. It may be best to remove any chance of terminal failures and handle some parts of your timer outside of the timer queue mechanism
Robert,
Thank you telling where to find the queue. I have already configured my timers as one-shot based on your advice from the original poster. I have a total of 7 timers but only one runs constantly and when its callback is entered the first thing I do is stop that timer and the last thing I do is re-start the timer, if, of course, I need to.
When I watch 'osMessageQId_osTimerMessageQ' address in a Memory window i can see a register that look to count up to the 'Timer Callback Queue size' (set at 8). Are the following values the callback addresses? I am having trouble deciphering what the data bytes at the 'osMessageQId_osTimerMessageQ' address all mean.
I also am using Segger emWin in my project and have now discovered it is all creating an osTimer to measure systems ticks. This 'GUI_Timer' is periodic and the source code files are locked so i can not edit them.
Do you have any thoughts?
Thanks, Tim