完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
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. 现象: 串口发送(没用中断发送),---->有接收,又触发发送,导致死锁 |
|
相关推荐
14个回答
|
|
尽管是老帖子了,有些想法,希望对其他人有帮助。
最近调试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加锁语句也能正常工作。 |
|
|
|
你这不是CUBE导致的“死锁”,而是RTOS线程之间没有同步好导致的。
不能靠应用级别的标识来判断线程之间的同步和运行,而是要靠RTOS自身的信号量、事件等等来判断和同步线程。 你可以不用RTOS测试下,先保证应用可用,再调RTOS吧。 |
|
|
|
7762642422d 发表于 2019-1-2 17:22 感谢回复,!~~~~ 当前UART中断确实不是RTOS的,但是相对于来说比RTOS的中断级别要优先吧? 从当前的现在来看就是进入串口中断后,还是触发了串口发送,这个可能是RTOS引起的,因为这个中断接收串口里面没有LOCK,导致可以串口继续发送 |
|
|
|
这里可能是串口溢出导致的,当发生这样的问题时,判断huart->State ,重新执行串口初始化能解决。
|
|
|
|
|
|
|
|
本帖最后由 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 errrn", 11, 0xff); } } } |
|
|
|
楼主应该加上溢出的处理,当发生忙状态时,串口寄存器的值是多少,就知道是哪些错误导致的了。
|
|
|
|
rstech_rd 发表于 2019-1-2 18:05 你的程序逻辑有严重的潜在问题! HAL_UART_RxCpltCallback()函数是在中断里被调用的,而你又在该函数里面调用了发送函数: HAL_UART_Transmit()。 你看代码,HAL_UART_Transmit()会判断uart的状态,此时返回了HAL_BUSY。 另外即使不是由上述原因产生的,也没有这么用的。收发尽量一直(要么中断,要么阻塞式)。 再者,HAL_UART_RxCpltCallback()里面只能用HAL_UART_Receive_IT()类型的开启中断函数。 |
|
|
|
|
|
|
|
7762642422d 发表于 2019-1-2 18:35 HAL_UART_RxCpltCallback里面也不能用HAL_UART_Receive_IT, 会把ErrorCode覆盖掉, HAL_UART_Receive_IT只是开启中断函数, 可以在对应的IRQHandler最后执行. |
|
|
|
都是库害的
|
|
|
|
赶快放弃库哦
|
|
|
|
配置寄存器多方便
|
|
|
|
配置寄存器多方便
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
253 浏览 0 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
806 浏览 2 评论
1991 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1095 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1520 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-20 01:36 , Processed in 0.821528 second(s), Total 99, Slave 83 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号