关于stm32g491ret6串口接收数据出现\0的问题
继续排查,用逻辑分析仪抓数据,仔细排查了半天,发现出现这个问题的情况是两条消息间隔太短,大概200us左右。而正常的消息是2ms以上收到,导致收到第一条数据可能没有被处理完成,第二条消息中断接收到消息后,缓冲区被清除,第一条消息就误被清除掉消息头的几个字节。问题描述:我在串口接收回调函数中使用了任务通知,接收到数据之后存到固定缓冲区后,在任务中阻塞等待任务通知处理。}在处理中打印,这回不会出现\0
问题描述:我在串口接收回调函数中使用了任务通知,接收到数据之后存到固定缓冲区后,在任务中阻塞等待任务通知处理。但偶尔会出现接收模块数据打印后出现\0的问题。
问题排查:先更换了不同模块,结果都一致。用模块厂的开发板接TTL转USB和上位机试了试,没有这个问题。用他们模块串口焊到我的mcu,同样出现这类问题。此时已经大致判断出是我mcu串口接收的问题。看了看配置,16位采样,没什么问题。继续排查,用逻辑分析仪抓数据,仔细排查了半天,发现出现这个问题的情况是两条消息间隔太短,大概200us左右。而正常的消息是2ms以上收到,导致收到第一条数据可能没有被处理完成,第二条消息中断接收到消息后,缓冲区被清除,第一条消息就误被清除掉消息头的几个字节。
以下是有问题的接收代码:
if (huart->Instance == USART1) {
/* We have not woken a task at the start of the ISR. */
#if 1
cmd_def_t.rx_lens = Size;
log_debug("Size:%d\r\n",Size);
debug_thread_notify_vaule(true, CMD_TASK_NOTIFY_DEBUG);
}
void debug_thread_notify_vaule(bool irq, uint32_t nofity_bit) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (irq == true) {
xTaskNotifyFromISR((TaskHandle_t)debugThread_t, nofity_bit, eSetBits,
&xHigherPriorityTaskWoken); //
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} else {
xTaskNotify((TaskHandle_t)debugThread_t, nofity_bit, eSetBits);
}
}
接续排查,将debug_thread_notify_vaule(true, CMD_TASK_NOTIFY_DEBUG);注释,直接在中断内答应,不处理数据。数据打印完整,已经可以锁定是中断内调用任务通知的原因了。
换成rtos自带的流缓冲区接收数据,单开一个最高优先级任务处理数据。
else if (huart->Instance == USART2) {
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, uart2_def_t.rx_buf, UART_RX_MAX_SZIE);
BaseType_t xHigherPriorityTaskWoken;
xStreamBufferSendFromISR(xStreamBuffer,uart2_def_t.rx_buf,Size,xHigherPriorityTaskWoken);
}
void StartHtdmUsartTask(void *argument) {
for (;;) {
xReceivedBytes = xStreamBufferReceive(
xStreamBuffer, ucRxData, sizeof(ucRxData), pdMS_TO_TICKS(100));
if( xReceivedBytes > 0 )
{
htdm_cmd_handle((char *)ucRxData, xReceivedBytes);
}
}
}在处理中打印,这回不会出现\0了,应该可以确定xTaskNotifyFromISR占用的时间较长导致的问题。
头疼了一周的问题总算解决。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)