STM32L072RZ Cortex M0+ does not block infitinely on stream buffer sometimes.

sorter wrote on Monday, April 22, 2019:

Hello,

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.

Thanks.

rtel wrote on Tuesday, April 23, 2019:

Can you please post the smallest amount of code that shows how the
consumer is using the stream buffer - thanks.

sorter wrote on Tuesday, April 23, 2019:

Of course sir,

Producer interrupt:

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...
}