xMessageBufferReceive time bug xTaskNotifyFromISR

~~~ MessageBufferHandle_t onlyForTestBuf; //this is global var //at task onlyForTestBuf = xMessageBufferCreate(24); for(;;) {
xMessageBufferReceive(onlyForTestBuf, ( void * )myMessage, sizeof(myMessage), portMAX_DELAY ); BeepMini(); } void TIM3IRQHandler(void) { xTaskNotifyFromISR(MotorsActionsHandle, PWMIRFAULT, eSetValueWithOverwrite, NULL); TIM3->SR = 0;
while(TIM3->SR &= TIMSRCC1IF); //HALTIMIRQHandler(&htim3); } ~~~ I don’t use onlyForTestBuf at any place! No more can add into onlyForTestBuf! But I hear Beep because of my function BeepMini(). But if I delete xTaskNotifyFromISR from my interrupt no more beep. Problem at O3 and O0 too. I use HAL and I don’t forget to check TIM3 global interrupt (at NVIC page) “Uses FreeRTOS functionality”, also there are no dynamic interrupt priority changes in my code. STM32F401xE,KEIL ARM COMPILER 5 Full proj https://yadi.sk/d/oiabwcgqJjvHMA

xMessageBufferReceive time bug xTaskNotifyFromISR

So if I understand correctly xMessageBufferReceive() should never return because nothing is ever sent to onlyForTestBuf(), yet BeepMini() seems to execute – indicating that xMessageBufferReceive() did infact return. You are sending a notification to MotorsActionsHandle(), is that the function that is calling BeepMini()? If you place a break point on BeepMini(), does it actually get hit? If not, is anything else calling BeepMini()? Or could anything else accidentally write to whatever peripheral is used to generate a beep? Have you read through https://www.freertos.org/FAQHelp.html and in particular https://www.freertos.org/RTOS-Cortex-M3-M4.html ? As always it is best to be using the latest version of FreeRTOS (or at least V10.2.0) as the newer the version the more configASSERT() there are that help catch errors in interrupt setup misconfigurations.

xMessageBufferReceive time bug xTaskNotifyFromISR

I’m wondering if it could be the case that if a task is sitting in a wait for Message Buffer, and the task gets sent a notifiaction, if that could cause the xMessageBufferReceive to return with a timeout error instead of going back into the wait. I try to program defensively and still test for timeout errors even when the wait is an infinite wait. A simple test would be to test the return value of the xMessageBufferReceive() and only beep on success to see if that is the issue.

xMessageBufferReceive time bug xTaskNotifyFromISR

Yes, xMessageBufferReceive() should never return because nothing is ever sent to onlyForTestBuf(), yet BeepMini() seems to execute – indicating that xMessageBufferReceive() did infact return. I think I understand problem. Look at FreeRTOS code streambuffer.c: ~~~ sizet xStreamBufferReceive( StreamBufferHandlet xStreamBuffer, … /* Wait for data to be available. */ …. ( void ) xTaskNotifyWait( ( uint32t ) 0, UINT32_MAX, NULL, xTicksToWait ); ~~~ In my interrupt I send via xTaskNotifyFromISR! And as said Richard Damon if my code will be: ~~~ MessageBufferHandle_t onlyForTestBuf; //this is global var //at task onlyForTestBuf = xMessageBufferCreate(24); size_t xReceivedBytes; for(;;) xReceivedBytes = xMessageBufferReceive(onlyForTestBuf, ( void * )myMessage, sizeof(myMessage), 100 ); if( xReceivedBytes > 0 ) BeepMini(); } ~~~ no beep. Now you can see xTaskNotifyFromISR makes xMessageBufferReceive return with zero bytes of data. May be should change at streambuffer.c xTaskNotifyWait( ( uint32t ) 0, UINT32_MAX, NULL, xTicksToWait ); to vTaskDelay(xTicksToWait); ?

xMessageBufferReceive time bug xTaskNotifyFromISR

Yes, MessageBuffers use the Notify feature to signal that data is available (but don’t set any bits so any bits set with a notify do remain for the task to see later. The issue is that the MessageBuffer receive routine when it is woken from the Wait, if it still doesn’t have the needed data, doesn’t check if it woke up from a timeout (so it should report that back) or if it was woken up be some other Notify, and thus it could possible continue to wait for the remaining time (but still allow for the abort delay function to abort the waiting.) Because of the xTaskAbortDelay case, fixing the behavior may be difficult (FreeRTOS might need to have a flag in the TCB to let parts know that an AbortDelay has been done to prevent resuming blocking from ‘spurious’ wakeups, which might impose execessive costs. An alternative would be a clear indication in the MessageBufferReceive documentation that other task notifications might abort the Receive early, so tasks using it do need to check the return value and understand that a ‘timeout’ might not mean the full time has elapsed, but the task might be able to handle that other notification and resume the receive. I can actually see cases where this behavior that in your case is undesired (but simple to test for) could actually be very useful to allow a task to do a form of multiple source wait (able to respond to a number of different notifcations or a message).

xMessageBufferReceive time bug xTaskNotifyFromISR

That’s why I asked if it was the same task. I actually plan, if feasible, to extend the task notification function so there is an array of them, rather than just one, then you can use different indexes for different purposes.

xMessageBufferReceive time bug xTaskNotifyFromISR

“I can actually see cases where this behavior that in your case is undesired (but simple to test for) could actually be very useful to allow a task to do a form of multiple source wait (able to respond to a number of different notifcations or a message).” For Direct To Task Notifications there are a lot of: xTaskNotifyGive(), vTaskNotifyGiveFromISR(), ulTaskNotifyTake(), xTaskNotify(), xTaskNotifyAndQuery(), xTaskNotifyAndQueryFromISR(), xTaskNotifyFromISR(), xTaskNotifyWait(), xTaskNotifyStateClear(). Please do not add xMessageBufferReceive to this list. But I’m interested in the situations you are talking about. Can you give some examples? Also this situation depreciates xTicksToWait param. xTicksToWait no more ticks to wait. “I actually plan, if feasible, to extend the task notification function so there is an array of them, rather than just one, then you can use different indexes for different purposes.” It will be interesting. Good luck

xMessageBufferReceive time bug xTaskNotifyFromISR

First, this absolutely does not depreciates the xTickToWait paramater, that still h as a very vital role, the when the task blocks for a notification it really wants to block and not need to keep polling for an event (so other tasks can run), but it also may want to wait for just a limited period of time, and if no event occured, do some other action, and perhaps then go back and wait again. As to multiple sources, the list you gave is basically all the variants of the Direct to Task API, which has a single base Notify function (and its ISR twin), and then a number of specializations that just effectively provide a value for the eAction parameter and maybe default values for some of the others, but all are just variations of the Notify operation. Many people have wanted ways to wait for events from many sources, and we have the QueueSet to manage data from multiple Queues and Semaphores. With a Message Buffer there is less need for multiple Queues, as you can make make the messages that are put on the queue indicate what type of message it is and then send them all on the same MessageBuffer. What this doesn’t provide is a way to handle mixing in some Semaphores in this mix. You could create a whole message for each Semaphore, but that adds complexity at the sending end to need to actually build the messages. Letting the program use the Direct to Task Notifications as an array of Semaphores, and the task waiting on the message, gets woken up on sending one of the notifications and on getting the 0 return on the MessageBufferReceive dosn’t process the message not received, and then checks the notification and finds it. This does slightli complicate programs that don’t use that feature, but not by that much, it does say that they need to check the return value of the Receive, but they really should be anyway out of general principle. if you want the equivalent of the max delay case, just do a ~~~ while(!xMessageBufferReceive( … portMAX_DELAY)) continue; ~~~ and that statement won’t move on until a message is received. Note this issue only happens if a task does both MessageBuffers and Direct to Task Notifications, and I really suspect that most of the time, if that notification occurs, the task wants to handle the notification, not continue to wait for the message. Look at the example that started the thread, A timer signaled a motor fault to the task, I would expect that that is likely wanted to be processed now, rather than waiting for some message, which by the portMAX_DELAY period, may well be a long time in comming (if you were expecting it soon, there would be a timeout to handle it getting lost).