你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于HAL UART 发送接收死锁问题

[复制链接]
benlarden 提问时间:2017-4-10 11:02 /
STM32F105S使用中断接收,触发UART_Receive_IT()中的   ......

   if(--huart->RxXferCount == 0)
    {
      __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);

      /* Check if a transmit process is ongoing or not */
      if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
      {
        huart->State = HAL_UART_STATE_BUSY_TX;
      }
      else
      {
        /* Disable the UART Parity Error Interrupt */
        __HAL_UART_DISABLE_IT(huart, UART_IT_PE);

        /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
        __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);

       huart->State = HAL_UART_STATE_READY;
      }
      HAL_UART_RxCpltCallback(huart);


      ......

     进入HAL_UART_RxCpltCallback(huart);后,判断huart->State 尽然不是上面的2个中的一个,然后返回HAL_BUSY状态,导致死锁


    请问哪位遇到过这种情况吗?请指点下,系统使用了FREERTOS.


    现象:
    串口发送(没用中断发送),---->有接收,又触发发送,导致死锁
<
收藏 4 评论12 发布时间:2017-4-10 11:02

举报

12个回答
giveup 回答时间:2018-6-24 11:00:56
尽管是老帖子了,有些想法,希望对其他人有帮助。
最近调试stm32f407vet6+freeRTOS+uart3/uart6的小程序。uart3/uart6都使用HAL_UART_Transmit_IT函数发送,uart3使用HAL_UART_Receive_IT接收,uart6只发送。上位机每40ms查询uart3,uart3反馈结果。
当然,在调试中肯定遇到了上面说的uart3不能接收的问题。设置了错误中断处理,仍然出现uart3随机性失去响应。调试中发现问题不是上面的原因,而是出现在hal库中HAL_UART_Receive_IT/HAL_UART_Transmit_IT函数处理上,具体讲, __HAL_LOCK(huart)处理不当。

上述两个函数存在于Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c中,大约786~863行。HAL库版本是:STM32Cube_FW_F4_V1.21.0。
发送函数和接收函数中,都出现了 __HAL_LOCK(huart)操作。这实现了对端口的全局加锁。然而,此处却是欠考虑:huart是全双工的,如果APP调用HAL_UART_Transmit_IT在tx操作中执行了 __HAL_LOCK(huart)操作,还没有执行 __HAL_UNLOCK(huart)时发生了rx接收中断,在HAL_UART_RxCpltCallback调用中重新设定HAL_UART_Receive_IT就会出现HAL_BUSY错误。而实际上,这种状态下,硬件都是正常,完全能工作的。观察两个函数中 __HAL_LOCK(huart)和 __HAL_UNLOCK(huart)之间保护的全局变量,只有一个 huart->ErrorCode = HAL_UART_ERROR_NONE是存在冲突的。然而,在错误处理回调函数中,这个错误码一般都检测不到。换句话说,这个加锁操作锁的范围比较大,造成了 Tx和Rx操作的冲突。
当然,如果在启动Rx设定时发生Tx中断,也会因相同原因发生Tx启动失败。
总结一句话,出现HAL_BUSY错误的原因之一是两个函数中加锁操作造成的。
解决的办法:检查HAL_UART_RxCpltCallback调用中重新设定HAL_UART_Receive_IT的返回值,若出现HAL_BUSY错误,进一步检查huart->RxState是否忙,决定是否重新调用启动接收。
当然,不推荐的做法是简单注释掉HAL库中HAL_UART_Receive_IT加锁语句也能正常工作。
moyanming2013 回答时间:2017-4-10 12:12:37
你这不是CUBE导致的“死锁”,而是RTOS线程之间没有同步好导致的。
不能靠应用级别的标识来判断线程之间的同步和运行,而是要靠RTOS自身的信号量、事件等等来判断和同步线程。
你可以不用RTOS测试下,先保证应用可用,再调RTOS吧。
benlarden 回答时间:2017-4-10 12:23:35
moyanming2013 发表于 2017-4-10 12:12
你这不是CUBE导致的“死锁”,而是RTOS线程之间没有同步好导致的。
不能靠应用级别的标识来判断线程之间的 ...

感谢回复,!~~~~
当前UART中断确实不是RTOS的,但是相对于来说比RTOS的中断级别要优先吧?
从当前的现在来看就是进入串口中断后,还是触发了串口发送,这个可能是RTOS引起的,因为这个中断接收串口里面没有LOCK,导致可以串口继续发送
回答时间:2017-4-10 13:16:27
这里可能是串口溢出导致的,当发生这样的问题时,判断huart->State ,重新执行串口初始化能解决。
benlarden 回答时间:2017-4-10 13:38:42
安 发表于 2017-4-10 13:16
这里可能是串口溢出导致的,当发生这样的问题时,判断huart->State ,重新执行串口初始化能解决。 ...

谢谢版主!~~
应该不是溢出,因为每次我只接收一个字节!~~
重新初始化确实可以!~~
benlarden 回答时间:2017-4-10 13:46:33
本帖最后由 benlarden 于 2017-4-10 14:02 编辑

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_UART_RxCpltCallback can be implemented in the user file
   */
        
        if(huart->Instance == USART3){
                ......//recv process

                cRxBuffPtr[0] = 0;
                if(HAL_UART_Receive_IT(huart,cRxBuffPtr[0],1) != HAL_OK){
                        HAL_UART_Transmit(&huart5, (uint8_t *)"uart3 err\r\n", 11, 0xff);
                }
        }
}
回答时间:2017-4-10 14:49:39
楼主应该加上溢出的处理,当发生忙状态时,串口寄存器的值是多少,就知道是哪些错误导致的了。
moyanming2013 回答时间:2017-4-10 15:28:21
benlarden 发表于 2017-4-10 13:46
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* NOTE: This function should not be mod ...

你的程序逻辑有严重的潜在问题!
HAL_UART_RxCpltCallback()函数是在中断里被调用的,而你又在该函数里面调用了发送函数:
HAL_UART_Transmit()。
你看代码,HAL_UART_Transmit()会判断uart的状态,此时返回了HAL_BUSY。
另外即使不是由上述原因产生的,也没有这么用的。收发尽量一直(要么中断,要么阻塞式)。
再者,HAL_UART_RxCpltCallback()里面只能用HAL_UART_Receive_IT()类型的开启中断函数。
benlarden 回答时间:2017-4-10 20:21:59
moyanming2013 发表于 2017-4-10 15:28
你的程序逻辑有严重的潜在问题!
HAL_UART_RxCpltCallback()函数是在中断里被调用的,而你又在该函数里面 ...

这个发送是调试串口,只是为了测试使用。
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版