Ready task doesn’t get scheduled

Hi there, I am using FreeRTOS 10.2.0 on an stm32f103c8 (ARM Cortex-M3). I have an USART1 interrupt set up and push all the received bytes into a circular buffer. From the main task I’m constantly polling the buffer’s size and read any bytes that are available. This works like a charm. However, the polling approach was just for initial testing. The communication task should be suspended, when it tries to read a byte from the buffer, but the buffer is empty. The IRQ should notify the task to continue execution everytime it received a new byte. So basically a top/bottom half processing approach, where the IRQ just receives and notifies a processing task. This is the code I’ve implemented: IRQ Handler: ~~~ extern “C” void USART1IRQHandler(void) { /* Check the reason for the interrupt. At the moment we don’t care about other interrupt sources than the receive buffer full interrupt. */ if((USART1->SR & USARTSR_RXNE) == 0) return;
/* Read the received byte from the USART data register
and push it into the circular buffer. The buffer will
prevent data overwrite. */
uint8_t rxData = USART1->DR & 0x00FF;
ringbuffer_push(rxBuffer, rxData);


/* Now notify the handling task, that a new byte was 
put into the buffer and can be processed. */
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(driverTaskHandle, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} ~~~ Communication task: ~~~ /* Check to see if there is data in the buffer. If so, we can immediately read from the buffer and do not have to wait for the interrupt to fire. In this case we also need to reset the notify flag from the IRQ. / if(!ringbuffer_isEmpty(rxBuffer)) { / Reset the notify flag. We do read the buffer’s content and if the flag is not reset, we will be able to read the buffer, if there is nothing inside (because the flag is still set. We don’t block but just poll the notify value to clear it in any case. */ ulTaskNotifyTake(pdTRUE, 0); return ringbuffer_read(rxBuffer); }
/* No data is in the buffer, so we have to wait for data
to become available. Thus we will block until we get no-
tified from the isr that new data is available. */
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

/* Once we reach this point, we were notified by the isr
about new data being available. We can now read the buffer
and return the data. */
return ringbuffer_read(rxBuffer);
~~~ The problem is, that after some random time (really anything between a few minutes up to 2 hours) the interrupt fires and the IRQ executes, but the communication task is not woken up. Further checking with the FreeRTOS task view (I’m using Attolic TrueStudio) revealed, that the communication task is in the ready state, so naturally vTaskNotifyGiveFromISR does not set xHigherPriorityTaskWoken to true. BUT, although the communication task has the highest priority of 3 (one idle task with prio 0 and one ui task with priority 2), I can see the idle task being executed instead of the high priority communication task. Is there anything that I’m missing? I also tried semaphores instead of direct task notification, but the result is the same.

Ready task doesn’t get scheduled

If I understand correctly the communications task is not woken up because it is already in the ready state. If that is the case, then what is the communications task doing? By which I mean, which code is it executing? You may consider using a Stream Buffer to do the same thing (which internally uses a task notification) https://www.freertos.org/RTOS-stream-buffer-example.html

Ready task doesn’t get scheduled

It is in the ready state, but not in the running state. Can I somehow check the instruction at which the task was suspended? I’ve already tried a static stream buffer, but had no success.

Ready task doesn’t get scheduled

Well it is possible by finding the task’s task control block (which is basically its handle), form which you can find its stack, from which you can find its program counter – but it is much easier if you use a thread aware plug in such as the one shipped with IAR, Segger or Code Confidence.

Ready task doesn’t get scheduled

Alright, it seems the problem is gone. I’ve successfully run the system for about 10 hours now. Maybe I’ve run out of stack (the NXP plugin showed a about 80% stack usage) and with stack overflow detection I guess the task wasn’t scheduled? However, the stack overflow hook did not execute.