【嵌入式】UCOSiii学习笔记

1. 为什么需要RTOS

一般情况下,单片机程序都是一个超级大循环,如下所示:

int main(void)
{
    Board_Init();   //板级初始化
    while (1) {
        Key_Scan(); // 按键扫描
        Sensor_Read();  // 传感器读取
        Uart_Process(); //串口处理
        Led_Update();   // led灯状态更新
    }
}

优点很明确:简单,功能路径明确,但是缺点也很明显,当某个功能占用时间较长时,可能导致其他功能不能及时响应,比如Uart_Process中串口数据处理耗时2较长,而系统出现异常需要更新Led灯Led_Update时就可能导致未能及时给出告警提示导致系统出现问题。

假如使用中断 + 标志位(前后台架构-大循环为后台、中断为前台)可以提升时间响应速度,但是会引入多个状态机、共享标志等。

所以此时RTOS(Real Time OS)出世了,它将功能拆分成若干任务(Task),由其内核管理任务状态和CPU使用权。进行任务调度的我们一般称为调度器。其实归根结底,在单片机上某一时刻还是只运行一个任务,但通过任务切换的方式就形成了并发,给人一种多任务同时执行的感觉。

2. RTOS能帮你做什么

RTOS引入了多任务的概念后,需要提供任务相关管理等功能,才能帮我们实现多任务并发执行。所以其最主要提供的功能如下:

  • 任务管理:创建、删除、挂起、恢复
  • 调度:根据任务优先级和状态选择任务
  • 时间:系统节拍、延时、超时、软件定时器等
  • 通信:消息队列、信号量、互斥量、事件标志等
  • 内存与诊断:固定内存分区、栈使用量、任务状态统计等

总结下来RTOS的特点如下:

  1. 分而治之:实现功能划分为多个任务
  2. 延时函数:不会空等待,会让出CPU的使用权给其他任务,即任务调度
  3. 抢占式:高优先级任务抢占低优先级任务
  4. 任务堆栈:每个任务都有自己的栈空间,用于保存局部变量以及任务的上下文信息

其实对于学过Linux开发的而言,RTOS任务可以理解为轻量线程,只不过RTOS任务一般没有Linux用户态/内核态进程模型和完整虚拟内存隔离;RTOS API 的阻塞、优先级和中断上下文规则必须重新学习。pthread_mutex 和 OSMutex 思路相近,却不代表使用约束完全一样。

3. UCOSiii

3.1 简介

UCOSiii时一个可裁剪、可剥夺的多任务系统,没有任务数目限制(只要RAM够大),是UCOS的第三代内核操作系统。

3.2 任务调度

任务调度就是使用一定的调度算法来决定当前需要执行的任务。

UCOSiii一共支持两种任务调度方式:

  • 抢占式调度:主要根据任务优先级进行调度,在创建任务时可以给每个任务分配优先级,优先级高的任务可以抢占优先级低的任务(优先级数字越小优先级越高)
  • 时间片调度:主要针对具有相同优先级的任务,当有多个任务具有相同优先级时,调度器根据用户设置的时间片来轮流运行这些任务。(注:时间片大小取决于滴答定时器中断频率,一般貌似为1ms,每个任务都可以自定义自身的时间片大小,如果任务运行中被打断或阻塞,则没用完的时间片不会再被使用)

3.3 任务状态

UCOSiii中任务有以下5种状态:

  1. 运行态:正在执行的任务
  2. 就绪态:完成创建可以执行,但还未执行的任务
  3. 挂起态:如果一个任务因为延时或者等待外部事件被挂起,则这个任务就处于挂起状态
  4. 休眠态:任务已经在CPU的内存中(被删除了),但是还没有交给UCOSiii内核管理
  5. 中断态:当处于运行态的任务被中断打断,CPU会去执行中断服务函数,则运行态的任务会被切换到中断态,直到中断处理完成,再切回继续运行

img

总结一下:

  1. 被创建的任务,初始状态均为就绪态
  2. 被删除的任务变成休眠态
  3. 仅就绪态和中断态可以转变为运行态
  4. 其他状态任务想运行,则必须先转变为就绪态

3.4 UCOSiii任务管理列表

UCOSiii使用三大类列表来跟踪任务状态:

  1. 就绪列表:准备运行的任务放在就绪列表:OSRdyList[x],其中x代表任务优先级数值,一般为32,优先级为0~31
  2. Tick列表:正在等待延时超时或挂起对象超时的任务,放在OSTickList
  3. 挂起列表:当任务等待信号量、事件时,任务将放置在PendList

注:空闲任务优先级最低,一直处于就绪态,不可阻塞

4. UCOSiii系统API函数

4.1 任务创建与删除

4.1.1 创建任务 OSTaskCreate()

当任务创建好后,就会立马处于就绪状态

4.1.2 删除任务OSTaskDel()

删除任务并不会删除任务的代码和释放任务栈,仅代表该任务和任务栈不再由内核管理。

(当代入得参数为NULL,则代表删除任务自身)

4.1.3 任务创建流程

  1. 定义函数入口参数(任务堆栈、任务优先级、任务控制块等)
  2. 调用创建任务API函数
  3. 实现任务函数功能

注意:

  1. 在调用UCOSiii的函数之前必须先初始化UCOSiii,调用函数OSInit()实现
  2. 任务创建完之后是不会直接启动的,需要开启任务调度器后才能启动任务,调用一次OSStart()即可
  3. 不可删除空闲任务
  4. 临界区保护,保护那些不想被打断的程序段。关闭UCOSiii所管理的中断,中断无法打断,滴答中断和PendSV中断无法进行,所以不能实现任务调度

4.2 任务的挂起和恢复

4.2.1 挂起任务函数OSTaskSuspend()

将任务从就绪列表中暂时移除,不再参与运行

4.2.2 恢复被挂起函数OSTaskResume()

把任务从新插入到就绪列表

注意:

  1. 函数 OSTaskSuspend()与函数 OSTaskResume()必须成对出现
  2. 任务挂起和恢复函数都不支持中断中调用
  3. 不能挂起空闲任务
  4. 挂起任务类似暂停,可恢复; 删除任务,无法恢复,只能重新创建

4.3 中断管理

中断本质就是让CPU打断正常程序的运行,转而紧急处理的事件(任务/程序)

中断执行流程:

  1. 中断请求:外设产生中断请求(GPIO、定时器等)
  2. 响应中断:CPU停止执行当前程序,转而去执行中断处理程序(ISR)
  3. 退出中断:执行完毕,返回被打断的程序处,继续往下执行

4.4 中断优先级分组设置

ARM Cortex-M使用了8位寄存器来配置中断的优先级,中断优先级配置范围在0~255。

STM32只用了中断优先级配置寄存器的高4位[7:4],提供了最大16级的中断优先级

  • 抢占优先级:抢占优先级高的中断可以打断正在执行但优先级低的中断
  • 子优先级:当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的先执行

5种优先级分组分配方式:

  • NVIC_PriorityGroup_0:0bit 用于抢占优先级,4bit 用于子优先级

  • NVIC_PriorityGroup_1:1bit 用于抢占优先级 ,3bit 用于子优先级

  • NVIC_PriorityGroup_2:2bit 用于抢占优先级 ,2bit 用于子优先级

  • NVIC_PriorityGroup_3:3bit 用于抢占优先级 ,1bit 用于子优先级

  • NVIC_PriorityGroup_4:4bit 用于抢占优先级 ,0bit 用于子优先级

    (建议将所有优先级位指定为抢占优先级位,方便UCOSIII管理)

中断相关寄存器:

  • 三个系统中断优先级配置寄存器:SHPR1、SHPR2、SHPR3

通过SHPR3将PendSV设置最低优先级,保证系统任务切换不会阻塞系统其他中断响应,SysTick设置为UCOSiii所管理的最高优先级,保证延时的精确性

  • 三个中断屏蔽寄存器:PRIMASK、FAULTMASK、BASEPRI

在UCOSiii中,中断屏蔽寄存器主要用到了BASEPRI和PRIMASK。

MASEPRI:屏蔽优先级低于某一个阈值的中断,比如BASEPRI设置为0x40,代表重点优先级在4~15内的均被屏蔽,0~3的中断优先级正常执行

PRIMASK:1个位的寄存器,当它置为1是,表示关掉所有可屏蔽的异常,只剩下NMI和硬fault可以响应。当它置为0是,表示没有关闭中断。当需要关闭大部分中断时则使用PRIMASK这个寄存器。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
error: Content is protected !!内容保护!!