logo资料库

《从0到1教你写uCOS-III》.pdf

第1页 / 共126页
第2页 / 共126页
第3页 / 共126页
第4页 / 共126页
第5页 / 共126页
第6页 / 共126页
第7页 / 共126页
第8页 / 共126页
资料共126页,剩余部分请下载后查看
第1章 前言
1.1 如何学习本书
1.2 本书的参考资料
1.3 本书的编写风格
1.4 本书的配套硬件
1.5 本书的技术论坛
第2章 如何学习RTOS
2.1 为什么要学习RTOS
2.2 如何学习RTOS
2.3 如何选择RTOS
第3章 新建工程—软件仿真
3.1 新建本地工程文件夹
3.2 使用KEIL新建工程
3.2.1 New Progect
3.2.2 Select Device For Target
3.2.3 Manage Run-Time Environment
3.3 在KEIL工程里面新建文件组
3.4 在KEIL工程里面添加文件
3.4.1 编写main函数
3.5 调试配置
3.5.1 设置软件仿真
3.5.2 修改时钟大小
3.5.3 添加头文件路径
第4章 裸机系统与多任务系统
4.1 裸机系统
4.1.1 轮询系统
4.1.2 前后台系统
4.2 多任务系统
第5章 任务的定义与任务切换的实现
5.1 本章目标
5.2 什么是任务
5.3 创建任务
5.3.1 定义任务堆栈
5.3.2 定义任务函数
5.3.3 定义任务控制块TCB
5.3.4 实现任务创建函数
5.4 OS系统初始化
5.5 启动系统
5.6 任务切换
5.7 main函数
5.8 实验现象
第6章 任务时间片运行
6.1 SysTick简介
6.2 初始化SysTick
6.3 编写SysTick中断服务函数
6.4 main函数
6.5 实验想像
第7章 阻塞延时与空闲任务
7.1 实现空闲任务
7.1.1 定义空闲任务堆栈
7.1.2 定义空闲任务TCB
7.1.3 定义空闲任务函数
7.1.4 空闲任务初始化
7.2 实现阻塞延时
7.3 main函数
7.4 实验现象
第8章 时间戳
8.1 时间戳简介
8.2 时间戳的实现
8.3 时间戳代码讲解
8.3.1 CPU_Init()函数
8.3.2 CPU_TS_Init()函数
8.3.3 CPU_TS_TmrInit()函数
8.3.4 BSP_CPU_ClkFreq()函数
8.3.5 CPU_TS_TmrFreqSet()函数
8.3.6 CPU_TS_TmrRd()函数
8.3.7 OS_TS_GET()函数
8.4 main函数
8.5 实验想象
第9章 临界段
9.1 临界段简介
9.2 关中断
9.2.1 测量关中断时间
9.3 锁调度器
9.3.1 测量锁调度器时间
9.4 main函数
9.5 实验现象
第10章 就绪列表
10.1 优先级表
10.1.1 优先级表函数讲解
1. OS_PrioInit()函数
2. OS_PrioInsert()函数
3. OS_PrioRemove()函数
4. OS_PrioGetHighest()函数
10.2 就绪列表
10.2.1 就绪列表函数讲解
1. OS_RdyListInit()函数
2. OS_RdyListInsertHead()函数
3. OS_RdyListInsertTail()函数
4. OS_RdyListInsert()函数
5. OS_RdyListMoveHeadToTail()函数
6. OS_RdyListRemove()函数
10.3 main函数
10.4 实验现象
第11章 支持多优先级
11.1 定义优先级相关全局变量
11.2 修改OSInit()函数
11.3 修改任务控制块TCB
11.4 修改OSTaskCreate()函数
11.5 修改OS_IdleTaskInit()函数
11.6 修改OSStart()函数
11.7 修改PendSV_Handler()函数
11.8 修改OSTimeDly()函数
11.9 修改OSSched()函数
11.10 修改OSTimeTick()函数
11.11 main函数
11.12 实验现象
第12章 实现时基列表
12.1 实现时基列表
12.1.1 定义时基列表变量
12.1.2 修改任务控制块TCB
12.1.3 实现时基列表相关函数
1. OS_TickListInit()函数
2. OS_TickListInsert()函数
3. OS_TickListRemove()函数
4. OS_TickListUpdate()函数
12.2 修改OSTimeDly()函数
12.3 修改OSTimeTick()函数
12.4 main 函数
12.5 实验现象
第13章 实现时间片
13.1 实现时间片
13.1.1 修改任务TCB
13.1.2 实现时间片调度函数
1. OS_SchedRoundRobin()函数
13.2 修改OSTimeTick()函数
13.3 修改OSTaskCreate()函数
13.4 修改OS_IdleTaskInit()函数
13.5 main函数
13.6 实验现象
第14章 任务的挂起和恢复
14.1 实现任务的挂起和恢复
14.1.1 定义任务的状态
14.1.2 修改任务控制块TCB
14.1.3 编写任务挂起和恢复函数
1. OSTaskSuspend()函数
2. OSTaskResume()函数
14.2 main函数
14.3 实验现象
第15章 任务的删除
15.1 实现任务删除
15.1.1 编写任务删除函数
1. OSTaskDel()函数
15.2 main函数
15.3 实验现象
第16章 IPC通信
附录 uC/OS的编程风格
文件头
文件包含
标识符命名法
缩写及助记符
注释
定义语句
数据类型
局部变量
函数原型
函数声明
缩进格式
语句和表达式
结构体和联合体
【野火®】 从 0 到 1 教你写 uCOS-III 第1章 前言 1.1 如何学习本书 本书与市面上的任何一本 uC/OS-III 相关的书都不一样,它们要么是翻译官方的参考手 册,要么是讲如何使用 uC/OS-III,要么是讲 uC/OS-III 的源码,而本书是教你怎么从 0 开 始把 uC/OS-III 写出来,既讲了源码实现,也讲了 API 如何使用。当你拿到本书开始学习 的时候你一定会惊讶,原来 RTOS 的学习并没有那么复杂,反而是那么的有趣,原来自己 也可以写 OS,成就感立马爆棚。 全书内容循序渐进,不断迭代,前一章都是后一章的基础,必须从头开始阅读,不能 进行跳跃式的阅读。在学习的时候务必做到两点:一是不能一味地看书,要把代码和书本 结合起来学习,一边看书,一边调试代码。看书倒是很简单,那如何调试代码?即单步执 行每一条程序,看看程序的执行流程和执行的效果与自己大脑所想是不是一样;二是在每 学完一章之后,必须将配套的例程重写一遍(切记不要复制,哪怕是一个分号,但可以 抄),做到举一反三,确保真正理解。在自己写的时候肯定会错漏百出,这个时候要珍惜 这些错误,好好调试,这是你提高编程能力的最好的机会。记住,程序不是写出来的,而 是调试出来的。 1.2 本书的参考资料 1、 uC/OS-III 官方源代码 2、 uCOS-III 中文翻译 (电子版) 3、 嵌入式操作系统 uCOS-II(第二版) (电子版) 4、 嵌入式实时操作系统μCOS-II 原理及应用 任哲编著 (电子版) 5、 CM3 权威指南 CnR2 (电子版) 6、 STM32F10xxx Cortex-M3 programming manual (电子版) 1.3 本书的编写风格 本书以 uC/OS-III 官方源码为蓝本,抽丝剥茧,不断迭代,教你怎么从 0 开始把 uC/OS-III 写出来。书中涉及到的数据类型,变量名称、函数名称,文件名称,文件存放的 位置都完全按照 uC/OS-III 官方的方式来实现,当你学完这本书之后可以无缝地切换到原版 的 uC/OS-III 的使用。要注意的是,在实现的过程中,某些函数我会去掉一些形参和一些冗 余的代码,只保留核心的功能,但这并不会影响我们学习。 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 1 / 126
【野火®】 从 0 到 1 教你写 uCOS-III 1.4 本书的配套硬件 本书支持野火 STM32 开发板全套系列,具体型号见表格 1-1,具体图片见图 1-1、图 1-2、图 1-3、图 1-4 和图 1-5。学习的时候如果配套这些硬件平台做实验,学习必会达到事 半功倍的效果,可以省去中间硬件不一样时移植遇到的各种问题。 表格 1-1 野火 STM32 开发板型号汇总 型号 - MINI 指南者 霸道 霸天虎 挑战者 区别 内核 Cortex-M3 Cortex-M3 Cortex-M3 Cortex-M4 Cortex-M4 引脚 64 100 144 144 176 RAM 48KB 64KB 64KB 192KB 256KB ROM 256KB 512KB 512KB 1MB 1MB 图 1-1 野火【MINI】STM32F103RCT6 开发板 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 2 / 126
【野火®】 从 0 到 1 教你写 uCOS-III 图 1-2 野火【指南者】STM32F103VET6 开发板 图 1-3 野火【霸道】STM32F103ZET6 开发板 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 3 / 126
【野火®】 从 0 到 1 教你写 uCOS-III 图 1-4 野火【霸天虎】STM32F407ZGT6 开发板 图 1-5 野火【挑战者】STM32F429IGT6 开发板 1.5 本书的技术论坛 如果在学习过程中遇到问题,可以到野火电子论坛:www.firebbs.cn 发帖交流 ,开源 共享,共同进步。 鉴于水平有限,本书难免有纰漏,热心的读者也可把勘误发到论坛好让我们改进做得 更好,祝您学习愉快,uC/OS-III 的世界,野火与您同行。 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 4 / 126
【野火®】 从 0 到 1 教你写 uCOS-III 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 5 / 126
【野火®】 从 0 到 1 教你写 uCOS-III 第2章 如何学习 RTOS 2.1 为什么要学习 RTOS 当我们进入嵌入式这个领域的时候,往往首先接触的都是单片机编程,单片机编程又 首选 51 单片机来入门。这里面说的单片机编程通常都是指裸机编程,即不加入任何 RTOS (Real Time Operation System 实时操作系统)的程序。常用的 RTOS 有国外的 FreeRTOS、 ucOS、RTX 和国内的 Huawei LiteOS、和 RT-Thread 等,其中尤以开源且免费的 FreeRTOS 的市场占有率最高,历史悠久的 ucos 屈居第二。 在裸机系统中,所有的程序基本都是自己写的,所有的操作都是在一个无限的大循环 里面实现。现实生活中的很多中小型的电子产品用的都是裸机系统,而且也能够满足需求。 但是为什么还要学习 RTOS 编程,偏偏还要整个操作系统进来。一是项目需要,随着产品 要实现的功能越来越多,单纯的裸机系统已经不能够完美地解决问题,反而会使编程变得 更加复杂,如果想降低编程的难度,我们可以考虑引入 RTOS 实现多任务管理,这是使用 RTOS 的最大优势。二是学习的需要,必须学习更高级的东西,实现更好的职业规划,为 将来走向人生巅峰迎娶白富美做准备,而不是一味的在裸机编程上面死磕。作为一个合格 的嵌入式软件工程师,学习是永远不能停止的事,时刻都在为将来准备。书到用时方恨少, 我希望机会来临时你不要有这种感觉。 为了帮大家理清 RTOS 编程的套路,下面我们简单的分析下这两种编程方式的区别, 这个区别我称它为学习 RTOS 的命门,只要打通这个任督二脉,以后的 RTOS 学习可以说 是易如反掌。在讲解这两种编程方法的区别的时候,我们主要讲方法论,不会涉及到具体 的代码编程,主要还是通过伪代码来讲解。 2.2 如何学习 RTOS 裸机编程和 RTOS 编程的风格有些不一样,而且有很多人说 RTOS 的学习很难,这就 导致学习的人一听到 RTOS 编程就在心理面忌惮三分,结果就是出师未捷身先死。 那么到底如何学习一个 RTOS?最简单的就是在别人移植好的系统之上,看看 RTOS 里面的 API 使用说明,然后调用这些 API 实现自己想要的功能即可。完全,不用关心底层 的移植,这是最简单快速的入门方法。这种方法各有利弊,如果是做产品,好处是可以快 速的实现功能,将产品推向市场,赢得先机,弊端是当程序出现问题的时候,因对这个 RTOS 不够了解,会导致调试困难,焦头烂额,一筹莫展。如果是学习,那么只会简单的 调用 API,那是不可取的,我们应该深入的学习其中一款 RTOS。 目前市场上现有的 RTOS,它们的内核实现方式都差不多,我们只需要深入学习其中 一款就行。万变不离其宗,以后换到其它型号的 RTOS,使用起来,那自然是得心应手。 那如何深入的学习一款 RTOS?这里有一个最有效也是最难的方法,就是阅读 RTOS 的源 码,深究内核和每个组建的实现方式,这个过程枯燥且痛苦。但为了能够学到 RTOS 的精 华,你不入地狱谁入地狱? 6 / 126 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com
【野火®】 从 0 到 1 教你写 uCOS-III 市面上虽然有一些讲解相关 RTOS 源码的书,如果你基础不够,且先前没有使用过该 款 RTOS,那么源码看起来还是会非常枯燥,且并不能从全局掌握整个 RTOS 的构成和实 现。 现在,我们采用一种全新的方法来教大家学习一款 RTOS,即不是单纯的讲里面的 API 如何使用,也不是单纯的拿里面的源码一句句来讲解。而是,从 0 开始,层层叠加, 不断地完善,教大家怎么把一个 RTOS 写 0 到 1 写出来,让你在每一个阶段都能享受到成 功的喜悦。在这个 RTOS 实现的过程中,只需要你具备 C 语言的基础就行,然后就是跟着 我们这个教程笃定前行,最后定有所成。 这个用来教学的 RTOS,我们不会完全自己写一个,不会再重复的造轮子,而是选取 年龄最大(26 岁)、商业化最成功、安全验证最多的 uC/OS-III 为蓝本,将其抽丝剥茧, 层层叠加,从 0 到 1 写出来。在实现的过程中,数据类型、变量名、函数名称、文件类型 等都完全按照 uC/OS-III 里面的写法,不会自己再重新命名。这样学完我们这个课程之后, 就可以无缝地过度到 uC/OS-III 的使用。 2.3 如何选择 RTOS 选择一个 RTOS 要看下你是学习还是做产品,如果是学习则选择一个年龄最大,商业 化最成功,安全验证最多的来学习,而且是深入学习。那么符合前面这几个标准的只有 ucos,所以,学一个 RTOS,首选 ucos,而且 ucos 的资料是最多的。当然,选择其他的 RTOS 来学习也是可以的。学完之后就是要用了,如果是产品中使用 ucos 就要面临授权的 问 题 , 就 是 要 给 版 权 费 。 一 听 到 要 给 钱 , 大 家 肯 定 是 不 乐 意 了 , 所 以 开 源 免 费 的 FreeRTOS 就受到各个半导体厂商和开发者的青睐。目前,FreeRTOS 是市场占有率最高的 RTOS,非常适合用来做产品。另外,国内的 RT-Thread 也在迅速的崛起,同样是开源免费。 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 7 / 126
【野火®】 从 0 到 1 教你写 uCOS-III 第3章 新建工程—软件仿真 在开始写 RTOS 之前,我们先新建一个工程,Device 选择 Cortex-M3 内核的处理器, 调试方式选择软件仿真,到最后写完整个 RTOS 之后,我们再把 RTOS 移植到野火 STM32 开发板上,到了最后的移植其实已经非常简单,只需要换一下启动文件和添加 bsp 驱动就 行。 3.1 新建本地工程文件夹 在开始新建工程之前,我们先在本地电脑端新建一个文件夹用于存放工程。文件夹名 字我们取为 RTOS,然后再在该文件夹下面新建各个文件夹和文件,有关这些文件夹的包 含关系和作用具体见表格 3-1。 表格 3-1 工程文件夹根目录下的文件夹的作用 文件夹名称 Doc - - 文件夹作用 用 于 存 放 对 整 个 工 程 的 说 明 文 件 , 如 readme.txt。通常情况下,我们都要对整个 工程实现的功能,如何编译,如何使用等 做一个简要的说明。 用于存放新建的工程文件。 - Source 用于存放 uC/OS-III 源码,这里面的代码是 纯软件的,跟硬件无关。 - Ports 用于存放接口文件,即 uC/OS-III 与 CPU 连接的文件,也就是我们通常说的移植文 件。要想 uC/OS-III 在单片机上面跑起来, 这些移植文件必不可少。 用于存放 uC/OS-III 根据 CPU 总结的通用 代码,只跟 CPU 相关。 用于存放一些 C 语言函数库。 用于存放用户程序,如 app.c,main 函数就 放在 app.c 这个文件里面。 - - 引脚 64 100 144 144 176 RAM 48KB 64KB 64KB 192KB 256KB ROM 256KB 512KB 512KB 1MB 1MB Project User - uCOS-III uC-CPU uC-LIB - 区别 内核 Cortex-M3 Cortex-M3 Cortex-M3 Cortex-M4 Cortex-M4 型号 - MINI 指南者 霸道 霸天虎 挑战者 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 8 / 126
分享到:
收藏