目录
七· 什么是优先级反转,以及优先级继承是如何减小(但不是消除)其影响的。
一·为什么,以及在什么时候有必要进行资源管理与控制。
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.使用守护任务
七· 什么是优先级反转,以及优先级继承是如何减小(但不是消除)其影响的。
1.优先级反转:
(1)低优先级任务在被高优先级任务抢占之前获取到互斥信号量。
(2)高优先级任务尝试获取互斥锁但是不能获取,因为它已经被低优先级任务持有,高优先级任务进入阻塞态,等待互斥锁可以用。
(3)低优先级任务组织高优先级任务执行,因此继承了高优先级任务的优先级,此时不能被中优先级任务抢占,因此低优先级和中优先级任务优先级反转存在的时间被最小化。当低优先级任务给出互斥量信号,低优先级任务的优先级返回本来的优先级。
(4)高优先级任务返回互斥锁时,导致高优先级任务作为互斥锁持有者退出阻塞态,当高优先级任务已经完成互斥锁时给出互斥信号量,这中优先级任务仅在高优先级任务返回到阻塞态时执行,因此中优先级任务不会阻碍高优先级任务。
2.优先级继承
持有互斥量的低优先级任务会继承等待互斥量的高优先级任务,等到低优先级任务给出互斥量,低优先级任务恢复本来优先级。
八.参考文献
FreeRTOS实时内核使用指南-中文
九.技术交流
公众号:橘入式技术交流
哔哩哔哩:橘-爽歪歪
总结
FreeRTOS提供了资源的管理技巧以及一些API函数,利用互斥量避免多个任务对共同资源无逻辑无规则使用,但是这种技巧也是存在弊端,不能一劳永逸,还是需要自己对项目有清楚的规划,任务之间不要相互干扰,做到高聚合低冗余的一个情况。