1.FreeRTOS内核支持抢占式调度和时间片轮转调度,默认情况下时间片轮转调度是使能了的,抢占式调度需要用户在FreeRTOSConfig.h中自己使能(configUSE_PREEMPTION)
2.抢占式调度用于不同优先级的任务之间,时间片轮转调度用于同优先级任务之间
3.有且只有以下5种情况会触发任务切换:
1.有比当前运行任务更高优先级的任务进入了就绪态
2.当前运行任务调用了阻塞函数(如vTaskDelay、等待任务通知、等待信号量等)使自己进入了阻塞态,此时若有处于就绪态的用户任务就执行该就绪态任务,没有的话就执行系统的空闲任务。
3.当前任务运行时间超过了系统心跳时间且有处于就绪态的用户任务
4.任务调用任务切换函数(如xYieldPending)来主动触发任务调度
5.任务自己删除或挂起了自己
注意,这里中断并不会触发任务调度,系统可管理中断的中断响应是由系统决定的,系统不可管理中断的响应只会打断当前任务的执行,并不会触发调度,因为中断函数中不可以调用系统函数所以其更不可能调用系统函数来主动进行任务切换;如果是由于主动执行期间导致高优先级的任务进入就绪态从而导致中断执行完之后就进行了任务切换那也不属于是中断导致的任务切换,而是属于上诉的情况1。
4.如果实际应用中有不同优先级的任务或者某个任务的执行时间会有可能大于一个系统心跳间隔的,那就会出现任务被打断的情况,此时就有可能出现函数的重入问题(任务A在执行函数1的时候被任务B打断,然后任务B执行时也调用了函数1),此时就要注意分析哪些函数是有可能被重入的,那么这些函数里面:
1.不得使用全局变量
2.不能使用内存申请和释放功能,或者在使用前禁止任务调度(进入临界区)
3.不可调用任何不可重入函数
4.不得和硬件交互,或者在交互前禁止任务调度(进入临界区)
5.不得使用静态的数据结构
会发现,此时事情会变得复杂得多,所以在实时性要求不是很高的应用中任务尽量都设置成同一个优先级的且保证任务执行时间不会大于系统心跳间隔
5.时间片轮转机制,一个时间片即一个系统心跳,对于有些系统(如uCos)来说是可以设置每个任务执行多少个时间片的,但是对于FreeRTOS来说每个任务固定只能执行一个时间片