I just ported the FreeRTOS v10.2.0 to my current project that includes an STM32L072RZ Cortex M0+ based MCU.
In one of tasks, I am blocking on a stream buffer which is feed from an UART ISR using StreamBufferSendFromISR() function. ISR is working correctly and feeds the stream buffer properly. I am checking the stream buffer size using debug facilities, it inserts chars properly. Also there is just one consumer task to consume the stream buffer. Consumer buffer blocks via the parameter of portMAX_DELAY on the stream buffer. When some chars available, it unblocks and consumes all of them rapidly.
The problem is that, sometimes consumer task continues to run, although the stream buffer is empty. The return value of xStreamBufferReceive() is “0”. I did not understand the situtation. This is a rare case but occurs. Please help me.
void UART_ISR_Handler(void)
{
//The length of incoming data is not fixed, so char by char reading...
//Also design of SW guarantees that blthRxStream never overflow.
xStreamBufferSendFromISR(isrRxStream, (void*)&receivedChar, 1, 0);
}
Consumer task:
//MY TEMPLATES THEY USED IN MANY PLACES IN THE CONSUMER TASK
template <typename Stream>
static bool getOneByte(Stream& buffer, char& rxChar, BaseType_t wait_ms)
{
auto received = xStreamBufferReceive(buffer, static_cast<void*>(&rxChar), 1, pdMS_TO_TICKS(wait_ms));
return received;
}
template <typename Stream>
static void pushOneByte(Stream& buffer, char& c)
{
xStreamBufferSend(buffer, static_cast<void*>(&c), 1, 0);
}
template <typename Stream>
static bool getPushOneByte(Stream& getStream, Stream& pushStream, char& c, BaseType_t wait_ms)
{
if(getOneByte(getStream, c, pdMS_TO_TICKS(wait_ms)))
{
pushOneByte(pushStream, c);
return true;
}
return false;
}
void vConsumerTask(void* prm)
{
//initialize the isrRxStream
isrRxStream = xStreamBufferCreate(1024, 1);
//create dispatcing buffer, private...
StreamBufferHandle_t dispatchingBuffer = xStreamBufferCreate(1024, 1);
//enter to the task...
for(;;)
{
//wait until at least one char is available on the stream
getPushOneByte(isrRxStream, dispatchingBuffer, cRx, portMAX_DELAY);
//process received char and following chars in a state machine...
//goes on...
}
//never runs...
}