Freertos 下的__HAL_LOCK(stm32)问题
最近发现一个问题,stm32 的HAL库中有__HAL_LOCK和__HAL_UNLOCK在串口发送和接受函数中都存在,但是这样一来,串口就无法全双工了
#define __HAL_LOCK(__HANDLE__) \
do{ \
if((__HANDLE__)->Lock == HAL_LOCKED) \
{ \
return HAL_BUSY; \
} \
else \
{ \
(__HANDLE__)->Lock = HAL_LOCKED; \
} \
}while (0U)
#define __HAL_UNLOCK(__HANDLE__) \
do{ \
(__HANDLE__)->Lock = HAL_UNLOCKED; \
}while (0U)
而在LWIP应用中,也有这样的问题,
low_level_output函数调用
HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
{
uint32_t bufcount = 0, size = 0, i = 0;
/* Process Locked */
__HAL_LOCK(heth);
这样的话,因为接受数据是在单独的线程中,如果要发送的时候正在接受,那么是不是意味着发送就莫名其妙的失败了,而且不是tcp的话,还不能重发
HAL库的锁机制不支持RTOS,而且不支持嵌套,是在接收的时候直接将其又开锁了。
我分析是这样,楼主看看对不对,以lwip为例
发送:
low_level_output ->HAL_ETH_TransmitFrame
接收接收中断:
HAL_ETH_IRQHandler -> 中断函数里面接收完成回调发送信号量 -> 中断函数结束时直接开锁了->等待信号量函数ethernetif_input ->low_level_input ->low_level_input->HAL_ETH_GetReceivedFrame_IT
由于接收在中断里面强行开启了锁,所以就不存在你说的发送时加上了锁后对接收的影响。
missfox 发表于 2019-7-19 11:14
HAL库的锁机制不支持RTOS,而且不支持嵌套,是在接收的时候直接将其又开锁了。
我分析是这样,楼主看看 ...
还是会存在影响的,接受是在单独的进程里面的
osThreadDef(EthIf, ethernetif_input, osPriorityRealtime, 0, INTERFACE_THREAD_STACK_SIZE);
osThreadCreate (osThread(EthIf), netif);
所以在其他进程里面发送数据,那么HAL_LOCK有被同时调用的风险(并发风险),但接受在一个while函数里面,所以影响不大
for( ;; )
{
if (osSemaphoreWait( s_xSemaphore, TIME_WAITING_FOR_INPUT)==osOK)
{
do
{
p = low_level_input( netif );
if (p != NULL)
{
if (netif->input( p, netif) != ERR_OK )
{
pbuf_free(p);
}
}
} while(p!=NULL);
}
}
但发送就可能受到影响
寒号鸟 发表于 2019-7-19 11:46
还是会存在影响的,接受是在单独的进程里面的
osThreadDef(EthIf, ethernetif_input, osPriorityRealti ...
这个处理办法就简单很多了,提升接收任务的优先级可解决。
接收任务的优先级高,就不会存在发送被影响的情况。 理解了,谢谢 missfox 发表于 2019-7-19 12:05
这个处理办法就简单很多了,提升接收任务的优先级可解决。
接收任务的优先级高,就不会存在发送被影响 ...
理解了,谢谢 missfox 发表于 2019-7-19 12:05
这个处理办法就简单很多了,提升接收任务的优先级可解决。
接收任务的优先级高,就不会存在发送被影响 ...
我今天思考了一下,发现还是会存在一种情况,您看我的想法是否合理
如果正在发送中(__HAL_locked已经加锁),突然来了一个接受中断(中断里面),
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
osSemaphoreRelease(s_xSemaphore);
}
然后接受函数被运行(接受函数的优先级高)
void ethernetif_input( void const * argument )
{
。。。。。
if (osSemaphoreWait( s_xSemaphore, TIME_WAITING_FOR_INPUT)==osOK)
{
do
{
p = low_level_input( netif );
if (p != NULL)
{
if (netif->input( p, netif) != ERR_OK )
{
pbuf_free(p);
}
}
}while(p!=NULL);
}
}
}
但是这个时候,注意发送函数正在发送(__HAL_LOCKD已经刚刚被发送加锁了),所以low_level_input肯定返回NULL(因为HAL_ETH_GetReceivedFrame_IT的HAL_LOCK返回busy,自然该函数会返回NULL),这样一来本次接收不就失败了嘛,本次的包就没有了
寒号鸟_SyD58 发表于 2019-7-20 10:09
我今天思考了一下,发现还是会存在一种情况,您看我的想法是否合理
如果正在发送中(__HAL_locked已经 ...
二楼已经回复你这种情况,在ETH中断接收处理函数里面已经开锁了。看下中断函数就明白了
页:
[1]