SemiDrive UART 移植说明及问题分析

一、移植背景

SemiDrive MCAL3.0 里没有 UART 相关配置,并且 MCAL 里 UART 驱动不完善,若有需要可以从 SSDK 中将 UART 相关驱动移植到 MCAL 中使用。


二、移植步骤

1、将 sdrv_uart.c/h 和 uart_cfg.c/h 文件移植到 MCAL 对应“E3\Semidrive_AutoSAR_MCAL_package_v3.0.0\MCAL_release\driver\uart”文件中。并添加到 IAR 工程中。



2、修改 sdrv_uart.c 中 #include <sdrv_common.h> 为 #include <sdrv_btm_common.h>;#include <irq_num.h>改为#include <irq_num_sf.h>;注释 #include <string.h>。



3、修改 uart_cfg.c 中头文件命名,将 #include <regs_base.h> 改为 #include <__regs_base.h>。



4、注释 sdrv_uart.h 中 __BEGIN_CDECLS 和 __END_CDECLS。

5、修改 UART 中断函数,将 int sdrv_uart_irq_handler(uint32 irq, void *ctrl) 改为 void sdrv_uart_irq_handler(void),并且使用 extern 将 uart_ctrl_ptr 结构体拉到 sdrv_uart.h 中,替换中断函数中的 ctrl。



6、在“E3\Semidrive_AutoSAR_MCAL_package_v3.0.0\MCAL_release\test_suite\example“添加 uart_example 文件,将 SSDK 中 uart_interrupt_disposable 例程添加到 uart_example.c 中。




三、调试步骤

1、使用 e3_gateway 开发板测试,分别在 R711 和 R709 跳线,使用逻辑分析仪抓取 Uart_Tx/Rx 波形。



2、串口输入 runcase 3500 启动 Uart test 例程,500ms 串口发送一次数据。




3、使用示波器获取 Uart_Tx/Rx 波形,可以看到 Tx 500ms 发送一次数据,解码后数据与实际发送数据一致,Rx 接收到的数据与实际波形也是一致。








四、客户问题分析

1、问题详述

在客户板子上将 SSDK Uart 移植到 MCAL 中,使用 Uart 与高压采集芯片通讯,工程全速运行时通过逻辑分析仪查看 Uart 通讯波形和信号正常,但暂停后再次运行,代码里通讯状态标志位一直显示复位或初始化,无法执行完成整个发送流程,逻辑分析仪抓取的波形中只能看到唤醒波形,无 Uart_Tx 发送波形。

2、解决思路

① 使用劳德巴赫单步调试发现异步发送的时候,remain 这个变量断点后调试,赋值赋不进去,一直为零,volatile 修饰 remain,把 volatile 注释掉,remain 可以赋值,但是代码全速跑只能发一帧报文;增加 Uart_SetStatus 接口清除 TX_BUSY,增加后全速运行也通讯异常。

② 按照客户驱动运行逻辑,单步调试,发现断点后,出现的并不是 TX_BUSY 而是 RX_BUSY,完善 Uart_SetStatus 函数接口,增加分别判断 T/RX_STATE 状态的逻辑,不为 IDLE,才将其设置为 BUSY,修改完成后编译调试,Attach 暂停后再继续运行,代码运行正常,逻辑分析仪抓取波形正常,UART 与高压采集芯片通讯正常。

③ 将客户中断函数 Uart_133_E3xx_IntrHandler 替换为 sdrv_uart_irq_handler 函数,并且将 sdrv_uart_read_async 重新加上“static inline”修饰、sdrv_uart_send_async 重新加上”static inline“ 修饰,Attach 暂停后再继续运行,通讯依旧异常。

④ 使用移植到 MCAL 工程里的 Uart 驱动,按照客户的方式在发送函数前先判断 rx_state 是否为 Idle,使用 E3640 开发板测试,Tx 只能发送一次,rx_state 一直为 busy,状态位无法被清除,一直不进 Tx 发送函数。

3、根因分析

① 当 E3 与高压采集芯片正常通讯时,Uart_Tx 每次发送数据给高压采集芯片,高压采集芯片也同要会回复数据给 E3,此时每次 Tx 中断执行完成后都会有 Rx 中断执行,并在 Rx 中断中将 rx_state 置为 Idle,所以 E3 和高压采集芯片能够正常通讯。

② 当程序暂停运行,sdrv_uart_async_transmit 发送完数据,调用 sdrv_uart_async_receive 函数接收 Uart_Rx 发送的数据,由于程序暂停 E3 接收不到高压采集芯片发送来的数据,无法进入 Rx 中断函数中清除 rx_state 的状态,因此 rx_state 一直为 Busy,而软件逻辑必须是 rx_state 为 Idle 才能调用 sdrv_uart_async_transmit 发送。当程序继续运行,就会陷入死循环,Tx 无法在发送数据。

4、解决方案

增加 Uart_SetStatus 函数,当 Uart_GetStatus 函数返回值不为 IDLE,则通过 Uart_SetStatus 函数将 T/RX_STATE 的状态置为 IDLE。修改后 Debug 调试暂停后再开始 Uart 与高压采集芯片通讯正常。


五、参考文档

参考:《SemiDrive_E3_SSDK_User_Guide_Rev01.04》

参考:《SemiDrive_E3_MCAL_User_Guide_Rev03.00》

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论