I'm having trouble to implement xQueue in FreeRTOS v8.
The board is based on STM32F4, and I'm trying to send data from ISR (Serial) to main Thread.
The only problem is that not all data is received on the main Thread. I checked the buffer before send and it's complete. On the main Thread, no matter how much chars I send, I always receive the first 5 values of the buffer.
The struct of the buffer (I've tried with a buffer of [10], and the result is the same):
typedef struct SerialBuffer
{
uint8_t Buffer[100];
} SerialBuffer;
The creation of the queue:
xQueueSerialDataReceived= xQueueCreate( 10, sizeof( SerialBuffer * ) );
On SerialPort Receive Handler:
SerialBuffer SerialBufferRec;
static int8_t CDC_Receive_FS (uint8_t *Buf, uint32_t *Len)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
uint32_t length = *Len -1;
//Copy the buffer
for(int i =0;i<100;i++)
{
if(i<=length)SerialBufferRec.Buffer[i]=Buf[i];
else SerialBufferRec.Buffer[i]=0;
}
xQueueSendFromISR(xQueueSerialDataReceived,(void *)&SerialBufferRec,&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
return (USBD_OK);
}
On main Task:
SerialBuffer SerialBufferReceived;
void ReceiveAndSendSerialData()
{
if(uxQueueMessagesWaitingFromISR(xQueueSerialDataReceived)>0)
xQueueReceive(xQueueSerialDataReceived,&SerialBufferReceived,1);
if(SerialBufferReceived.Buffer[0] != 0)
{
...
}
}
I've tried send from a Task to other Task and not using ISR, and the result is the same!
EDIT:
Explaining CDC_Receive_FS (uint8_t *Buf, uint32_t *Len)
:
If I send from PC the string "abcdefg", *Buf
will be:
Buf[0]='a' ... until Buf[6]='g'
And *Len
will be a uint8_t with value 7
So, the for(int i =0;i<100;i++)
is there just to make sure that all 100 positions of the SerialBufferRec.Buffer
will be overwritten. If its minor than the length of the buffer received, copy the buffer received, otherwise fill with zero. It also helps to empty the last message that was in the array.
The SerialBufferRec
just before calling xQueueSendFromISR
will be:
SerialBufferRec.Buffer[0]='a'
...
SerialBufferRec.Buffer[6]='g'
SerialBufferRec.Buffer[7]=0
...
SerialBufferRec.Buffer[99]=0
The SerialBufferRecived
on receive Task arrives like this ('f' and 'g' missing):
SerialBufferRec.Buffer[0]='a'
...
SerialBufferRec.Buffer[4]='e'
SerialBufferRec.Buffer[5]=0
...
SerialBufferRec.Buffer[99]=0
CDC_Receive_FS(...)
is called, specifically howuint8_t *Buf
is created and populated before being passed as an argument. – ryyker*Buf
to feed theSerialBufferRec
, that will be sent through Queue. Adding a breakpoint just beforexQueueSendFromISR
, I can check thatSerialBufferRec
is complete. – Matheus StumpfSerialBuffer
pointers. Try changingxQueueCreate( 10, sizeof( SerialBuffer * ) );
toxQueueCreate( 10, sizeof( SerialBuffer) );
. – tgregorychar buffer[100];
or as achar *buffer;
. And if the second one, has it been initialized with memory? Showing these in your code example is paramount to any ability for another person to provide any useful feedback. – ryykerxQueueSerialDataReceived= xQueueCreate( 10, sizeof( SerialBuffer * ) );
should be 100, should it not? Eg.xQueueSerialDataReceived= xQueueCreate( 100, sizeof( SerialBuffer ) );
– ryyker