c - STM32 - FreeRTOS xQueue 接收不完整的数组

标签 c stm32 freertos

我在 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)
        {
           ...
        }

}

我试过从一个任务发送到另一个任务而不使用 ISR,结果是一样的!

编辑:

解释 CDC_Receive_FS (uint8_t *Buf, uint32_t *Len) :

如果我从 PC 发送字符串“abcdefg”,*Buf将是:

Buf[0]='a' ... until Buf[6]='g' 

*Len将是一个值为 7

的 uint8_t

因此,for(int i =0;i<100;i++)是否只是为了确保 SerialBufferRec.Buffer 的所有 100 个位置将被覆盖。如果它小于接收到的缓冲区的长度,则复制接收到的缓冲区,否则用零填充。它还有助于清空数组中的最后一条消息。

SerialBufferRec就在打电话之前 xQueueSendFromISR将是:

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

最佳答案

...根据原始帖子中的新信息,以前的内容被删除为不相关。

EDIT:基于 OP 的新内容,并取决于以下功能的工作方式:

xQueueSendFromISR(xQueueSerialDataReceived,(void *)&SerialBufferRec,&xHigherPriorityTaskWoken);

基于示例 at FreeRTOS regarding usage of xQueueSendFromISR ,

看起来不是将 100 个元素打包到您传递到循环外的参数中,您应该在循环内每次迭代只传递 1 个元素:

void vBufferISR( void )
{
char cIn;
BaseType_t xHigherPriorityTaskWoken;

    /* We have not woken a task at the start of the ISR. */
    xHigherPriorityTaskWoken = pdFALSE;

    /* Loop until the buffer is empty. */
    do
    {
        /* Obtain a byte from the buffer. */
        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );

        /* Post the byte. */
        xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );

    } while( portINPUT_BYTE( BUFFER_COUNT ) );

    /* Now the buffer is empty we can switch context if necessary. */
    if( xHigherPriorityTaskWoken )
    {
        /* Actual macro used here is port specific. */
        taskYIELD_FROM_ISR ();
    }
}

然后,在您的代码(的缩写描述)中,这将转化为一次发送一个字节: (注意,为了简洁起见,我将 Buf[i] 的赋值简化为 SerialBufferRec.Buffer[i])

...
char cIn;
for(int i =0;i<100;i++)
{
      xQueueSendFromISR(xQueueSerialDataReceived,&Buf[i],&xHigherPriorityTaskWoken);

}

关于c - STM32 - FreeRTOS xQueue 接收不完整的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47944095/

相关文章:

c++ - 在 clang 编译的 Termux 中运行 C 代码

c - stm32 Nucleo-L011K4 i2c 确认失败

c - IAR 嵌入式工作台 : Unknown or ambiguous symbol

c - 定义 FREERTOS_USED 符号后 Atmel UC3A0512 FAT API 问题

rtos - 实时操作系统基础

queue - 在非 ISR 上下文中使用 "FromISR"FreeRTOS 调用有什么缺点(如果有)?

根据特定值多次调用#define

c - 十六进制格式说明符在 shellcode 中产生不可预测的结果

C malloc valgrind - 在我的单链表实现中未初始化的内存

c - 为什么 objcopy 排除一个部分而不排除另一个部分?