【发布时间】:2023-08-04 08:08:01
【问题描述】:
我无法在 FreeRTOS v8 中实现 xQueue。
该板基于STM32F4,我正在尝试将数据从ISR(串行)发送到主线程。
唯一的问题是不是所有的数据都在主线程上接收到。我在发送之前检查了缓冲区,它已经完成了。在主线程上,无论我发送多少字符,我总是收到缓冲区的前 5 个值。
缓冲区的结构体(我试过用[10]的缓冲区,结果是一样的):
typedef struct SerialBuffer
{
uint8_t Buffer[100];
} SerialBuffer;
队列的创建:
xQueueSerialDataReceived= xQueueCreate( 10, sizeof( SerialBuffer * ) );
在 SerialPort 接收处理程序上:
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);
}
关于主要任务:
SerialBuffer SerialBufferReceived;
void ReceiveAndSendSerialData()
{
if(uxQueueMessagesWaitingFromISR(xQueueSerialDataReceived)>0)
xQueueReceive(xQueueSerialDataReceived,&SerialBufferReceived,1);
if(SerialBufferReceived.Buffer[0] != 0)
{
...
}
}
我试过从一个Task发送到另一个Task,没有使用ISR,结果是一样的!
编辑:
解释CDC_Receive_FS (uint8_t *Buf, uint32_t *Len):
如果我从 PC 发送字符串“abcdefg”,*Buf 将是:
Buf[0]='a' ... until Buf[6]='g'
*Len 将是一个 uint8_t,其值为 7
所以,for(int i =0;i<100;i++) 只是为了确保 SerialBufferRec.Buffer 的所有 100 个位置都将被覆盖。如果它小于接收到的缓冲区的长度,则复制接收到的缓冲区,否则用零填充。它还有助于清空数组中的最后一条消息。
在调用xQueueSendFromISR 之前的SerialBufferRec 将是:
SerialBufferRec.Buffer[0]='a'
...
SerialBufferRec.Buffer[6]='g'
SerialBufferRec.Buffer[7]=0
...
SerialBufferRec.Buffer[99]=0
接收任务上的SerialBufferRecived 像这样到达(缺少“f”和“g”):
SerialBufferRec.Buffer[0]='a'
...
SerialBufferRec.Buffer[4]='e'
SerialBufferRec.Buffer[5]=0
...
SerialBufferRec.Buffer[99]=0
【问题讨论】:
-
从您提供的内容中不知道如何调用
CDC_Receive_FS(...),特别是在作为参数传递之前如何创建和填充uint8_t *Buf。 -
嗨 ryyker,CDC_Receive_FS() 是串行的事件处理程序,当我从 PC 向开发板发送数据时,会触发此方法。我创建了一个全局变量,只使用
*Buf来提供SerialBufferRec,它将通过队列发送。在xQueueSendFromISR之前添加一个断点,我可以检查SerialBufferRec是否完整。 -
您已经创建了一个
SerialBuffer指针队列。尝试将xQueueCreate( 10, sizeof( SerialBuffer * ) );更改为xQueueCreate( 10, sizeof( SerialBuffer) );。 -
我仍然看不到作为参数传递的变量是如何创建的。我可以看到您将它作为指针传递,这是适当的,但我不知道它是被创建为
char buffer[100];还是char *buffer;。如果是第二个,它是用内存初始化的吗?在您的代码示例中显示这些对于其他人提供任何有用反馈的能力至关重要。 -
除了@tgregory 注释,
xQueueSerialDataReceived= xQueueCreate( 10, sizeof( SerialBuffer * ) );中的第一个参数应该是100,不是吗?例如。xQueueSerialDataReceived= xQueueCreate( 100, sizeof( SerialBuffer ) );