zoukankan      html  css  js  c++  java
  • FreeRTOS 在Tricore上的三种任务切换方式

    FreeRTOS 在Tricore上的三种任务切换方式如下:

    (1)任务中调用任务切换

      切换函数:portYIELD()/portYIELD_WITHIN_API()/taskYEILD()

      处理器资源:Trap_class6_TIN0

      触发方式:_syscall(0)

      处理函数:void prvTrapYield( int iTrapIdentification )

      使用场合:例如 ①任务调用vTaskDelay()时,其内部会执行portYIELD_WITHIN_API()进行任务切换;②调用xQueueSend()函数时,会检查是否使某一阻塞态任务解阻塞,若是,则调用portYIELD_WITHIN_API()进行任务切换

    (2)中断中调用任务切换

      切换函数:portYIELD_FROM_ISR()/taskYEILD_FROM_ISR()

      处理器资源:GPSRx0

      触发方式:GPSRx0.B.SETR = 1或INT_SRB0.B.TRIG0 = 1 

      处理函数:static void prvInterruptYield( int iId )

      使用场合:在中断中调用进行任务切换,例如在中断中向队列中写数据xQueueSendFromISR( xQueue, &xHigherPriorityTaskWoken );,然后使用portYIELD_FROM_ISR( xHigherPriorityTaskWoken )进行任务切换。

    (3)systick中断中的任务切换

      切换函数:在StmISR中进行

      处理器资源:SysTimerx

      触发方式:SysTimerx  COMP0计数器溢出触发中断

      处理函数:static void prvSystemTickHandler( int iArg )

      使用场合:每次进入中断,都会检查是否有延时任务超时,若有,则进行一次任务切换

    三种方式的区别在于:跳转到执行任务切换的处理函数的方式,但三者的上下文保存与切换代码完全一致。① SysTick中断方式周期性地检查并进行任务切换,该中断优先级被设置为2,防止其抢占正在执行的中断处理而引发错误(若SysTick中断通过抢占其他中断而进入,那么在进行上下文切换时,会把被其打断的中断处理函数的上下文CSA地址保存到最近一次运行的任务TCB.TopOfStack中,而将PCX指向新任务的CSA地址,因此SysTick中断退出时会将新任务的上下文恢复到寄存器中从而执行新任务,而不是返回到被抢占的中断中继续执行,于是整个系统都会乱掉。进入SysTick中断后的CSA情况为:PCX->Breaked Int's CSA -> 最近一个任务的CSA);② 任务中调用的任务切换的方式为立即进行任务切换(陷阱的优先级高于中断);③ 而中断中调用的任务切换方式为触发一个可挂起的软件中断,其优先级被设置为1,原因和SysTick中断一样。实际上,ARM-CM3中使用PendSV进行任务切换也是基于这个原因(CM3中的FreeRTOS任务切换方式有两种:SysTick(Trap)和PendSV(SW Int),其实SysTick也是用了PendSV,Pend是指可被悬起的意思)。三种方式对应的任务切换处理函数在port.c中定义,代码如下:

    (1)

    void prvTrapYield( int iTrapIdentification )
    {
        uint32_t *pxUpperCSA = NULL;
        uint32_t xUpperCSA = 0UL;
        extern volatile uint32_t *pxCurrentTCB;
    
        switch( iTrapIdentification )
        {
            case portSYSCALL_TASK_YIELD:
    _disable(); _dsync(); xUpperCSA = _mfcr( CPU_PCXI ); pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA ); *pxCurrentTCB = pxUpperCSA[ 0 ]; vTaskSwitchContext(); pxUpperCSA[ 0 ] = *pxCurrentTCB; SRC_GPSR00.B.SRR = 0; _isync(); break; default: /* Unimplemented trap called. */ configASSERT( ( ( volatile void * ) NULL ) ); break; } }

    (2)

    static void prvInterruptYield( int iId )
    {
        uint32_t *pxUpperCSA = NULL;
        uint32_t xUpperCSA = 0UL;
        extern volatile uint32_t *pxCurrentTCB;
    
        /* Just to remove compiler warnings. */
        ( void ) iId;
    
        _disable();
        _dsync();
        xUpperCSA = _mfcr( CPU_PCXI );
        pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA );
        *pxCurrentTCB = pxUpperCSA[ 0 ];
        vTaskSwitchContext();
        pxUpperCSA[ 0 ] = *pxCurrentTCB;
        SRC_GPSR00.B.SRR = 0;
        _isync();
    }

    (3)

    static void prvSystemTickHandler( int iArg )
    {
        uint32_t ulSavedInterruptMask;
        uint32_t *pxUpperCSA = NULL;
        uint32_t xUpperCSA = 0UL;
        extern volatile uint32_t *pxCurrentTCB;
        int32_t lYieldRequired;
    
        /* Clear the interrupt source. */
        IfxStm_clearCompareFlag( &MODULE_STM0, IfxStm_Comparator_0 );
    
        /* Reload the Compare Match register for X ticks into the future.
        IfxStm_increaseCompare( &MODULE_STM0, IfxStm_Comparator_0, ulCompareMatchValue );
    
        /* Kernel API calls require Critical Sections. */
        ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
        {
            /* Increment the Tick. */
            lYieldRequired = xTaskIncrementTick();
        }
        portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
    
        if( lYieldRequired != pdFALSE )
        {
            _disable();
            _dsync();
            xUpperCSA = _mfcr( CPU_PCXI );
            pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA );
            *pxCurrentTCB = pxUpperCSA[ 0 ];
            vTaskSwitchContext();
            pxUpperCSA[ 0 ] = *pxCurrentTCB;
            SRC_GPSR00.B.SRR = 0;
            _isync();
        }
    }
  • 相关阅读:
    Failed to load config "react-app" to extend from.
    An unexpected error occurred: "expected workspace package to exist for "@babel/core"".
    写一个 LRU 缓存函数(#146)
    TERSUS笔记303-06末页
    TERSUS笔记302-08每页条数逻辑
    TERSUS笔记301-显示列表处理+序号+01共几条取值+08每页条数下拉菜单值设置+02共页数计算取值
    TERSUS笔记300-增加
    TERSUS笔记118-多表增删改查完整操作
    Java多线程之二(Synchronized)
    HashMap在JDK1.7中可能出现的并发问题
  • 原文地址:https://www.cnblogs.com/uestcliming666/p/12669365.html
Copyright © 2011-2022 走看看