FreeRTOS快速使用指南(4) 资源管理

目录

一·为什么,以及在什么时候有必要进行资源管理与控制。

1.为什么进行资源管理与控制

2.什么时候进行资源管理与控制

二· 什么是临界区。

1.使用方法:

2.taskENTER_CRITICAL()分析:

3.taskENTER_CRITICAL()分析:

三· 互斥是什么意思。

四· 挂起调度器有什么意义

1.任务挂起所有

2.任务唤醒所有

五· 如何使用互斥量

1.创建互斥信号量

 2.获取互斥信号量

3.释放互斥信号量

4.如何使用互斥信号量

六· 如何创建与使用守护任务。

1.创建守护函数

2.使用守护任务

七· 什么是优先级反转,以及优先级继承是如何减小(但不是消除)其影响的。

1.优先级反转:

2.优先级继承

八.参考文献

九.技术交流


一·为什么,以及在什么时候有必要进行资源管理与控制。

        1.为什么进行资源管理与控制

                    把资源分好类,便于程序开发有条理性,下一步就是对资源进行合理有逻辑的控制

        2.什么时候进行资源管理与控制

                    在资源数量比较多的情况下、并且不同的任务会对同一或者不同资源进行处理控制

 

二· 什么是临界区。

临界区就是指taskENTER_CRITICAL()taskEXIT_CRITICAL()之间的代码区间,防止被其它任务给中断,但是会被硬件中断打断,即高于 configMAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断打断,但是这些可以打断的临界区的函数不能使用FreeRTOS API函数

1.使用方法:

taskENTER_CRITICAL();//任务进入临界区
。
。
code
。
。
taskEXIT_CRITICAL();//任务离开临界区

2.taskENTER_CRITICAL()分析:

        调用内联函数vPortRaiseBASEPRI(),将basepri设置为最高优先级

static portFORCE_INLINE void vPortRaiseBASEPRI( void )
{
    uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
     __asm
    {
         /* Set BASEPRI to the max syscall priority to effect a critical section. */
         msr basepri, ulNewBASEPRI
         dsb
         isb
    }

}

3.taskENTER_CRITICAL()分析:

        调用内联函数 vPortSetBASEPRI(),将basepri设置为最低优先级

static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
    __asm
    {
       /* Barrier instructions are not used as this function is only used to lower the BASEPRI value. */
         msr basepri, ulBASEPRI
    }
}

注:basepri是一个中断寄存器,该值为n,大于等于n的任务都被屏蔽

        故taskENTER_CRITICAL()与 taskEXIT_CRITICAL()两个函数的意思是在临界去代码前把 configMAX_SYSCALL_INTERRUPT_PRIORITY赋予给basepri,优先级及小于该优先级的任务都被屏蔽,等待临界区内代码执行完再将basepri指设置为0,即不屏蔽任何优先级的任务。

 

三· 互斥是什么意思。

        相互排斥,两个任务或多个任务不运行不会相互干扰

        任务1执行的时候任务2不执行,任务2执行的时候任务1不执行

四· 挂起调度器有什么意义

         可以保护一段代码不被其他任务打断(实现临界区,适用于临界区较长的方案,但是唤醒操作耗时长)

1.任务挂起所有

        void vTaskSuspendAll( void );

2.任务唤醒所有

        portBASE_TYPE xTaskResumeAll( void );

返回值

pdTRUE:某个任务在唤醒函数之前执行被调度然后被挂起了

pdFALSE:其他情况

五· 如何使用互斥量

 

 注意:小心互锁信号造成的任务优先级互锁和优先级反转

1.创建互斥信号量

        xSemaphoreHandle xSemaphoreCreateMutex( void );

返回值

NULL:创建失败(内存不足)

句柄:互斥量创建成功

 2.获取互斥信号量

        xSemaphoreTake( xSemaphore, xBlockTime )

3.释放互斥信号量

        xSemaphoreGive( xSemaphore )

4.如何使用互斥信号量

       (1)创建互斥量

       (2)任务A,获取互斥量,执行任务A功能,释放互斥量

       (3)任务B, 获取互斥量,执行任务B功能,释放互斥量

六· 如何创建与使用守护任务。

1.创建守护函数

  守护任务由内核在每次心跳中断时调用,要挂接一个心跳钩子函数,需要做以下配置:

         (1)设置 FreeRTOSConfig.h 中的常量 configUSE_TICK_HOOK 为 1

         (2)提供钩子函数的具体实现,void vApplicationTickHook( void );

         (3)一般设置钩子函数优先级比较低

2.使用守护任务

        心跳钩子函数在系统心跳中断的上下文上执行,所以必须保证非常短小,适度占用
栈空间,并且不要调用任何名字不带后缀 ”FromISR” FreeRTOS API 函数。

 

七· 什么是优先级反转,以及优先级继承是如何减小(但不是消除)其影响的。

1.优先级反转:

        (1)低优先级任务在被高优先级任务抢占之前获取到互斥信号量。

       (2)高优先级任务尝试获取互斥锁但是不能获取,因为它已经被低优先级任务持有,高优先级任务进入阻塞态,等待互斥锁可以用。

        (3)低优先级任务组织高优先级任务执行,因此继承了高优先级任务的优先级,此时不能被中优先级任务抢占,因此低优先级和中优先级任务优先级反转存在的时间被最小化。当低优先级任务给出互斥量信号,低优先级任务的优先级返回本来的优先级。

        (4)高优先级任务返回互斥锁时,导致高优先级任务作为互斥锁持有者退出阻塞态,当高优先级任务已经完成互斥锁时给出互斥信号量,这中优先级任务仅在高优先级任务返回到阻塞态时执行,因此中优先级任务不会阻碍高优先级任务。

2.优先级继承

        持有互斥量的低优先级任务会继承等待互斥量的高优先级任务,等到低优先级任务给出互斥量,低优先级任务恢复本来优先级。

八.参考文献

FreeRTOS实时内核使用指南-中文

九.技术交流

公众号:橘入式技术交流

哔哩哔哩:橘-爽歪歪

总结

        FreeRTOS提供了资源的管理技巧以及一些API函数,利用互斥量避免多个任务对共同资源无逻辑无规则使用,但是这种技巧也是存在弊端,不能一劳永逸,还是需要自己对项目有清楚的规划,任务之间不要相互干扰,做到高聚合低冗余的一个情况。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值