今天遇到一个问题,Freertos卡在vPortEnterCritical断言中了,从vPortEnterCritical中的代码可以看到,此时在中断中执行了vPortEnterCritical。在检查完代码后,还是没注意到是在哪里调用了这个方法(老眼昏花了)。于是添加了几行log,轻松定位到问题。
1.错误日志:
RTOS_CORE [I] vPortValidateInterruptPriority:754 ulCurrentInterrupt:0x44
RTOS_CORE [I] vPortValidateInterruptPriority:785 ucCurrentPriority:0x30,ucMaxSysCallPriority:0x20
RTOS_CORE [I] vPortValidateInterruptPriority:786 result:1
RTOS_CORE [D] vPortValidateInterruptPriority:803 reg:300,val:300
RTOS_CORE [D] uxQueueMessagesWaiting:1585 E
RTOS_CORE [D] vPortEnterCritical:443 IRQ[44]:TIM2 ----中断TIM2中调用了没有ISR的函数
RTOS_CORE [E] vPortEnterCritical:445 ASSERT ERROR:0 ----RTOS卡在这里,445行
vPortEnterCritical中添加日志,判断是否有中断发生。CortexM4Int2String()打印对应中断的名字。从上面的日志可以看到,此时在中断TIM2中。
2.vPortEnterCritical添加日志
3.portmacro.h中宏修改
注意待代码稳定后,请删掉日志或者关闭对应的log。
#define vPortEnterCriticalDbg( ) \
do { \
if( portNVIC_INT_CTRL_REG & 0xFF/*portVECTACTIVE_MASK*/) LOGD("E"); \
vPortEnterCritical(); \
} while (0)
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
#define portENTER_CRITICAL() vPortEnterCriticalDbg() //vPortEnterCritical()
此时运行即可发现在uxQueueMessagesWaiting()中执行,对用源码如下,唉,当时眼瞎了没看到!!!
//modbus post 方法
BOOL
xMBSlavePortEventPost( MBObj_t *pMbObj, eMBEventType eEvent )
{
BaseType_t xStatus, xHigherPriorityTaskWoken = pdFALSE;
assert(pMbObj->msg.pvMsgQueueHdl != NULL);
BOOL isIsr = (BOOL)xPortInterruptedFromISRContext();
MB_LOGD("isISR:%d",isIsr);
if( isIsr == TRUE )
{
xStatus = xQueueSendFromISR(pMbObj->msg.pvMsgQueueHdl, (const void*)&eEvent, &xHigherPriorityTaskWoken);
if ( xHigherPriorityTaskWoken )
{
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
if (xStatus != pdTRUE) {//===================下面uxQueueMessagesWaiting中调用了临界区代码
MB_LOGE("[INT]Faied to post msg st:%x.pendMsg:%d",xStatus, uxQueueMessagesWaiting(pMbObj->msg.pvMsgQueueHdl));
return FALSE;
}
}
else
{
xStatus = xQueueSend(pMbObj->msg.pvMsgQueueHdl, (const void*)&eEvent, MB_EVENT_QUEUE_TIMEOUT);
if (xStatus != pdTRUE)
{
MB_LOGE("Faied to post msg st:%x.pendMsg:%d",xStatus, uxQueueMessagesWaiting(pMbObj->msg.pvMsgQueueHdl));
}
}
return TRUE;
}
将上面的 uxQueueMessagesWaiting 改成uxQueueMessagesWaitingFromISR问题解决。
版权声明:本文为armwind原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。