11/11/2020 记DMA冲突引发的血案
环境
硬件使用Pixhawk fmuv2版本,软件为基于rtthread的飞控。
问题现象
电机控制线程使用UART6-DMA模式下从F4向F1发送数据时,开启日志记录,或使用和文件系统相关的命令时,UART6串口停止发送数据。在不开启SD卡相关记录和命令时,电机控制线程正常。
犯罪现场
将PWM使用的IO抽象为一个设备时(F4为主控芯片控制电机转速,是经过UART6串口发送给F1,再通过F1控制电机。所以将PWM抽象为一个设备,PWM的读写又操作了串口设备。后续有详细过程)
-
信 量初始为1
-
对应的发送函数:
- 发送完成回调
具体现象
在记日志前,发送一次时取信 量,完成后释放信 量,每次发送都有回调。但是开启记日志后,发送后不会进入回调,也就不会释放信 量,导致下一次发送获取不到信 量,无法发送(其实看到这里就应该想到时SD卡的读取和UART6的收发底层配置冲突,但是CUBE软件误导了我,后面会说)。
排查过程
-
通过keil断点调试,发现发送回调是在logger.c中的函数后就收不到了。具体是在这个操作后。
-
继续进入函数查找问题
- 猜想一:在进行文件系统的操作时,进行了临界区的上锁,关闭硬件中断后,无法响应发送完成中断。
- 猜想二:文件系统优先级较高,一直占用CPU资源。使得UART6的DMA写入第一次未完成,就进行了第二次写入。第一次写入前取了信 量,但是由于被第二次打断了,没有完成发送完成中断的回调函数释放信 量。
? 对于猜想二,我直接将文件系统的优先级调至比电机驱动线程低,但问题仍未解决。
? 对于猜想一:文件系统是使用互斥量上锁,防止其他进程中间打断的,并不影响硬件中断的响应。
? 而在信 量获取或者释放过程中,的确进行了中断关闭,但是事件极短,在关闭期间丢掉了发送完成中断的几率很小。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!