Freertos系列(一)Freertos的基础知识

任务特性

任务调度器:其可决定哪个任务先运行,那个任务后运行。

在使用 RTOS 的时候一个实时应用可以作为一个独立的任务。每个任务都有自己的运行环境,不依赖于系统中其他的任务或者 RTOS 调度器。任何一个时间点只能有一个任务运行,具体运行哪个任务是由 RTOS 调度器来决定的,RTOS 调度器因此就会重复的开启、关闭每个任务。任务不需要了解 RTOS 调度器的具体行为,RTOS 调度器的职责是确保当一个任务开始执行的时候其上下文环境(寄存器值,堆栈内容等)和任务上一次退出的时候相同。为了做到这一点,每个任务都必须有个堆栈,当任务切换的时候将上下文环境保存在堆栈中,这样当任务再次执行的时候就可以从堆栈中取出上下文环境,任务恢复运行。

  1. 简单
  2. 没有使用限制
  3. 支持抢占
  4. 支持优先级
  5. 每个任务都拥有堆栈导致了ran使用量增大
  6. 如果使用抢占优先级的话必须仔细的考虑重入的问题

任务的状态

  1. 运行态

当一个任务正在运行时,那么就说这个任务处于运行态,处于运行态的任务就是当前正在使用处理器的任务。如果使用的是单核处理器的话那么不管在任何时刻永远都只有一个任务处于运行态。

  1. 就绪态

处于就绪态的任务是那些已经准备就绪(这些任务没有被阻塞或者挂起),可以运行的任务,但是处于就绪态的任务还没有运行,因为有一个同优先级或者更高优先级的任务正在运行

  1. 阻塞态

如果一个任务当前正在等待某个外部事件的话就说它处于阻塞态,比如说如果某个任务调用了函数 vTaskDelay()的话就会进入阻塞态,直到延时周期完成。任务在等待队列、信号量、事件组、通知或互斥信号量的时候也会进入阻塞态。任务进入阻塞态会有一个超时时间,当超过这个超时时间任务就会退出阻塞态,即使所等待的事件还没有来临

  1. 挂起态

像阻塞态一样,任务进入挂起态以后也不能被调度器调用进入运行态,但是进入挂起态的任务没有超时时间。任务进入和退出挂起态通过调用函数 vTaskSuspend()和 xTaskResume()。

suspend [səˈspend]
v. 悬; 挂; 吊; 暂停; 中止; 使暂停发挥作用(或使用等); 延缓; 暂缓; 推迟;
resume [rɪˈzjuːm]
v. 重新开始; (中断后)继续; 恢复席位 / 地位 / 职位;

任务优先级

数字越大,优先级越高(不能超过32)
每 个 任 务 都 可 以 分 配 一 个 从 0~(configMAX_PRIORITIES-1) 的 优先 级

任务的实现

void vATaskFunction(void *pvParameters) 
{
    
    
for( ; ; ) 
{
    
    
	--任务应用程序-- 
	vTaskDelay(); (4)
}
/*不能从任务函数中返回或者退出,从任务函数中返回或退出的话
就会调用configASSERT(),前提是你定义了 configASSERT()。
如果一定要从任务函数中退出的话那一定要调用函数 vTaskDelete(NULL)
来删除此任务。*/
	vTaskDelete(NULL);  
}

(1)、任务函数本质也是函数,所以肯定有任务名什么的,不过这里我们要注意:任务函数的返回类型一定要为 void 类型,也就是无返回值,而且任务的参数也是 void 指针类型的!任务函数名可以根据实际情况定义。
(2)、循环里面就是真正的任务代码了,此任务具体要干的活就在这里实现!
(3)FreeRTOS 的延时函数,此处不一定要用延时函数,其他只要能让 FreeRTOS 发生任务
切换的 API 函数都可以,比如请求信号量、队列等,甚至直接调用任务调度器。只不过最常用的就是 FreeRTOS 的延时函数。
(4)、任务函数一般不允许跳出循环,如果一定要跳出循环的话在跳出循环以后一定要调用函数 vTaskDelete(NULL)删除此任务!FreeRTOS 的任务函数和 UCOS 的任务函数模式基本相同的,不止 FreeRTOS,其他 RTOS的任务函数基本也是这种方式的。

任务控制块

概念:描述任务属性的数据结构称为任务控制块,为TCB_t

任务堆栈

任务堆栈的作用:

  1. 任务处于运行状态
    当任务在运行时,一般都会调用各式各样的函数,而函数的局部变量,参数,返回值是存在于函数栈帧里的,每个函数都拥有独立的栈帧,各个栈帧使用的空间就是任务堆栈的空间。所以任务堆栈的作用是用于保存函数在运行/调用过程中的参数/局部变量。

  2. 任务处于切换
    当运行的任务被切换时,需要保护现场(CPU中寄存器的值),以便于下次恢复数据。所以任务堆栈的作用是用于保存CPU中寄存器的值。任务(低优先级的)在运行过程中,随时可能被切换,所以CPU中寄存器的值入栈的栈位置是不确定的,这取决于当前任务的执行情况。

  3. 堆栈溢出
    若堆栈的空间设置太大,会浪费内存资源。而设置得太小,则会出现堆栈溢出,同时,应避免使用递归调用函数,函数中局部变量的分配空间不能太大。

猜你喜欢

转载自blog.csdn.net/qq_45699195/article/details/113091566
今日推荐