RTOS官方文档学习
任务与协程
区别
一个程序可以只有任务、只有协程、二者都有,但不可以通过队列/信号量互相传递数据
任务特点
-
任务之间可以互相独立
-
每个任务分配自己的堆栈,提高了RAM使用率
-
操作简单、按优先级抢占式执行
-
抢占容易导致重入(执行任务时被其他线程或进程调用了)
协程特点
-
一般用于小型,RAM有限制的处理器上
-
所有协程共用一个堆栈
-
通过一组宏实现的
-
减少了重入问题,但是和任务混用总抢不过人家
任务状态
运行、就绪、阻塞、挂起
任务优先级
-
0--configMAX_PRIORITIES - 1,最大值定义在FreeRTOSConfig.h中
-
设置的越小越好,某些特殊情况不得超过32
-
空闲任务优先级为0
-
默认情况,相同优先级按时间切片轮流运行
任务调度
单核调度
-
抢占式调度,即使在同一时间片,出现了一个高优先级任务,也会打断当前的低优先级任务。
-
时间片指两个tick中断之间的时间,相同优先级的任务,一人一个时间片依次执行。
-
如果一个高优先级任务永远不阻塞、不挂起,低优先级任务永远也不会执行,因此推荐创建事件驱动的任务,等待事件的时候阻塞掉它,收到事件再解除阻塞
-
高优先级任务处于“阻塞”状态时, 低优先级任务会运行。
-
FreeRTOSConfig中:
configUSE_PREEMPTION=0
关闭抢占,只有阻塞/挂起/运行的任务调用 taskYIELD()/ISR才会切换下文的任务
configUSE_TIME_SLICING=0
关闭时间片,相同优先级的任务不会在tick间隔后切换。
AMP调度
非对称多核处理,每个核心独立运行字节的实例,不需要有相同架构
SMP调度
对称多核处理,一个程序跨多个处理器调度
- 单核移植到SMP
- configRUN_MULTIPLE_PRIORITIES = 0 ,可以同时运行优先级相同的多个任务
- configUSE_CORE_AFFINITY = 1,通过vTaskCoreAffinitySet() 方法定义某个任务可以在哪个核运行
任务实现
定义任务
void vMyTask(void *pvParameters)
{
for(;;){
Task coding here...
//任务代码写在死循环里,非必要不退出,退出一定要delete
}
vTaskDelete(NULL);
}
typedef void (*TaskFunction_t)(void*);
- 这句话是什么意思呢,就是TaskFunction_t是一个指向函数的指针,这类函数具有void * 类型的形参,返回值类型是void
- 事件型驱动代码框架,WaitForEvent是消息队列接收/事件等待等
if(WaitForEvent(事件,等待超时时间))
{Tasking coding here...}
else
{报错、处理错误等}
- 通过宏定义实现一个任务定义
portTASK_FUNCTION_PROTO( vMyTask, pvParameters );