logo资料库

[野火®]《RT-Thread 内核实现与应用开发实战—基于STM32》.pdf

第1页 / 共363页
第2页 / 共363页
第3页 / 共363页
第4页 / 共363页
第5页 / 共363页
第6页 / 共363页
第7页 / 共363页
第8页 / 共363页
资料共363页,剩余部分请下载后查看
推荐序
第1章 前言
1.1 如何学习本书
1.2 本书的参考资料
1.3 本书的编写风格
1.4 本书的配套硬件
1.5 本书的技术论坛
第2章 如何学习RTOS
2.1 为什么要学习RTOS
2.2 如何学习RTOS
2.3 选择什么RTOS
第3章 初识RT-Thread
3.1 RT-Thread简介
3.1.1 版权
3.1.2 收费问题
3.2 RT-Thread的意义
第一部分:从0到1教你写RT-Thread内核
第4章 新建RT-Thread工程—软件仿真
4.1 新建本地工程文件夹
4.2 使用KEIL新建工程
4.2.1 New Progect
4.2.2 Select Device For Target
4.2.3 Manage Run-Time Environment
4.3 在KEIL工程里面新建文件组
4.4 在KEIL工程里面添加文件
4.4.1 编写main函数
4.5 调试配置
4.5.1 设置软件仿真
4.5.2 修改时钟大小
4.5.3 添加头文件路径
第5章 裸机系统与多线程系统
5.1 裸机系统
5.1.1 轮询系统
5.1.2 前后台系统
5.2 多线程系统
第6章 线程的定义与线程切换的实现
6.1 本章目标
6.2 什么是线程
6.3 创建线程
6.3.1 定义线程栈
6.3.2 定义线程函数
6.3.3 定义线程控制块
6.3.4 实现线程创建函数
1. 实现链表相关函数
定义链表节点数据类型
初始化链表节点
在双向链表表头后面插入一个节点
在双向链表表头前面插入一个节点
从双向链表删除一个节点
2. rt_hw_stack_init()函数
6.4 实现就绪列表
6.4.1 定义就绪列表
6.4.2 将线程插入到就绪列表
6.5 实现调度器
6.5.1 调度器初始化
6.5.2 启动调度器
6.5.3 第一次线程切换
1. rt_hw_context_switch_to() 函数
2. PendSV_Handler()函数
6.5.4 系统调度
1. rt_schedule()函数
2. rt_hw_contex_switch()函数
6.6 main函数
6.7 实验现象
第7章 临界段的保护
7.1 什么是临界段
7.2 Cortex-M内核快速关中断指令
7.3 关中断
7.4 开中断
7.5 临界段代码的应用
7.6 实验现象
第8章 对象容器的实现
8.1 什么是对象
8.1.1 对象枚举定义
8.1.2 对象数据类型定义
8.1.3 在线程控制块中添加对象成员
8.2 什么是容器
8.2.1 容器的定义
8.3 容器的接口实现
8.3.1 获取指定类型的对象信息
8.3.2 对象初始化
8.3.3 调用对象初始化函数
8.4 实验现象
第9章 空闲线程与阻塞延时的实现
9.1 实现空闲线程
9.1.1 定义空闲线程的栈
9.1.2 定义空闲线程的线程控制块
9.1.3 定义空闲线程函数
9.1.4 空闲线程初始化
9.2 实现阻塞延时
9.3 SysTick_Handler中断服务函数
9.3.1 系统时基更新函数
9.4 main函数
9.5 实验现象
第10章 支持多优先级
10.1 就绪列表
10.1.1 线程就绪优先级组
1. 寻找优先级最高的线程
10.1.2 线程优先级表
1. 调度器插入线程
2. 调度器删除线程
10.2 修改代码,支持多优先级
10.2.1 修改线程控制块
10.2.2 修改调度器初始化函数rt_system_scheduler_init()
10.2.3 修改线程初始化函数rt_thread_init()
10.2.4 添加线程启动函数rt_thread_startup()
10.2.5 修改空闲线程初始化函数rt_thread_idle_init()
10.2.6 修改启动系统调度器函数rt_system_scheduler_start()
10.2.7 修改系统调度函数rt_schedule ()
10.2.8 修改阻塞延时函数rt_thread_delay()
10.2.9 修改时基更新函数rt_tick_increase()
10.3 main函数
10.4 实验现象
第11章 定时器的实现
11.1 实现定时器
11.1.1 系统定时器列表
11.1.2 系统定时器列表初始化
11.1.3 定义定时器结构体
11.1.4 在线程控制块中内置定时器
11.1.5 定时器初始化函数
11.1.6 定时器删除函数
11.1.7 定时器停止函数
11.1.8 定时器控制函数
11.1.9 定时器启动函数
1. 插入定时器1(timeout_tick=4)
2. 插入定时器2(timeout_tick=2)
3. 插入定时器3(timeout_tick=3)
11.1.10 定时器扫描函数
11.2 修改代码,支持定时器
11.2.1 修改线程初始化函数
11.2.2 修改线程延时函数
11.2.3 修改系统时基更新函数
11.2.4 修改main.c文件
11.3 实验现象
第12章 支持时间片
12.1 实现时间片
12.1.1 在线程控制块中添加时间片相关成员
12.1.2 修改线程初始化函数
1. 修改空闲线程初始化函数
12.1.3 修改系统时基更新函数
12.2 修改main.c文件
12.3 实验现象
第二部分:RT-Thread 内核应用开发
第13章 移植RT-Thread到STM32
13.1 获取STM32的裸机工程模板
13.2 下载RT-Thread Nano 源码
13.3 安装RT-Thread Package
13.4 往裸机工程添加RT-Thread源码
13.4.1 拷贝RT-Thread Package到裸机工程根目录
13.4.2 拷贝rtconfig.h文件到user文件夹
13.4.3 拷贝board.c文件到user文件夹
13.4.4 RT-Thread文件夹内容简介
1. bsp文件夹简介
2. components文件夹简介
3. include文件夹简介
4. libcpu文件夹简介
5. src文件夹简介
13.4.5 添加RT-Thread源码到工程组文件夹
1. 新建rtt/source和rtt/ports组
2. 指定RT-Thread头文件的路径
13.5 修改rtconfig.h
13.5.1 rtconfig.h文件内容讲解
13.5.2 rtconfig.h文件修改
13.6 修改board.c
13.6.1 board.c文件内容讲解
1. rt_hw_board_init()函数
2. SysTick_Handler()函数
13.6.2 board.c文件修改
13.7 添加core_delay.c和core_delay.h文件
13.8 修改main.c
13.9 下载验证
第14章 创建线程
14.1 硬件初始化
14.2 创建单线程—SRAM静态内存
14.2.1 定义线程函数
14.2.2 定义线程栈
14.2.3 定义线程控制块
14.2.4 初始化线程
14.2.5 启动线程
14.2.6 main.c文件内容全貌
14.3 下载验证
14.4 创建单线程—SRAM动态内存
14.4.1 动态内存空间的堆从哪里来
14.4.2 定义线程函数
14.4.3 定义线程栈
14.4.4 定义线程控制块指针
14.4.5 创建线程
14.4.6 启动线程
14.4.7 main.c文件内容全貌
14.5 下载验证
14.6 创建多线程—SRAM动态内存
14.7 下载验证
第15章 重映射串口到rt_kprintf函数
15.1 rt_kprintf()函数定义
15.2 自定义rt_hw_console_output函数
15.3 测试rt_kprintf函数
15.3.1 硬件初始化
15.3.2 编写rt_kprintf测试代码
15.3.3 下载验证
第16章 RT-Thread的启动流程
16.1 万事俱备,只欠东风
16.2 小心翼翼,十分谨慎
16.3 孰优孰劣
16.4 RT-Thread的启动流程
16.4.1 $Sub$$main函数
16.4.2 rtthread_startup()函数
16.4.3 rt_application_init()函数
16.4.4 $Super$$main()函数
16.4.5 main函数
第17章 线程管理
17.1 线程的基本概念
17.2 线程调度器的基本概念
17.3 线程状态的概念
17.4 线程状态迁移
17.5 常用的线程函数讲解
17.5.1 线程挂起函数rt_thread_suspend()
17.5.2 线程恢复函数rt_thread_resume()
17.6 线程的设计要点
17.7 线程管理实验
17.8 实验现象
第18章 消息队列
18.1 消息队列的基本概念
18.2 消息队列的运作机制
18.3 消息队列的阻塞机制
18.4 消息队列的应用场景
18.5 消息队列控制块
18.6 常用消息队列的函数讲解
18.6.1 消息队列创建函数rt_mq_create()
18.6.2 消息队列删除函数rt_mq_delete()
18.6.3 消息队列发送消息函数rt_mq_send()
18.6.4 消息队列接收消息函数rt_mq_recv()
18.7 消息队列使用注意事项
18.8 消息队列实验
18.9 实验现象
第19章 信号量
19.1 信号量基本概念
19.2 二值信号量的应用场景
19.3 二值信号量的运作机制
19.4 计数型信号量的运作机制
19.5 信号量控制块
19.6 常用信号量函数接口讲解
19.6.1 信号量创建函数rt_sem_create()
19.6.2 信号量删除函数rt_sem_delete()
19.6.1 信号量释放函数rt_sem_release()
19.6.2 信号量获取函数rt_sem_take()
19.7 信号量实验
19.7.1 二值信号量同步实验
19.7.1 计数信号量实验
19.8 实验现象
19.8.1 二值信号量同步实验现象
19.8.1 计数信号量实验现象
第20章 互斥量
20.1 互斥量的基本概念
20.2 互斥量的优先级继承机制
20.3 互斥量的应用场景
20.4 互斥量的运作机制
20.5 互斥量控制块
20.6 信号量函数接口讲解
20.6.1 互斥量创建函数rt_mutex_create()
20.6.2 互斥量删除函数rt_mutex_delete()
20.6.3 互斥量释放函数rt_mutex_release()
20.6.4 互斥量获取函数rt_mutex_take()
20.7 互斥量使用注意事项
20.8 互斥量实验
20.9 实验现象
第21章 事件
21.1 事件的基本概念
21.2 事件的应用场景
21.3 事件的运作机制
21.4 事件控制块
21.5 事件函数接口讲解
21.5.1 事件创建函数rt_event_create()
21.5.2 事件删除函数rt_event_delete()
21.5.3 事件发送函数rt_event_send()
21.5.4 事件接受函数rt_event_recv()
21.6 事件实验
21.7 实验现象
第22章 软件定时器
22.1 软件定时器的基本概念
22.2 软件定时器的应用场景
22.3 软件定时器的精度
22.4 软件定时器的运作机制
22.5 定时器超时函数
22.6 软件定时器的使用
22.6.1 软件定时器的创建函数
22.7 软件定时器实验
22.8 实验现象
第23章 邮箱
23.1 邮箱的基本概念
23.2 邮箱的运作机制
23.3 邮箱的应用场景
23.4 邮箱的应用技巧
23.5 邮箱控制块
23.6 邮箱的函数接口讲解
23.6.1 邮箱创建函数rt_mb_create()
23.6.2 邮箱删除函数rt_mb_delete()
23.6.3 邮箱邮件发送函数rt_mb_send_wait()(阻塞)
23.6.4 邮箱邮件发送函数rt_mb_send ()(非阻塞)
23.6.5 邮箱邮件接收函数rt_mb_recv()
23.7 邮箱的实验
23.8 邮箱的实验现象
第24章 内存管理
24.1 内存管理的基本概念
24.2 内存管理的运作机制
24.2.1 静态内存管理
24.2.2 动态内存管理
1. 小内存管理模块
2. SLAB内存管理模块
24.3 内存管理的应用场景
24.4 静态内存管理的函数接口讲解
24.4.1 静态内存控制块
24.4.2 静态内存创建函数rt_mp_create()
24.4.3 静态内存删除函数rt_mp_delete()
24.4.4 静态内存初始化函数rt_mp_init()
24.4.5 静态内存申请函数rt_mp_alloc()
24.4.6 静态内存释放函数rt_mp_free()
24.5 动态内存管理的函数接口讲解
24.5.1 系统堆内存初始化rt_system_heap_init()
24.5.2 系统堆内存申请函数rt_malloc()
24.5.3 系统堆内存释放函数rt_free()
24.6 内存管理的实验
24.6.1 静态内存管理实验
24.6.1 动态内存管理实验
24.7 内存管理的实验现象
24.7.1 静态内存管理实验现象
24.7.1 静态内存管理实验现象
第25章 中断管理
25.1 异常与中断的基本概念
25.1.1 中断的介绍
25.1.2 和中断相关的名词解释
25.2 中断管理的运作机制
25.3 中断延迟的概念
25.4 中断管理的应用场景
25.5 中断管理讲解
25.6 中断管理的实验
25.7 中断管理的实验现象
第26章 双向链表
26.1 双向链表的基本概念
26.2 双向链表的函数接口讲解
26.2.1 链表初始化函数rt_list_init()
26.2.2 向链表中插入节点
1. 向链表指定节点后面插入节点rt_list_insert_after()
2. 向链表指定节点前面插入节点rt_list_insert_before()
26.2.3 从链表删除节点函数rt_list_remove()
26.3 双向链表的实验
26.4 双向链表的实验现象
联系我们
RT-Thread 内核实现与应用开发实战指南 —基于野火 STM32 全系列(M3/4/7)开发板 推荐序 RT-Thread 从 2006 年走来,已经经过了十多个年头。早年就和野火相识于网络,记得 那个时候野火还没那么火(才开始做开发板),RT-Thread 也还只是国内一个小众的 RTOS。 直至 2018 年年中,野火过来上海才有缘相见,互道年轻 。 在 2017 年底,欣闻野火有著 RT-Thread 书籍的计划,非常欣喜、感谢。这将是 RT- Thread 的首本书籍,在 RT-Thread 的基础生态推广上有着举足轻重的作用!不仅如此,作 为 RT-Thread 的官方合作伙伴,野火也在其全系列的 STM32 开发板上适配了 RT-Thread 例 程并配套了手把手的教程。 野火的这本书籍,第一部分先从 0 到 1 的方式,从最底层的汇编开始,一步一步构造 出一个 RT-Thread 操作系统内核,向大家揭示了任务如何定义、任务如何切换,也讲解了 任务的延时如何实现,讲解了如何支持多优先级,讲解了如何实现定时器和讲解如何实现 时间片等 RT-Thread 操作系统的核心知识点;第二部分,则讲解 RT-Thread 内核设施的应 用,使得大家学习 RT-Thread 不再困难,使用 RT-Thread 不再困难。 整本书由浅入深,层层叠加,与初学者的入门路径完全吻合,是学习 RT-Thread 物联 网操作系统的不二之选书籍。同时整本书也兼顾深度,对于要了解操作系统内核原理的使 用者,也非常值得一看。 RT-Thread 创始人 本书电子版和配套的实验源码均可到野火电子 / RT-Thread / 芯片之家 公众号下载。 野火电子公众号 RT-Thread 公众号 芯片之家公众号 1 / 363 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com
RT-Thread 内核实现与应用开发实战指南 —基于野火 STM32 全系列(M3/4/7)开发板 《RT-Thread 内核实现与应用开发实战指南—基于 STM32》 野火 STM32 固件库和 GUI 书籍 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 2 / 363
RT-Thread 内核实现与应用开发实战指南 —基于野火 STM32 全系列(M3/4/7)开发板 第1章 前言 1.1 如何学习本书 本书是首本系统讲解 RT-Thread 的中文书籍,共分为两个部分,第一部分为“从 0 到 1 教你写 RT-Thread 内核”,即重点讲解 RT-Thread 的原理实现,从 0 开始,不断迭代,教 你怎么把 RT-Thread 的内核写出来,让你彻底学会线程是如何定义的,系统是如何调度的 (包括底层的汇编代码讲解),多优先级是如何实现的等等操作系统最深层次的知识。当 你拿到本书开始学习的时候你一定会惊讶,原来 RTOS 的学习并没有那么复杂,反而是那 么的有趣,原来自己也可以写 RTOS,成就感立马爆棚。 当第一部分知识你彻底掌握好之后,再切换到其它 RTOS 的学习,那简直就是易如反 掌,纵观现在市面上流行的几种 RTOS,它们的内核的实现基本都差不多,只需要深入研 究其中一种即可,没有必要每一种 RTOS 都深入的研究源码,如果你时间允许,看看那也 无所谓。第二部分是“RT-Thread 内核应用开发”,重点讲解 RT-Thread 的移植,内核每个 组件的应用,比起第一部分,这部分内容掌握起来比较容易。 全书内容循序渐进,不断迭代,前一章都是后一章的基础,必须从头开始阅读,不能 进行跳跃式的阅读。在学习的时候务必做到两点:一是不能一味地看书,要把代码和书本 结合起来学习,一边看书,一边调试代码。看书倒是很简单,那如何调试代码?即单步执 行每一条程序,看看程序的执行流程和执行的效果与自己大脑所想是不是一样;二是在每 学完一章之后,必须将配套的例程重写一遍(切记不要复制,哪怕是一个分号,但可以 抄),做到举一反三,确保真正理解。在自己写的时候肯定会错漏百出,这个时候要珍惜 这些错误,好好调试,这是你提高编程能力的最好的机会。记住,程序不是一气呵成写出 来的,而是一步一步调试出来的。 1.2 本书的参考资料 1、 RT-Thread 官方源代码 2、 RT-Thread_manual.zh.pdf(电子版) 3、 《STM32 库开发实战指南》(电子版) 1.3 本书的编写风格 本书第一部分以 RT-Thread Nano 3.0.3 官方源码为蓝本,抽丝剥茧,不断迭代,教你 怎么从 0 开始把 RT-Thread 内核写出来。书中涉及到的数据类型,变量名称、函数名称, 文件名称,文件存放的位置都完全按照 RT-Thread 官方的方式来实现,当你学完这本书之 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 3 / 363
RT-Thread 内核实现与应用开发实战指南 —基于野火 STM32 全系列(M3/4/7)开发板 后可以无缝地切换到原版的 RT-Thread 的使用。要注意的是,在实现的过程中,某些函数 我会去掉一些形参和一些冗余的代码,只保留核心的功能,但这并不会影响我们学习。 本书第二部分主要讲 RT-Thread 的移植和内核组件的使用,不会再去深入讲解源码, 着重讲应用,如果对第一部分不感兴趣的朋友,可以跳过第一部分,直接进入第二部分的 学习,两者之间没有必然的联系。 1.4 本书的配套硬件 本书支持野火 STM32 开发板全套系列,具体型号见表格 1-1,具体图片见图 1-1、图 1-3、图 1-5、图 1-7 和图 1-9。其中野火挑战者有三个型号,分别为 F429、F767 和 H743, 它们共用同一个底板,只是核心板不一样。学习的时候如果配套这些硬件平台做实验,学 习必会达到事半功倍的效果,可以省去中间硬件不一样时移植遇到的各种问题。 表格 1-1 野火 STM32 开发板型号汇总 型号 - MINI 指南者 霸道 霸天虎 挑战者 F429 挑战者 F767 挑战者 H7 区别 内核 Cortex-M3 Cortex-M3 Cortex-M3 Cortex-M4 Cortex-M4 Cortex-M7 Cortex-M7 引脚 64 100 144 144 176 176 176 RAM 48KB 64KB 64KB 192KB 256KB 512KB 1MB ROM 256KB 512KB 512KB 1MB 1MB 1MB 2MB 图 1-1 野火【MINI】STM32F103RCT6 开发板 4 / 363 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com
RT-Thread 内核实现与应用开发实战指南 —基于野火 STM32 全系列(M3/4/7)开发板 图 1-2 野火【MINI】STM32F103RCT6 开发板 带液晶效果图 图 1-3 野火【指南者】STM32F103VET6 开发板 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 5 / 363
RT-Thread 内核实现与应用开发实战指南 —基于野火 STM32 全系列(M3/4/7)开发板 图 1-4 野火【指南者】STM32F103VET6 开发板带液晶效果图 图 1-5 野火【霸道】STM32F103ZET6 开发板 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 6 / 363
RT-Thread 内核实现与应用开发实战指南 —基于野火 STM32 全系列(M3/4/7)开发板 图 1-6 野火【霸道】STM32F103ZET6 开发板带液晶显示效果图 图 1-7 野火【霸天虎】STM32F407ZGT6 开发板 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 7 / 363
RT-Thread 内核实现与应用开发实战指南 —基于野火 STM32 全系列(M3/4/7)开发板 图 1-8 野火【霸天虎】STM32F407ZGT6 开发板带液晶显示效果图 图 1-9 野火【挑战者】F429/F767/H743 开发板 论坛:www.firebbs.cn 淘宝:https://fire-stm32.taobao.com 8 / 363
分享到:
收藏