最近在调试一个新板子,我负责板子上通讯模块程序的编写和调试,调试的时候断断续续遇到不少问题,在这里记录下。

调试CAN收发过程中遇到的问题

1 现象

接上篇CAN/LIN的收发程序调通了之后,紧接着整体的路由功能也都实现了,本以为皆大欢喜,后面用板子试了上下电,再进行测试发现,CANoe只能接收几次由CAN2在接收中断里执行的发送任务里发出的报文,而不是稳定的报文。接下来就开启了漫长的调试过程。

2 调试

这路CAN的功能其实很简单,有两个任务,任务一:接收到其他节点发过来的标准CAN报文,触发中断调用Callback函数,在Callback函数里把接收到的报文原封不动的传回去、任务二:每隔100ms就周期性的发几帧报文。以前的项目里这两个功能其实已经实现过了,所以觉得很奇怪为什么板子冷启动之后突然就不行了。
从现象来看,CANoe是可以通过CAN2发出报文,这说明CAN模块是可以正常接收报文,因为如果板子没法接收报文,CANoe会报Not Acknowledge,同时,在CANoe端也可以读到通过CAN2发出的报文,说明板子的CAN模块是可以正常工作的,所以分析直接原因是板子的冷启动导致了CAN2在上电后只能几次进入中断,再往后就无法进入中断调用Callback函数。
开始怀疑是把两路CAN的接收函数放在同一个while(1)里导致的,尝试了把两个接收函数放到了两个任务里,结果仍然进不去中断。
然后怀疑其他模块的任务占用了我的CAN的资源,然后把其他任务注释掉,发现还是不行。
这时候同事提醒我可能不是CAN没有进中断,而是压根CAN没收到报文。那为什么CANoe显示发送成功了呢?因为Transiver或者MCU接收到报文后在硬件层面回复了ACK,但是实际上并没有把收到的报文放到邮箱里,也就不会触发中断调用Callback函数。那么到这里,立马验证到底是没有进中断还是没有进Receive()函数。
这里用到一个小技巧,可以用示波器读MCU输出引脚电平状态的方法,不需要MCU在DEBUG模式下,就可以观测到函数有没有运行到设定的地方。
由于没有直接使用中断函数,而是调用的Callback函数,所以在Callback函数里加入了电平翻转的功能,只要Callback函数被调用了,目标引脚的电平就会不停翻转。代码如下。代码下载进去,上下电后测试PTE3引脚的电平状态,短暂变化几次后保持不变。

void CAN1_TX_RX_Callback(uint8_t instance, flexcan_event_type_t eventType, uint32_t buffIdx, flexcan_state_t *flexcanState)
{if(instance == 1){PINS_DRV_SetPinDirection(PTE, 3, 1);PINS_DRV_TogglePins(PTE, 1<<3);}else if(instance == 0){//if(Msg_CanRxbuffer.msgId || Msg_CanRxbuffer.data[0]){PINS_DRV_SetPinDirection(PTE, 9, 1);PINS_DRV_TogglePins(PTE, 1<<9);}}if(eventType == FLEXCAN_EVENT_RX_COMPLETE)          //receive completed{//CAN1_HandleRequest();}
}

再往上查,FLEXCAN_IRQHandlerRxMB这个函数里调用了Callback函数,把电平翻转的代码插到这个函数里。

 if(instance == 1){PINS_DRV_SetPinDirection(PTE, 3, 1);PINS_DRV_TogglePins(PTE, 1<<3);}else if(instance == 0){//if(Msg_CanRxbuffer.msgId || Msg_CanRxbuffer.data[0]){PINS_DRV_SetPinDirection(PTE, 9, 1);PINS_DRV_TogglePins(PTE, 1<<9);}}/* Invoke callback */if (state->callback != NULL){state->callback(instance, FLEXCAN_EVENT_RX_COMPLETE, mb_idx, state);}

再次测试,现象与刚才的一致。再往上查,发现FLEXCAN_IRQHandler这个函数调用了FLEXCAN_IRQHandlerRxMB这个函数,于是插入调试代码。

     /* Check mailbox completed reception */if (state->mbs[mb_idx].state == FLEXCAN_MB_RX_BUSY){if(instance == 1){PINS_DRV_SetPinDirection(PTE, 3, 1);PINS_DRV_TogglePins(PTE, 1<<3);}else if(instance == 0){//if(Msg_CanRxbuffer.msgId || Msg_CanRxbuffer.data[0]){PINS_DRV_SetPinDirection(PTE, 9, 1);PINS_DRV_TogglePins(PTE, 1<<9);}}FLEXCAN_IRQHandlerRxMB(instance, mb_idx);}

再次测试,现象与刚才的一致。于是把测试代码拿出这个if语句,判断是否与邮箱的状态有关。

    if(instance == 1){PINS_DRV_SetPinDirection(PTE, 3, 1);PINS_DRV_TogglePins(PTE, 1<<3);}else if(instance == 0){//if(Msg_CanRxbuffer.msgId || Msg_CanRxbuffer.data[0]){PINS_DRV_SetPinDirection(PTE, 9, 1);PINS_DRV_TogglePins(PTE, 1<<9);}}/* Check mailbox completed reception */if (state->mbs[mb_idx].state == FLEXCAN_MB_RX_BUSY){FLEXCAN_IRQHandlerRxMB(instance, mb_idx);}

经过测试,终于发现了异常。当把测试代码放到判断邮箱状态上一行后,此时PTE9引脚的输出电平会一直变化。也就是说每次代码执行到这里时邮箱都是FLEXCAN_MB_RX_IDLE的状态,然后通过查看CAN模块的FLEXCAN_DRV_Receive函数

    /* Start receiving mailbox */if(state->mbs[mb_idx].state != FLEXCAN_MB_IDLE){return STATUS_BUSY;}state->mbs[mb_idx].state = FLEXCAN_MB_RX_BUSY;state->mbs[mb_idx].mb_message = data;state->mbs[mb_idx].isBlocking = isBlocking;/* Enable MB interrupt*/result = FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, true);if (result != STATUS_SUCCESS){state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;}

只有当程序判断当前邮箱是FLEXCAN_MB_IDLE的状态,才会开启邮箱的接收过程,同时更改邮箱状态为FLEXCAN_MB_RX_BUSY。
这说明,之前所有的测试例子中,由于某种原因,邮箱是FLEXCAN_MB_RX_BUSY的状态,导致无法将data里的数据放入到邮箱中,邮箱无法启动接收过程。但是由于上一次接收成功的过程中已经打开了中断使能,所以后面无论接收过程是否被启动,只要MCU的硬件完成了接收过程,就会触发中断进入到中断服务程序。
定位到问题后,再用CAN0_ReceiveData函数验证一下是否正确。

status_t CAN0_ReceiveData(void)
{status_t result;result = FLEXCAN_DRV_Receive(INST_CANCOM1, RX_MB_64BYTES, &Msg_CanRxbuffer);if(result == STATUS_SUCCESS){PINS_DRV_SetPinDirection(PTE, 3, 1);PINS_DRV_TogglePins(PTE, 1<<3);}return result;
}

经过测试,发现PTE3输出电平不会翻转,验证了判断是正确的。
到这一步,问题排查就很清晰了。用测试代码一层一层往上测试,发现负责通讯的任务都挂掉了。再测试其他任务,发现都是挂掉的状态。
经过与硬件工程师讨论,板子上负责芯片供电的VDD本来有一颗电解电容用于稳压的,由于时间原因没有焊上去,导致输出电压不稳定,也间接让程序里多个用软件计时的任务挂掉了。而用硬件计时的定时器任务完好无损,这也是为什么定时器中断函数能够稳定的执行,并稳定的输出100ms的CAN报文。
VDD输出波形见下图。

S32K144调试记录(二)相关推荐

  1. S32K144调试记录(一)

    最近在开发S32K144的CAN/LIN模块,调试的时候断断续续遇到不少问题,在这里记录下. 调试CAN/LIN收发过程中出现的问题 1 现象 1.1 CAN CANoe一直报Tx stuff err ...

  2. S32DS使用Jlink下载S32K144程序记录

    一,S32DS配置. 参考文章 在S32DS中使用J-Link调试S32K144开发板_大橙员的博客-CSDN博客 新建工程 以自带例程"S32K144_Project_ADC"为 ...

  3. ROS上同时预览depth,IR,RGB 调试记录

    ROS上同时预览depth,IR,RGB 调试记录 用rviz同时显示RGB,IR,DEPTH(验证设备:astraprosm,canglong2,deeyea) 1.编译libuvc库 cd lib ...

  4. 松下MINAS-A6伺服电机调试记录

    松下MINAS-A6伺服电机调试记录 因项目需求,进行松下MINAS-A6伺服电机调试 文章目录 松下MINAS-A6伺服电机调试记录 概述 一.手册数据 二.设备使用 1.驱动器及电机连接 2.设备 ...

  5. AML8726调试记录

    一:源代码下载: 1:Installing Repo # mkdir ~/bin # PATH=~/bin:$PATH # curl https://dl-ssl.google.com/dl/goog ...

  6. 海思NNIE开发(一):海思Hi3559AV100/Hi3519AV100 NNIE深度学习模块开发与调试记录

    海思NNIE开发系列文章: 海思NNIE开发(一):海思Hi3559AV100/Hi3519AV100 NNIE深度学习模块开发与调试记录 海思NNIE开发(二):FasterRCNN在海思NNIE平 ...

  7. 煤炭超临界水气化与超临界燃烧传热耦合Fluent模拟(调试记录)

    煤炭超临界水气化与超临界燃烧传热耦合Fluent模拟(调试记录) 这是一篇fluent数值计算的调试记录(自分用) ------------------------------------------ ...

  8. RK3568开发笔记-EDP显示屏接口调试记录

    目录 文章目录 前言 一.edp显示接口介绍 二.edp接口部分原理图 三.edp接口显示屏参数介绍 四.RK3568设备树参数配置 五.完整DTS edp参数 六.RK3568多屏显示vop选择 七 ...

  9. 2020-02-24 RK3288 Android7.1 5.1 增加AP6256 WI-FI Bluetooth调试记录

    RK3288 Android7.1 5.1 增加AP6256 WI-FI Bluetooth调试记录 一.硬件连接图,AP6335.AP6255.AP6256 Pin对Pin,可以直接替换. 二.原本 ...

最新文章

  1. 快速提高你的UI设计水平的一些小技巧
  2. 【scala】 scala 条件控制 和异常处理(二)
  3. 原始套接字SOCK_RAW
  4. 树莓派进阶之路 (037) - 设置树莓派3 B+的静态IP
  5. Linux中的文件描述符与打开文件之间的关系
  6. 库存管理-历史库存和收发存系列-俄罗斯库存报表J3RFLVMOBVED1
  7. spring boot基础教程:入门程序Hello World的编写
  8. 推荐21个顶级的Vue UI库! – TalkingData‘s Blog
  9. [置顶] 删除:大数据取舍之道读书笔记
  10. 性能测试——loadrunner_添加多个主机发送请求
  11. 使用强类型DataSet增加数据并获取自动增长的ID
  12. Atitit 编程语言原理与概论attilax总结
  13. 武汉CMMI3-CMMI5三年到期后复审指南
  14. 微信小程序实现物流步骤条
  15. 【黑灰产犯罪研究】恶意点击
  16. 高压均质机原理、使用方法及维护注意事项
  17. 首次登录Navicat连接数据库遇到的问题
  18. 2022-XTU程设练习1
  19. 蓝宇数码冲刺深交所:年营收2.72亿 郭振荣控制45%股权
  20. cesium颜色值赋值

热门文章

  1. 豆瓣读者董董:王博士的格子衬衫与怀里的蛇
  2. 相约3.8!罗.姆EEPROM在线研讨会
  3. Microsoft Visual Studio 2019介绍之使用入门
  4. 游戏原画是怎样的?加班多么?
  5. 解决百度地图(new BMap.Autocomplete)影响input赋值的问题
  6. 如何利用SEO方式使网站增加流量
  7. python 利用火狐浏览器爬取内容
  8. 微信小程序使用towxml解析md/html
  9. 苏州银行信息技术面试
  10. 2010年度总结-在淘宝的半年日子