Freertos vPortEnterCritical卡死调试方法

今天遇到一个问题,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问题解决。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值