硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3744|回复: 1
收起左侧

[FreeRTOS] FREERTOS   中断中唤醒了高优先级任务 需要切换任务   不太理

[复制链接]

22

主题

12

回帖

21

积分

新手上路

积分
21
发表于 2016-8-16 17:23:04 | 显示全部楼层 |阅读模式
楼主,我看的8.2.3的版本,我如果  在任务中使用了   vTaskSuspendAll,,然后再中断中调用xQueueGenericSendFromISR    然后是 xTaskRemoveFromEventList  这个函数会判断是否唤醒了高优先级任务

         if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
    {
        /* Return true if the task removed from the event list has a higher
        priority than the calling task.  This allows the calling task to know if
        it should force a context switch now. */
        xReturn = pdTRUE;


        /* Mark that a yield is pending in case the user is not using the
        "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
        xYieldPending = pdTRUE;
    }
xYieldPending 这个变量被设置了为真;

然后在每次时钟滴答时  都会:执行 xTaskIncrementTick  这个函数大体框架是:



BaseType_t xTaskIncrementTick( void ){
          TCB_t * pxTCB;         TickType_t xItemValue;
         BaseType_t xSwitchRequired = pdFALSE;

    /* Called by the portable layer each time a tick interrupt occurs.    Increments the tick then checks to see if the new tick value will cause any
    tasks to be unblocked. */    traceTASK_INCREMENT_TICK( xTickCount );
    if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )    {
        /* Increment the RTOS tick, switching the delayed and overflowed        delayed lists if it wraps to 0. */
        ++xTickCount;

            }
    else    {
        ++uxPendedTicks;

        /* The tick hook gets called at regular intervals, even if the        scheduler is locked. */
        #if ( configUSE_TICK_HOOK == 1 )        {
            vApplicationTickHook();        }
        #endif    }

    #if ( configUSE_PREEMPTION == 1 )    {
        if( xYieldPending != pdFALSE )        {
            xSwitchRequired = pdTRUE;        }
        else        {
            mtCOVERAGE_TEST_MARKER();        }
    }    #endif /* configUSE_PREEMPTION */

    return xSwitchRequired;}
红色代码相当于  在 关闭调度器的 时间中的  滴答 代码每次都要执行,那就是 PENDSV还是被执行了,这就不是没有起到 挂起所有任务的目的了吗?   挂起所有任务,不就是需要再挂起器件 不能执行 PENDSV中断吗?





楼主我又看了下源码 和别人的分析 做了一个总结 不知道 这样是否正确;

最终分析结论:======================================================================


首先是:  vTaskSuspendAll   执行将 uxSchedulerSuspended 加1 ,然后 在ISR中调用消息队列信号量,事件等等发送 可能导致高优先级任务唤醒的 系统API,这些函数中会有  xTaskRemoveFromEventList这个函数,他 执行时 会根据  
uxSchedulerSuspended 是否为0 来决定 是吧被 唤醒的 高优先级任务 放在 就绪队列 ReadyList,还是  挂起就绪队列 xPendingReadyList ,如果调度器没有被关闭就是放在就绪队列,这也是滴答定时器或者PENDSV调度时搜索的就绪表,如果调度器被关闭了,那么被唤醒的高优先级任务就会被放在 挂起就绪队列中PendingReadyList 中,  相当于就是在 调度器被关闭期间,由ISR中调用的API被唤醒的任务 都被 记录在一张挂起就绪表中,  
然后在执行到 xTaskResumeAll时,
/* Move any readied tasks from the pending list into the
                appropriate ready list. */
                while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE )
                {
                    pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) );
                    ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
                    ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
                    prvAddTaskToReadyList( pxTCB );


                    /* If the moved task has a priority higher than the current
                    task then a yield must be performed. */
                    if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
                    {
                        xYieldPending = pdTRUE;//指示可以调度,任务已经被移到  就绪表中了 从  挂起就绪表;
                    }
                    else
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }


之前放在 挂起就绪表中的任务就被 全部转移到了  就绪表 中,就可以被正常调度了;  所以就算在调度器被关闭器件 PENDSV被执行了,也没有任何关系,反正是不会把当前任务 切换出去的;









所以在ISR中使用 系统API时,不用强制  执行调度,传入一个NULL即可,xTaskRemoveFromEventList会自动的设置  xYieldPending = pdTRUE,让系统滴答执行任务调度;   
强制调度 也不会出错 ,但是效果和 系统滴答一样,做无用功;
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107031
QQ
发表于 2016-8-17 10:31:02 | 显示全部楼层
我第一次看FreeRTOS的源码还是3年前的事情了,这个我就不花时间再去看源码跟楼主交流了,现在就uCOS的印象还深点
uCOS的调度锁就是设置设计一个变量标志即可,中断里面发消息的话,退出中断的时候,也会判断这个变量标志,如果开了调度器锁就不切换了。
FreeRTOS应该大同小异。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 01:12 , Processed in 0.147005 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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