目录

1. 前后台系统结构

1.1 概述

1.2 前后台系统存在的问题

1.2.1 实时性不能保证

1.2.2 CPU利用率不高

1.2.3 编程思维不自然

2. RTOS原理及功能简介

2.1 概述

2.2 RTOS与前后台结构的比较

2.3 工作原理简介

2.3.1 提供任务概念

2.3.2 提供任务调度机制

2.3.3 提供资源管理与通信组件

2.4 总结

3. 调试工具使用

4. 芯片内核简介

4.1 为什么要了解硬件特性

4.2 内核概述

4.3 内核特性介绍

4.3.1 工作模式及特权级别

4.3.2 寄存器组

4.3.3 Cortex-M3预定义的存储器映射

4.3.4 堆栈

4.3.5 系统异常

4.3.6 指令系统

5. 内核编程实践

5.1 需求说明

5.2 代码说明

5.2.1 寄存器操作

5.2.2 triggerSV函数说明

5.2.3 PendSV_Handler函数说明


1. 前后台系统结构

1.1 概述

说明1:前后台结构实现为主循环 + ISR,我们需要自己实现主循环并处理ISR与主循环之间的交互

说明2:如果中断要处理的事情很简短,可以在ISR中完成;如果时间要处理的事情较多,则返回后台程序处理

1.2 前后台系统存在的问题

1.2.1 实时性不能保证

实时性不能保证,事件可能无法得到及时处理

示例中在处理flag1事件时延时2秒,会影响对flag2事件的处理

1.2.2 CPU利用率不高

存在CPU空转的情况,CPU利用率不高

说明:上述CPU空转就是因为当前要操作的资源尚未准备好,但是前后台系统又无法去处理其他事务

1.2.3 编程思维不自然

强迫人按照机器的顺序工作方式思考编码。当执行的任务越多,代码结构越复杂,编码难度越大。

不能并行处理,只能顺序处理

2. RTOS原理及功能简介

关键:为什么RTOS能解决前后台系统存在的问题

2.1 概述

RTOS是一种通用的任务管理框架,用于控制任务的运行和任务之间的交互,保证事件得到实时处理。

RTOS的三要素:实时性 + 操作系统 + 嵌入式

2.2 RTOS与前后台结构的比较

① RTOS相当于实现了后台的主循环,并能够处理ISR与主循环的交互

② 使得用户可以只考虑任务的设计

③ RTOS还提供了各种组件用于实现任务间交互及其他控制管理功能(e.g. 存储管理)

2.3 工作原理简介

2.3.1 提供任务概念

提供多个执行流,虽然实际只有一颗CPU,但通过"虚拟化",每个Task好像独占CPU

此处"虚拟"的CPU并非完全的虚拟,"独占"也并不是真正独占,而只是任务认为自己独占

任务认为自己独占的理解:task可以认为自己独占一颗CPU,所以可以实现为一个死循环。而CPU上实际的执行流,会由于操作系统的控制,在不同task之间进行切换。这样既简化了task的设计,也充分利用了CPU

这就引入了一个问题,即"操作系统的控制"本身在实现上也是一段代码,那么这段代码在什么时机运行呢 ? 其实就是在中断或者task主动交出CPU控制权的时候(e.g. task调用可能导致阻塞的函数)

2.3.2 提供任务调度机制

通过RTOS控制任务的运行时机,事件处理的实时性得到有效保证

说明1:一般中断ISR只会进行简短的预处理,而将耗时的操作交给task来执行。RTOS可以确保在ISR执行完成后,立即调度ISR的后续task执行(当然,这需要task优先级的保障)

说明2:ISR后续task在运行时,如果需要等待资源,RTOS会调度其他task执行

说明3:高优先级task可以抢占低优先级task

2.3.3 提供资源管理与通信组件

提供一些组件用于简化任务对资源的访问,事件的处理,以及任务之间的通信,有效降低任务之间的代码耦合

2.4 总结

下图体现了RTOS相对于前后台系统的优势

3. 调试工具使用

4. 芯片内核简介

4.1 为什么要了解硬件特性

RTOS作为系统软件,运行时必然与硬件相关,e.g.

① 任务切换时寄存器的保存

② 异常处理

③ 内核时钟节拍来自硬件定时器

4.2 内核概述

Cortex-M3内核是ARM公司开发的CPU内核。完整的MCU芯片集成了Cortex-M3内核及其他组件

4.3 内核特性介绍

4.3.1 工作模式及特权级别

① 前台程序(中断服务程序)只能在特权级运行

② 后台程序可以根据需要切换权限级别

说明:特权级的不同通常体现在栈指针的使用上,用户级使用PSP;特权级使用MSP

4.3.2 寄存器组

① 只有R13为Banked register,代码中均为R13,运行时根据当前运行的特权级确定使用的是MSP还是PSP

② 之所以区分低组和高组寄存器,是因为大部分16-bit Thumb-2指令只能访问低组寄存器(本质原因:16-bit指令编码长度限制)

注意:Cortex-M3有三个程序状态寄存器,分别是APSR(应用PSR)/ IPSR(中断PSR)/ EPSR(执行PSR)

上述三个程序状态寄存器其实是一个三合一寄存器,即可以单独访问,也可以组合访问

4.3.3 Cortex-M3预定义的存储器映射

说明:Cortex-M3此处的地址空间映射由处理器内核设置,而非芯片厂商设置,这点有利于简化系统移植

4.3.4 堆栈

Cortex-M3使用满递减栈,采用双堆栈机制

4.3.5 系统异常

4.3.5.1 系统异常列表

需要注意如下3种异常,

① 复位

② PendSV

③ SysTick

4.3.5.2 进入异常

说明1:此处要区分哪些寄存器由硬件保存,哪些寄存器由软件保存,由软件保存的寄存器需要软件自己恢复

特别注意:由硬件保存的寄存器也是保存在当前栈中

说明2:注意异常向量表的前2个成员,分别是MSP初始值和复位异常入口地址

注意1:Cortex-M3中需要保存LR,是因为LR只有一个,并非banked register(在Cortex-A系列中,LR为banked register)

而且保存后LR寄存器还要在异常返回时起特殊作用,这点和Cortex-A系列非常不同。Cortex-A系列异常处理的思路是通过banked LR保存返回地址,然后用LR恢复PC

注意2:进入异常时,LR寄存器值在入栈后,会被设置为特殊的EXC_RETURN值,这个值在异常退出时影响返回动作

经过仿真,Cortex-M3在首次进入PendSV异常时,LR值为0xFFFFFFF9,即退出异常时会返回线程模式,并使用MSP

4.3.5.3 退出异常

说明:将进入异常时设置的特殊LR(即EXC_RETURN值)写入PC,就会进入异常返回流程

在Cortex M3中,只有bit 3 & bit 2是可变动的,各种组合情况如下,

bit 3

bit 2

含义

EXC_RETURN数值

0

0

返回handler模式,因为handler模式只能运行在特权级,所以只能使用MSP

0xFFFFFFF1

0

1

错误组合,handler模式无法使用PSP

1

0

返回thread模式,且使用MSP,即仍在特权级运行

0xFFFFFFF9

1

1

返回thread模式,且使用PSP,即在用户级运行

0xFFFFFFFD

4.3.5.4 复位异常的响应

说明:复位异常发生后,CPU将0x00000000和0x00000004中的内容(即异常向量表的前2项)分别加载MSP和PC,即可开始执行

右边的图画错了,赋值给PC的应该是0x00000101,即启动引导代码的位置;赋值给MSP的应该是0x20008000,即MSP初始值

4.3.5.5 PendSV异常的响应

作用:在PendSV中执行RTOS上下文切换(即不同任务间的切换)

工作原理:配置为最低优先级,上下文切换的请求将自动延迟到其他的ISR都完成后才处理,并且可以被其他异常 / 中断抢占。

说明:如果在SysTick中断中发现需要进行任务切换,则只是标记PendSV异常,SytTick中断处理结束时仍然返回之前的ISR。最后当没有比PendSV优先级更高的异常/中断时,才进行任务切换

注意:这一流程的实现需要依赖Cortex-M3提供的NVIC硬件支持,这种可抢占的异常也体现了RTOS的实时特性

4.3.6 指令系统

Cortex-M3使用Thumb-2指令集,长度可为16位或32位。指令可以携带后缀,如有条件执行。

下面仅介绍后续汇编代码中会使用到的指令。

5. 内核编程实践

5.1 需求说明

触发PendSV异常,在异常处理函数中,保存R4 ~ R11寄存器到缓冲区,再恢复R4 ~ R11寄存器,以模拟任务切换时的寄存器保存与恢复

5.2 代码说明

5.2.1 寄存器操作

#define NVIC_INT_CTRL   (0xE000ED04) //中断控制状态寄存器
#define NVIC_PENDSVSET  (0x10000000) //设置挂起pendSV位,将bit[28]置1
#define NVIC_SYSPRI2    (0xE000ED22) //系统处理器优先级寄存器,按字节访问
#define NVIC_PENDSV_PRI (0x000000FF) //设置pendSV优先级为最低

说明1:中断控制状态寄存器

设置该寄存器的bit 28即可将pendSV中断挂起,当没有更高优先级的中断需要处理时,将进入pendSV中断的ISR运行

说明2:系统处理器优先级寄存器

pendSV中断为第14号中断,由于可以按字节访问NVIC寄存器,所以将0xE000ED22设置为0xFF即可将pendSV中断设置为最低优先级

5.2.2 triggerSV函数说明

void triggerPendSV(void)
{// 设置pendSV为最低优先级MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI;// 设置挂起pendSV位MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET;
}

triggerPendSV函数的作用就是先将pendSV中断的优先级设为最低,然后将该中断挂起,用于模拟请求任务切换的场景

5.2.3 PendSV_Handler函数说明

__asm void PendSV_Handler(void)
{// 汇编中使用C变量IMPORT blockPtr// 加载缓冲区地址LDR    R0, =blockPtrLDR    R0, [R0]LDR    R0, [R0]// 保存寄存器STMDB  R0!, {R4-R11}// 更新缓冲区指针LDR    R1, =blockPtrLDR    R1, [R1]STR    R0, [R1]// 修改部分寄存器,用于测试ADD    R4, R4, #1ADD    R5, R5, #1// 恢复寄存器LDMIA  R0!, {R4-R11}// 更新缓冲区指针STR    R0, [R1]// 异常返回BX     LR
}

说明1:PendSV_Handler函数名

该函数为pendSV异常的ISR,之所以使用该函数名,是因为在Keil初始化环境中将pendSV的异常向量设置为PendSV_Handler

说明2:缓冲区指针的维护

先来说明一下缓冲区的定义方式,

typedef struct _BlockType_t {unsigned long *stackPtr;
} BlockType_t;BlockType_t block;
BlockType_t *blockPtr = NULL;unsigned long stackBuffer[1024]; // 缓冲区int main(void)
{block.stackPtr = stackBuffer + 1024;blockPtr = █....
}

如此便可理解加载缓冲区地址的操作了,

LDR    R0, =blockPtr // 获取blockPtr变量的地址(blockPtr标号的地址)// 变量名就是符号地址
LDR    R0, [R0]      // 获取block的地址(也就是blockPtr指针变量的值)
LDR    R0, [R0]      // 获取stackPtr指针变量的值(也就是缓冲区的地址)

之所以可以通过第2次{ LDR R0, [R0] }可以获取stackPtr指针变量的值,是因为stackPtr是BlockType_t结构的第1个成员,而C语言要求结构体变量的首地址与其第1个成员的首地址相同

说明3:EXC_RETURN值的设置

响应pendSV异常时,LR的值被设置为0xFFFFFFF9,即异常返回时进入线程模式且使用MSP(线程模式 + 特权级)

这是因为系统启动时默认为线程模式 + MSP,而中断返回是默认返回中断触发前的运行状态

RTOS原理与实现01:RTOS基础知识相关推荐

  1. 图像识别的原理和应用:从基础知识到实际案例

    图像识别的原理和应用:从基础知识到实际案例 图像识别是一种利用计算机对图像进行处理.分析和理解,以识别各种不同模式的目标和对象的技术.图像识别是人工智能和计算机视觉的一个重要分支,它在各个领域都有广泛 ...

  2. 计算机系统组成及工作原理PPT,第二章 计算机基础知识 2.1 计算机系统的组成与工作原理 2.2 数制转换及运算 2.3 数据在计算机中的表示....

    Presentation on theme: "第二章 计算机基础知识 2.1 计算机系统的组成与工作原理 2.2 数制转换及运算 2.3 数据在计算机中的表示."- Presen ...

  3. 【计算机基础】01计算机基础知识

    第1章 计算机基础知识 1.1 概述 1.1.1 计算机的发展史    1942年2月,美国宾夕法尼亚大学研制出世界上第一台电子多用途数字计算机ENIAC. 5个发展时代: 1. 第一代计算机 第一代 ...

  4. 海南大学计算机原理,海南大学微机原理课件 第一章 计算机基础知识

    第一章 计算机基础知识 数 制 §1.1 一.计算机使用的数制及其相互转换 十进制(D).二进制(B).八进制(O)和十六进制(H). 数制中用少量数码按次序排列成数位,并按由低到高的进位方式进行计 ...

  5. 01.软件测试基础知识整合

    软件测试基础 前言 一.什么是软件测试 二.软件测试的目的 三.软件测试的基本流程 四.测试分类 五.测试用例 1.什么是测试用例 2.测试用例的重要性 3.测试用例的设计方法 4.测试点分析 5.如 ...

  6. 【笔记】网易微专业-Web安全工程师-01.WEB基础知识

    课程概述: 本课是基础中的基础,通俗易懂的讲解了Web的本质和Web开发的基础知识.对于Web小白,建议从头开始抓紧学习:对于已经有一定Web基础知识的同学,建议快速的过一遍,夯实基础. 课程大纲: ...

  7. 电子计算机的基本结构基于存储程序,01计算机基础知识题(50道)

    有答案的 计算机基础知识测试题(带答案) 第一章 计算机基础知识习题 三.填空题 1.到目前为止,电子计算机的基本结构基于存储程序思想,这个思想最早是由提出的. 2.微型机硬件的最小配置包括主机.键盘 ...

  8. 密码算法学习笔记01:基础知识-公钥密码和混合密码系统

    来自书籍<图解密码技术 第三版.pdf> 密码算法基础知识-公钥密码和混合密码系统 一.公钥密码 公钥密码--用公钥加密,用私钥解密. 公钥密码无需向接收者配送用于解密的钥匙,只需向发送者 ...

  9. RTOS的基本概念与线程基础知识

    1 RTOS概念及线程的引入 1.1 RTOS的概念 用人来类比单片机程序和RTOS: 妈妈要一边给小孩喂饭,一边加班跟同事交流,怎么办? 对于单线条的人,不能分心,不能同时做事,她只能这样做: 给小 ...

最新文章

  1. R语言使用colnames函数改变dataframe列名称实战
  2. spring整合mybatis(入门级简单教程1)--在spring中配置c3p0,并成功测试
  3. 关于E1的一些扫盲资料
  4. VTK:网格之TableBasedClipDataSetWithPolyData
  5. 企业网站6个常见的优化漏洞
  6. JDK线程池CompletionService的使用
  7. Python版常见的排序算法
  8. 还以为iPhone安全?多款iOS应用被曝“偷偷”发送用户数据
  9. Java开源项目Hibernate包作用详解
  10. 地方税务局行政效能管理(行政审批)整体解决方案
  11. IIS中启用ASP并连接Access数据库的解决办法
  12. opencv-python的人脸识别系统
  13. 打造自己的 PTM!新词挖掘+预训练
  14. ftp连接21端口出现的问题的解决方案
  15. 服务器属于三大系统,服务器三大操作系统
  16. outlook邮箱邮件大小限制_Office Outlook 2010、2013附件大小超过了允许的范围限制三种解决方法图解...
  17. domyPP:回归经典表格管理,以可协作表格管理项目
  18. 入手评测 联想小新Pro 16怎么样?
  19. php置顶功能代码,jquery实现页面置顶功能代码
  20. 微信小程序:伪input组件的样式

热门文章

  1. Python3入门与进阶_课堂笔记
  2. W25Q128数据手册翻译(3)
  3. 使用Amazon CDK部署基于Amazon Fargate的高可用、易扩展的Airflow集群
  4. 探索PinYin4j.jar将汉字转换为拼音的基本用法
  5. 与“奋斗者”号同行 华为这个智慧办公新物种不一般
  6. ueditor百度编辑器destoon的word图片转存功能
  7. Ceph cache tier 中 flush 和 evict 机制源码分析
  8. c#的winForm启动自动隐藏界面包含任务栏图标
  9. Photonbsp;shopnbsp;cs5nbsp;快捷键
  10. 轻松几步破解 XMind 8 Update 7