FreeRTOS实时操作系统的内核控制示例解析

 更新时间:2022年6月1日 13:41  点击:862 作者:zhzht19861011

前言

内核控制的一些功能需要移植层提供,为了方便移植,这些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();}/* 首先定义宏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();
}

以上就是FreeRTOS实时操作系统的内核控制示例解析的详细内容,更多关于FreeRTOS实时操作系统内核控制的资料请关注猪先飞其它相关文章!

原文出处:https://freertos.blog.csdn.net/article/details/50553099

[!--infotagslink--]

相关文章

  • python小白练习题之条件控制与循环控制

    Python 中的条件控制和循环语句都非常简单,也非常容易理解,与其他编程语言类似,下面这篇文章主要给大家介绍了关于python小白练习题之条件控制与循环控制的相关资料,需要的朋友可以参考下...2021-10-09
  • apache配置黑名单和白名单及账户权限控制

    本文我们将分享apache配置黑名单和白名单,apache层的账户权限控制,以及apache黑名单白名单过滤功能,apache rewrite规则实现白名单。 apache配置黑名单和白名单的两...2016-09-14
  • 浅谈基于SpringBoot实现一个简单的权限控制注解

    这篇文章主要介绍了基于SpringBoot实现一个简单的权限控制注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-01
  • Lua流程控制语句if else的使用示例

    今天小编就为大家分享一篇关于Lua流程控制语句if else的使用示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...2020-06-30
  • Python : turtle色彩控制实例详解

    今天小编就为大家分享一篇Python : turtle色彩控制实例详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-22
  • 新手初学Java流程控制

    这篇文章主要介绍了JAVA流程控制语句的的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下,希望可以帮到你...2021-07-07
  • Springcloud实现服务多版本控制的示例代码

    这篇文章主要介绍了Springcloud实现服务多版本控制的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-05-15
  • ASP.NET对HTML页面元素进行权限控制(一)

    界面每个元素的权限也是需要控制的。比如一个查询用户的界面里面有查询用户按钮,添加用户按钮,删除用户按钮,不同的角色我们得分配不同的权限...2021-09-22
  • ASP.NET Core WebApi版本控制的实现

    这篇文章主要介绍了ASP.NET Core WebApi版本控制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • 版本控制CVS转到分布式Git并和Github上Fork的项目合并

    本文我们来学习常用的代码版本控制C/S系统软件CVS转到分布式版本控制系统Git上,并和Github上Fork的项目合并。 在捣鼓我的 Gregarius 时,发现无法读取 HTTPS 的 RSS...2016-11-25
  • 两个php日期控制类

    由于工作需要我找了二个时间日期控制,这个不用js只要php实现的,因为要带参考查询所以操作了操作,有需要的朋友可以参考一下哦,我自己用的是第二个,所以第二个己作了修改。...2016-11-25
  • ASP.NET对HTML页面元素进行权限控制(二)

    分三步实现:标出界面所要分配权限的元素、扫描界面获取所要分配权限的元素信息、存入数据库中,感兴趣的朋友可以了解下...2021-09-22
  • 解析鸿蒙轻内核静态内存的使用

    摘要:静态内存实质上是一个静态数组,静态内存池内的块大小在初始化时设定,初始化后块大小不可变更。静态内存池由一个控制块和若干相同大小的内存块构成。控制块位于内存池头部,用于内存块管理。内存块的申请和释放以块大小为粒度...2021-06-22
  • 分布式文档存储数据库之MongoDB访问控制的操作方法

    这篇文章主要介绍了分布式文档存储数据库之MongoDB访问控制的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-12-08
  • 解析Linux内核与设备树的编译和烧写

    在内核源码中,存在大量对板级细节信息描述的代码。开源文档中对设备树的描述是,一种描述硬件资源的数据结构,它通过bootloader将硬件资源传给内核,使得内核和硬件资源描述相对独立...2021-06-26
  • PHP会话控制实例代码与详细分析

    这篇文章介绍了php中会话控制的问题,结合实例形式分析了php针对cookie与session的相关操作技巧,有兴趣的同学可以参考一下 本文实例讲述了PHP会话控制。分享给大家...2016-12-31
  • mysql的MVCC多版本并发控制的实现

    这篇文章主要介绍了mysql的MVCC多版本并发控制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-12
  • Linux 系统优化的一些建议(内核优化)

    这篇文章主要介绍了Linux 系统优化的一些建议,帮助大家更好的使用Linux,感兴趣的朋友可以了解下...2020-08-28
  • Bootstrap每天必学之日期控制

    Bootstrap每天必学之日期控制,对Bootstrap日期控制感兴趣的小伙伴们可以参考一下...2016-03-09
  • Go语言中的流程控制结构和函数详解

    这篇文章主要介绍了Go语言中的流程控制结构和函数详解,本文详细讲解了if、goto、for、switch等控制语句,同时对函数相关知识做了讲解,需要的朋友可以参考下...2020-05-01