背景:
在之前我们使用S32DS配置好的UART中断接收的程序中(【S32K146车规级MCU】使用S32DS适配Uart),发现串口在连续接收数据的过程中会存在丢数据的情况,就开始调查原因,就有了该篇帖子。
故障现象:
本地适配的shell在输入方向键的↑时候无法解析识别对应的动作,调查发现键盘输入↑在windows 下回连续上报“up key : 0x1b 0x5b 0x41” 三个字符,本地程序只收到两个字符造成无法解析,以下是本地uart 的初始化和中断处理流程。
/********************************************************************************************************
* Private Function Declarations *
*******************************************************************************************************/
void uart_rx_callback(void *driverState, uart_event_t event, void *userData)
{
UartRecvType * Puart = (UartRecvType *)userData;
if(event == UART_EVENT_RX_FULL)
{
/* Get date and write to ringbuffer */
RingBuffer_Write(&Puart->ringbuff,&Puart->data,1);
}
/* Start to recive uart data */
if(event == UART_EVENT_END_TRANSFER)
LPUART_DRV_ReceiveData(INST_LPUART_1,&Puart->data,1);
}
/********************************************************************************************************
* Global Function Declarations *
*******************************************************************************************************/
void uart_init(void)
{
/* Init lpuart */
LPUART_DRV_Init(INST_LPUART_1,&lpUartState0,&lpuart_0_InitConfig0);
/* Init Ringbuffer */
static uint8_t uart_rx_buff[128] = {0};
RingBuffer_Init(&uart_rx.ringbuff,uart_rx_buff,128);
/* Enable uart rx irq and set rx callback */
INT_SYS_SetPriority(LPUART1_RxTx_IRQn,2);
LPUART_DRV_InstallRxCallback(INST_LPUART_1,uart_rx_callback,(void *)&uart_rx);
/* Start to recive uart data */
LPUART_DRV_ReceiveData(INST_LPUART_1,&uart_rx.data,1);
}以上程序初始化接收流程也比较清晰,初始化串口开启UART接收中断,在串口接收中断回调函数中将数据写入环形buffer,接收一字节后继续开启启动一次接收,每次接收长度为1字节。
本地debug 查看串口中更新的ringbuff 数据结构,发现按下↑键,中断触发了两次,对应接收到两个数据分别为 0x1b 0xd0,第一个字节数据是对的后面是不正确的。

调查过程:
先使用逻辑分析仪抓取串口接收的物理层数是正确的,从而确定是接收端数据丢失的原因。

查看代码发现S32K1XX的串口中断接收处理中,在中断接收完成后会关闭LPUART的接收功能,看到此处理方式基本可以确定数据丢失原因为短暂的关闭了UART接收功能,上述逻辑分析仪抓取的数据可以看出数据此时为持续的,这时关闭UART功能会造成数据的丢失。

我们注释掉上述的处理后,功能恢复正常,从而确定是此处代码的原因。
我们已经可以确认是这块代码的问题了,我们继续通过逻辑分析仪,在关闭uart 接收功能处,添加IO状态查看当前uart 接收功能。

在此复现之前的问题查看uart 接收数据期间的状态,接收功能被关闭了100us
故障修改:
问题原因明确后,修改方案我们最简单的方式删除该处理,,因为该处理会被SDK的多个接口调用,删除会对sdk的代码造成未知的影响,为了兼容现有sdk 代码的处理方式,sdk 使用lpuart_state_t 来管理驱动的访问方式,在lpuart 初始化后我们可以获取到该结构,在该成员中添加enableRecive 成员控制是否需要关闭uart 接收功能。

串口初始化后设置该成员为true

修改接收中断完成处理逻辑,根据用户配置来是否屏蔽该段代码。

修改后运行代码功能串口丢数据问题得到解决。
我要赚赏金
