manhuami2007的个人空间 https://bbs.21ic.com/?741514 [收藏] [复制] [RSS]

日志

论STM的HAL库与外设死机

已有 567 次阅读2017-1-4 22:29 |系统分类:嵌入式系统| 外设, 死机, uart, 串口, hal, uart, hal, uart, hal

前段时间的一个项目比较简单,就使用ST提供的CubeMx直接生成了工程,并在其基础上编写程序。不过串口用着用着就会出现死机而处理器没事。这是为什么?

通过调试和阅读代码,发现是因为串口出现了类似死锁的问题。


什么是死锁?


死锁是指两个或两个以上进程在执行过程中,由于竞争资源或者由于彼此通讯而造成的阻塞状态。

因此死锁的重点是多个进程使用同一资源。


没有操作系统为何出现的多个进程呢?

没有操作系统的嵌入式系统中也存在两个进程:

  • 后台程序,即main()等主循环函数
  • 中断处理程序

那么HAL库怎么造成了外设死锁的?

根据上面的分析,我们知道是由于主循环在使用外设的同时,中断也要使用这个外设。

先看看HAL库操作外设的简单流程图

程序先检查外设是否上锁,如果上锁则直接退出,没有上锁则上锁之后接着进行相应的设置最后执行后续操作。

问题就出在这个上锁上。我的程序使用的外设是UART,使用中断接收数据,使用DMA发送数据。在中断中收到一个字节之后,再打开中断接收下一个字节。在主循环中使用DMA发送相关的数据。

那么当主程序中使用正在设置UART发送时,也就是UART还处于锁定的状态时,进入了UART接收中断,这时在中断用又要设置UART接收,此时UART处于锁定状态,所以UART的接收设置肯定会失败。从而造成UART不能再接收数据。


怎么处理呢?

这种情况下,我们不能在中断中等待外设释放锁定,因为此时主循环中的程序无法执行,因此不能释放资源。

所以我们应该在中断中通过函数的返回值判断操作是否成功,若没有成功则设置一个标志位,然后再在主循环中检查这个标志位,并在主循环中重新进行操作。


总结

避免死锁最根本的方法就是防止在主循环与中断中同时使用同一外设。

如果不能避免,那么尽量做到执行每个函数后,都判断返回值是否正确,并对执行失败的操作做相应的处理。


欢迎大家添加我的微信公众号“光豆儿”



路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)