OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2968|回复: 2

F407 FreeRTOS开启任务前,使用进入临界区taskENTER_CRITICAL()和退出临界区taskEXIT_CRITICAL()函数,导致中断不启动

[复制链接]

1

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2018-8-2
在线时间
47 小时
发表于 2020-2-18 12:12:46 | 显示全部楼层 |阅读模式
50金钱
f407使用FreeRTOS,在程序创建开启任务前,硬件初始化中,使用了进入临界区taskENTER_CRITICAL()和退出临界区taskEXIT_CRITICAL()函数,导致在使用vTaskStartScheduler()开启任务前中断不开启,已验证在任务中使用进入和退出临界区是没有什么问题的,请问下大家这是什么问题?


        mymalloc(SRAMIN,1024); //这里使用了taskENTER_CRITICAL()进入临界区函数
        while(1)         //实验强制进入死循环
        {
                IWDG_Feed();  //喂狗
                LEDWORK_Set(LED_MODE_FLICKER,100,100); //工作指示灯故障闪烁
                printf("error:TF f_mount Failed! return->%d\r\n",ret);
                delay_ms(500);
                printf("Please check!\r\n");       
                delay_ms(500);       
        }
        LEDWORK_Set(LED_MODE_FLICKER,500,500); //工作指示灯正常闪烁
       
       AppTaskCreate();       /* 创建任务 */
       vTaskStartScheduler(); /* 开启任务 */
       
        for(;;)
        {
        }





最佳答案

查看完整内容[请看2#楼]

问题已经解决,进一步的跟踪 taskENTER_CRITICAL()和taskEXIT_CRITICAL()这两个宏调用 #define taskENTER_CRITICAL() portENTER_CRITICAL() #define taskEXIT_CRITICAL() portEXIT_CRITICAL(), 再进一步的跟踪, void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* This is not the interrupt safe version of the enter critical function so assert() if it is being c ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2018-8-2
在线时间
47 小时
 楼主| 发表于 2020-2-18 12:12:47 | 显示全部楼层
问题已经解决,进一步的跟踪 taskENTER_CRITICAL()和taskEXIT_CRITICAL()这两个宏调用  
#define taskENTER_CRITICAL() portENTER_CRITICAL()
#define taskEXIT_CRITICAL() portEXIT_CRITICAL(),
再进一步的跟踪,

void vPortEnterCritical( void )
{
        portDISABLE_INTERRUPTS();
        uxCriticalNesting++;

        /* This is not the interrupt safe version of the enter critical function so
        assert() if it is being called from an interrupt context.  Only API
        functions that end in "FromISR" can be used in an interrupt.  Only assert if
        the critical nesting count is 1 to protect against recursive calls if the
        assert function also uses a critical section. */
        if( uxCriticalNesting == 1 )
        {
                configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
        }
}

void vPortExitCritical( void )
{
        configASSERT( uxCriticalNesting );
        uxCriticalNesting--;
        if( uxCriticalNesting == 0 )
        {
                portENABLE_INTERRUPTS();
        }
}

问题就在uxCriticalNesting这个变量,这个变量是用于临界段的嵌套计数,该变量的默认static UBaseType_t uxCriticalNesting = 0xaaaaaaaa,
该变量在开启任务vTaskStartScheduler()函数中进行初始化,所以导致未初始化的该变量时,使用taskENTER_CRITICAL()和taskEXIT_CRITICAL()函数时,
vPortExitCritical()函数中是未执行打开中断的函数portENABLE_INTERRUPTS()的。
回复

使用道具 举报

1

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2018-8-2
在线时间
47 小时
 楼主| 发表于 2020-2-18 15:42:47 | 显示全部楼层
taskENTER_CRITICAL()将所有低于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的中断关闭,以防止被中断打断,但是在使用taskEXIT_CRITICAL()函数时,并没有将已关闭的中断打开,使用这个函数portENABLE_INTERRUPTS()可将中断开启。但是在任务中就不存在这个问题,有点搞不懂
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-8 06:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表