OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3526|回复: 1

HAL_UART_Receive_IT使用时的死锁问题

[复制链接]

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2013-10-10
在线时间
12 小时
发表于 2018-8-2 11:23:04 | 显示全部楼层 |阅读模式
本帖最后由 紫阳真人 于 2018-8-2 12:20 编辑

主函数循环里面开启了printf,后面不加延时,并且HAL_UART_Receive_IT写在中断里,通过上位机给发送指令程序会卡死。单片机接收指令后,中断里HAL_UART_Receive_IT不会返回HAL_OK,但是退出中断在主函数循环里再次调用HAL_UART_Receive_IT的时候正常。
主函数循环部分代码如下:
while (1)
  {
                printf("\nLocation:%d",AdcValueFilter(MOTOR_LOCATION));
//                HAL_Delay(50);/**/
//                HAL_UART_Receive_IT(&huart3,(uint8_t*)aRxBuffer,4);

                /*其他*/
}
中断回调函数部分代码:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
        do
        {
                ret = HAL_UART_Receive_IT(&huart3,(uint8_t*)aRxBuffer,4);/*判忙?*/
        }
        while(ret != HAL_OK);

}
以下是在上面程序上做修改后的现象:
1、如程序所示,此时接收一次数据之后直接在do while里面死循环;
2、把do while去掉,只留HAL_UART_Receive_IT,系统接收一次之后不能再接收;
3、主函数加上HAL_Delay(50);正常;
4、HAL_UART_Receive_IT写在主函数,中断里do while去掉,正常;
5、去掉主函数里的printf语句,正常;
请问到底是哪里出了问题,原理是什么,该怎么改?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2013-10-10
在线时间
12 小时
 楼主| 发表于 2018-8-2 12:56:02 | 显示全部楼层
本帖最后由 紫阳真人 于 2018-8-2 13:01 编辑

printf函数通过HAL_UART_Transmit发送的时候调用了__HAL_LOCK(huart);
HAL_UART_Receive_IT函数也调用了__HAL_LOCK(huart);
猜测中断里的HAL_UART_Receive_IT调用__HAL_LOCK(huart);的同时,主函数正在通过printf调用__HAL_LOCK(huart);于是发生了死锁。此时主函数是停滞的,在中断里每当调用HAL_UART_Receive_IT的时候就会直接返回一个HAL_BUSY,在do while语句中无限循环下去。另外加延时函数可以避免死锁,我猜测是通过延时避开了__HAL_LOCK(huart);后测试延时越短死锁概率越高,猜测基本成立。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 03:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表