• FreeRTOS系列第13篇---FreeRTOS内核控制


          内核控制的一些功能须要移植层提供,为了方便移植。这些API函数用宏来实现,比方上下文切换、进入和退出临界区、禁止和使能可屏蔽中断。内核控制函数还包含启动和停止调度器、挂起和恢复调度器以及用于低功耗模式的调整系统节拍函数。

    1.强制上下文切换宏

          taskYIELD:用于强制上下文切换的宏。

    在中断服务程序中的等价版本号为portYIELD_FROM_ISR。这也是个宏,事实上现取决于移植层。

          用于上下文切换的实际代码由移植层提供。对于Cortex-M3硬件。这个宏会引起PendSV中断。

    2.进入临界区宏

          taskENTER_CRITICAL用于进入临界区的宏。在临界区中不会发生上下文切换。

         进入临界区的实际代码由移植层提供,对于Cortex-M3硬件,先禁止全部RTOS可屏蔽中断,这能够通过向basepri 寄存器写入configMAX_SYSCALL_INTERRUPT_PRIORITY来实现。basepri寄存器被设置成某个值后,全部优先级号大于等于此值的中断都被禁止。但若被设置为0。则不关闭不论什么中断。0为默认值。然后临界区嵌套计数器增1。

    3.退出临界区宏

          taskEXIT_CRITICAL:用于退出临界区的宏。

          退出临界区的实际代码有移植层提供。对于Cortex-M3硬件。先将临界区嵌套计数器减1。假设临界区计数器为零,则使能全部RTOS可屏蔽中断。这能够通过向basepri 寄存器写入0来实现。

    4.禁止可屏蔽中断宏

          taskDISABLE_INTERRUPTS:禁止全部RTOS可屏蔽中断。

    在调用宏taskENTER_CRITICAL进入临界区时,也会间接调用该宏禁止全部RTOS可屏蔽中断。

    5.使能可屏蔽中断宏

          taskENABLE_INTERRUPTS:使能全部RTOS可屏蔽中断。在调用宏taskEXIT_CRITICAL退出临界区时,也会间接调用该宏使能全部RTOS可屏蔽中断。

    6.启动调度器

    6.1函数描写叙述

          void vTaskStartScheduler( void );

          启动RTOS调度器。之后RTOS内核控制哪个任务运行以及何时运行。

          当调用vTaskStartScheduler()后,空暇任务被自己主动创建。假设configUSE_TIMERS被设置为1,定时器后台任务也会被创建。

          假设vTaskStartScheduler()成功运行,则该函数不会返回,直到有任务调用了vTaskEndScheduler()。假设由于RAM不足而无法创建空暇任务,该函数也可能运行失败。并会立马返回调用处。

    7.停止调度器

    7.1函数描写叙述

          void vTaskEndScheduler( void );

          仅用于x86硬件架构中。

          停止RTOS内核系统节拍时钟。全部创建的任务自己主动删除并停止多任务调度。

    8.挂起调度器

    8.1函数描写叙述

          void vTaskSuspendAll( void );

          挂起调度器。但不禁止中断。当调度器挂起时,不会进行上下文切换。

    调度器挂起后。正在运行的任务会一直继续运行,内核不再调度(意味着当前任务不会被切换出去),直到该任务调用了xTaskResumeAll ()函数。

          内核调度器挂起期间,那些能够引起上下文切换的API函数(如vTaskDelayUntil()、xQueueSend()等)决不可使用。

    9.恢复被挂起的调度器

    9.1函数描写叙述

          BaseType_t xTaskResumeAll( void );

          恢复因调用vTaskSuspendAll()函数而挂起的实时内核调度器。xTaskResumeAll()仅恢复调度器,它不会恢复那些被vTaskSuspend()函数挂起的任务。

    9.2返回值

          返回pdTRUE 表示恢复调度器引起了一次上下文切换,否则,返回pdFALSE。

    9.3使用方法举例

     voidvTask1( void * pvParameters )
     {
         for( ;; )
         {
             /* 任务代码写在这里 */
     
             /* ... */
     
             /* 有些时候。某个任务希望能够连续长时间的运行,但这时不能使用taskENTER_CRITICAL ()/taskEXIT_CRITICAL ()的方法,这样会屏蔽掉中断,引起中断丢失。包含系统节拍时钟。

    能够使用vTaskSuspendAll ()停止RTOS内核调度:*/ xTaskSuspendAll (); /* 运行操作代码放在这里。

    这样不用进入临界区就能够连续长时间运行了。在这期间。中断仍然会得到响应,RTOS内核系统节拍时钟也会继续保持运作 */ /* ... */ /* 操作结束。又一次启动RTOS内核 。我们想强制进行一次上下文切换。可是假设恢复调度器的时候已经运行了上下文切换。再运行一次是没有意义的。因此会进行一次推断。

    */ if( !xTaskResumeAll () ) { taskYIELD (); } } }

    10.调整系统节拍

    10.1函数描写叙述

          void vTaskStepTick( TickType_txTicksToJump );

          假设RTOS使能tickless空暇功能,每当仅仅有空暇任务被运行时,系统节拍时钟中断将会停止,微控制器进入低功耗模式。

    当微控制器退出低功耗后。系统节拍计数器必须被调整,将进入低功耗的时间弥补上。

          假设FreeRTOS移植文件里定义了宏portSUPPRESS_TICKS_AND_SLEEP()实体,则函数vTaskStepTick用于在这个宏portSUPPRESS_TICKS_AND_SLEEP()实体内部调整系统节拍计数器。函数vTaskStepTick是一个全局函数,所以也能够在宏portSUPPRESS_TICKS_AND_SLEEP()实体中重写该函数。

          在文件FreeRTOSConfig.h中,宏configUSE_TICKLESS_IDLE必须设置为1。此函数才有效。

    10.2參数描写叙述

    • xTickToJump:时间值,单位是系统节拍周期,表示微处理器进入低功耗的时间,函数依据这个值来调整系统节拍计数器的值。

    10.3使用方法举例

    /* 首先定义宏portSUPPRESS_TICKS_AND_SLEEP()。宏參数指定要进入低功耗(睡眠)的时间,单位是系统节拍周期。*/
    #defineportSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime )
     
    /* 定义被宏portSUPPRESS_TICKS_AND_SLEEP()调用的函数 */
    void vApplicationSleep(TickType_t xExpectedIdleTime )
    {
        unsigned long ulLowPowerTimeBeforeSleep,ulLowPowerTimeAfterSleep;
     
        /* 从时钟源获取当前时间,当微控制器进入低功耗的时候,这个时钟源必须在运行 */
        ulLowPowerTimeBeforeSleep =ulGetExternalTime();
     
        /*停止系统节拍时钟中断。*/
        prvStopTickInterruptTimer();
     
        /* 配置一个中断,当指定的睡眠时间达到后,将处理器从低功耗中唤醒。这个中断源必须在微控制器进入低功耗时也能够工作。*/
        vSetWakeTimeInterrupt( xExpectedIdleTime );
     
        /*进入低功耗 */
        prvSleep();
     
        /* 确定微控制器进入低功耗模式持续的真正时间。由于其他中断也可能使得微处理器退出低功耗模式。

    注意:在调用宏portSUPPRESS_TICKS_AND_SLEEP()之前。调度器应该被挂起,portSUPPRESS_TICKS_AND_SLEEP()返回后,再将调度器恢复。因此。这个函数未完毕前。不会运行其他任务。

    */ ulLowPowerTimeAfterSleep =ulGetExternalTime(); /*调整内核系统节拍计数器。*/ vTaskStepTick( ulLowPowerTimeAfterSleep –ulLowPowerTimeBeforeSleep ); /*又一次启动系统节拍时钟中断。*/ prvStartTickInterruptTimer(); }



  • 相关阅读:
    两种常用的启动和关闭MySQL服务
    磁盘分区(20G升50G)
    Google的一些功能和软件
    Google辅助类软件
    Google协作平台
    Google邮箱:Gmail国际顶级邮箱
    Google表单
    Google幻灯片
    在VC/MFC中嵌入Google地图——图文并茂
    与走在创业路上的学子交流——记网维“海大快点”创业团队
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7008021.html
Copyright © 2020-2023  润新知