没有合适的资源?快使用搜索试试~ 我知道了~
首页从零开始:C语言驱动的嵌入式操作系统内核实战教程
从零开始:C语言驱动的嵌入式操作系统内核实战教程
需积分: 5 21 下载量 18 浏览量
更新于2023-05-23
1
收藏 3.58MB PDF 举报
本手册名为《底层工作者手册之嵌入式操作系统内核》,作者是一位没有专业操作系统内核背景的从业者,仅凭有限的应用经验和基本的C语言知识,通过实践和自学,逐步构建了一个实时嵌入式操作系统内核。该手册的核心价值在于,它不仅从实际应用角度介绍操作系统,更注重阐述操作系统内核的工作原理和设计过程。 作者以个人编写操作系统内核的经历为基础,详细解释了从零开始创建一个内核的过程。读者将跟随作者的脚步,理解操作系统内核的功能实现步骤,如内存管理、进程调度、中断处理等核心模块。每个新增功能都配以实例演示,使读者能够直观地看到代码运行的效果。此外,手册强调C语言和硬件基础知识的重要性,认为具备这些技能的读者完全可以理解和修改扩展操作系统。 相比于许多只关注使用方法的书籍,这本书更侧重于操作系统内核的底层原理和设计思路,旨在帮助读者深入理解操作系统的工作机制。作者通过边设计边编码的方式,分享了操作系统从无到有的诞生过程,使得即使是对硬件和底层编程不熟悉的读者,只要有基础的C语言知识,也能跟随本书进行学习。 书中特别提到,作者在工作初期,由于缺乏实践经验,面对硬件开发遇到诸多困难。然而,这正是他转向软件开发,特别是底层编程的契机。通过这个转变,他逐渐积累了宝贵的经验,成为了一名能够编写操作系统内核的专家。 《底层工作者手册之嵌入式操作系统内核》是一本实用的教程,适合希望深入了解操作系统内核实现过程的读者,特别是那些希望通过实践和理解底层原理来提升自己技能的程序员。它不仅仅是一份技术指南,也是作者个人成长和学习的记录,为读者提供了一个宝贵的学习案例。
资源详情
资源推荐
9
ARM7 芯片软件的运行完全是由上述的这些寄存器决定的 , 只要能合理的修改这些寄存
器就能控制软件的运行 , 操作系统就是通过备份 、 还原 、 更改这些寄存器来控制程序执行流
程的,进而实现任务之间的切换。由于 C 语言无法访问到这些寄存器,因此必须使用汇编
语言才能对这些寄存器进行操作,下节我们将了解一些 ARM7 的汇编语言,以便理解操作
系统的任务切换过程。
第 2 节 ARM7 汇编语言简介
ARM7 芯片有 2 种汇编语言指令集,一种叫做 ARM 指令集,字长为 32bits ,另一种 叫
THUMB 指令集 , 字长为 16bits 。 这两种指令集各有优缺点 , 它们可以单独使用也可以混合
在一起使用,在 ARM7 芯片上,我们将只使用 ARM 指令集,在后续的 Cortex 芯片上我们
将使用 THUMB 指令集的改良版 —— THUMB2 指令集。
本小节只介绍本操作系统中使用到的一些汇编语言 , 对它们的介绍也仅限于本操作系统
使用到的部分用法,并非全面,更详细的信息请读者自行查阅附录中的参考文档 2 。
另外我再补充一下我观点 , 以前看到一些同学说在学习芯片 , 请教如何使用汇编语言编
程 , 总是抠这方面的问题 。 我觉得如果我们学习芯片的目的只是做开发项目 , 那么就没有必
要学习汇编语言 , 可以把更多的精力放在学习芯片的功能特性上 。 一个完备的芯片产品甚至
不需要底层软件工程师了解太多的芯片硬件外设特性,有封装好的驱动库函数可以直接调
用 。 这次如果不是编写操作系统 , 我对汇编语言也仅仅是了解一点 。 汇编语言了解一点即可 ,
,
在某些极少数情况下可能会使用到汇编语言定位问题,但这也是极少的情况。
在操作系统中我们使用了下面几条指令:
� MOV/MOVS
MOV 是英文单词 Move 的缩写 , “ 搬移 ” 的意思,将数据搬移进寄存器,指令格式为 :
MOV 目的寄存器 , 源寄存器
MO V 指令将源寄存器中的数据搬移到目的寄存器中 , 寄存器间数据搬移可以使 用 MO V
指令,如:
MOV R 0 , R1
MOV R14, PC
意为:
R0 = R1
R14 = PC + 8
注意, ARM7 有两级流水线,如果读取 PC 寄存器的话,就会多读取 2 条指令的长度
,
也就是 8 个字节,目的寄存器为 PC+8 。
MOVS 指令与 MOV 指令的格式 、 功能是一样的 , 除此之外 , 如果目的寄存器是 PC 的
话 , MOVS 会将当前模式下的 SPSR 写入到 CPSR 中 。 本操作系统从 SVC 模式返回 USR 模
式时就需要使用 MOVS 指令恢复 USR 模式的 CPSR 。例如,在中断模式下有下面的指令:
MOVS PC, R14
意为:
CPSR = SPSR
10
PC = R14
� ADD
ADD 指令顾名思义,就是英文 Add “ 加 ” 的意思,指令格式为:
ADD 目的寄存器 , 源寄存器 , 立即数
ADD 指令将源寄存器中的数据和立即数相加的结果保存到目的寄存器中,执行加法操
作时可以使用 ADD 指令,如:
ADD R14, R14, #0x40
意为:
R14 = R14 + 0x40
� SUB/SUBS
SUB 是英文单词 Subtract 的缩写,意为 “ 减 ” ,指令格式为:
SUB 目的寄存器 , 源寄存器 , 立即数
SUB 指令将源寄存器中的数据减去立即数,所得的结果存入到目的寄存器中,执行减
法操作时可以使用 SUB 指令,如:
SUB R14, R14, #4
意为:
R14 = R14 – 4
SUB S 指令中 的 S 标志 与 MOV S 指令中 的 S 标志作用类似 , 如果目的寄存器 是 P C 的话
,
SUBS 会将当前模式下的 SPSR 写入到 CPSR 中。本操作系统从 IRQ 中断模式返回 USR 模
式时就需要使用 SUBS 指令恢复 USR 模式的 CPSR ,如:
SUBS PC , R14, #4
意为:
PC = R14 – 4
CPSR = SPSR
� AND
AND 指令顾名思义,就是英文 And “ 与 ” 操作的意思,指令格式为:
AND 目的寄存器 , 源寄存器 1, 源寄存器 2
AND 指令将源寄存器 1 中的数据和源寄存器 2 中的数据做与操作,结果存入目的寄存
器中,执行与操作时可以使用 AND 指令,如:
AND R0 , R0, R1
意为:
R0 = R0 & R1
� ORR
ORR 对应的英文是 Or , “ 或 ” 操作的意思,指令格式为:
11
ORR 目的寄存器 , 源寄存器 1, 源寄存器 2
ORR 指令将源寄存器 1 中的数据和源寄存器 2 中的数据做或操作,结果存入目的寄存
器中,执行或操作时可以使用 ORR 指令,如:
ORR R0 , R0, R1
意为:
R0 = R0 | R1
�
LDR
LDR 是英文 Load Register 的缩写 , “ 加载寄存器 ” 的意思 , 将内存中的数据存入寄存器
中,指令格式为下面 2 种格式 :
LDR 目的寄存器 , [ 源寄存器 ]
LDR 目的寄存器 , = 常量
第一种格式将源寄存器中数据指向的内存地址中的数据存入目的寄存器 , 第二种格式将
常量值存入目的寄存器,为寄存器赋值时可以使用 LDR 指令,如:
LDR R14, [R0]
LDR R0, =gpstrCurTaskSpAddr
第一条 指令意为:
R14 = *R0
第二条 指令中 gpstrCurTaskSpAddr 是一个全局变量,第二条指令意为:
R0 = &gpstrCurTaskSpAddr
从上述介绍来看 , LDR 指令与 MOV 指令似乎具有相同的功能 , 都可以为寄存器赋值
。
这两条指令的部分功能确实是一样的 , 但它们也有各自应用的特点 。 要说明这两者之间的区
别,我们还需要进一步了解 ARM7 的指令结构,以下是有关 ARM7 机器码的一些知识 , 可
以了解一下,但如果你只是做软件开发则不会有太多用处,了解即可。
ARM7 内核采用的是 RISC 精简指令集,所有的 ARM 指令都是 32bits 的,在这 32bit s
里既包含了指令的指令码,也包含了指令需要运算的数据,以 MOV 指令为例,通过 MO V
指令的 32bits 可以识别出这是一个 MOV 指令 , 又可以在这 32bits 里找到源寄存器和目的寄
存器。我们来看一下 MOV 指令的机器码格式:
图 6 MOV 指令的机器码格式
28~31bits ( cond ) 是条件码 , 就是表明这条语句里是否有大于 、 等于 、 非零等的条件判
断,这 4bits 共有 16 种状态,分别为:
二进制码 指令符号 含义 二进制码 指令符号 含义
0000 EQ 相等 0001 NE 不等
0010 CS/HS
进位
/
无符号数
大于等于
0011 CC/LO
清进位
/
无符
号数小于
0100 MI
减
/
负数
0101 PL
加
/
正数或
0
12
0110 VS 溢出 0111 VC 没溢出
1000 HI 无符号数大于 1001 LS 无符号数小
于等于
1010 GE 有符号数大于
等于
1011
LT
有符号数小
于
1100 GT 有符号数大于 1101 LE 有符号数小
于等于
1110 AL 任何条件
1111
- 未定义
表 1 汇编语言条件码
指令与条件码可以有多种组合 , 比如 MOV 指令可以有 MOV 、 MOVEQ 、 MOVLT 等多
种形式。前面我们说过状态寄存器里有 NZCV 的状态标志,当执行一条指令时,芯片就会
将这条指令的条件码与状态寄存器中的状态标志做比较 , 如果状态寄存器中的状态标志满足
这条指令的条件码时 , 则执行这条语句 , 如果不满足则不执行这条指令 。 状态寄存器中的状
态标志是受某些指令影响的 , 因此在使用有条件码的指令进行判断前 , 必然会有其它指令配
合使用,先修改状态寄存器中的状态标志,例如:
CMP R1, #0
BEQ GETNEXTTASKSP
第一条 指令 “ CMP ” 是一个 “ 比较 ” 指令,如果 R1 等于 0 ,那么它就将状态寄存器中
的 Z 置为 1 , 表示结果为真 , 否则 , 将状态寄存器中的 Z 置为 0 , 表示结果为假 。 第二条指
令其实是一条 “ B ” 指令 , 是 “ 跳转 ” 指令 , B 之后的 “ EQ ” 就是条件码 , 从表 1 中可以知
道,条件是 “ 相等 ” 时才执行。
当 R1 等于 0 时, CMP 指令就将 Z 置为 1 ,执行 BEQ 时满足条件,就执行了跳转。如
果 R1 不等于 0 , CMP 指令就将 Z 置为 0 ,执行 BEQ 时不满足条件,就不执行跳转。
同理,只有当状态寄存器中的标志为相等时, MOVEQ 指令才会执行,这时其功能 与
MOV 指令相同。而 MOVLT 指令则是当状态寄存器中的标志为有符号数,并且处于小于状
态时才会执行的 MOV 指令 。 MOV 指令的条件码是 AL , 因此 MOV 指令可以不管任何条件
都去执行。其它指令也可以与条件码组合使用,具体情况请查阅参附录中的参考文档 2 。
25bit ( I ) 是用来区别 shifer_operand 域是采用立即数寻址方式还是寄存器寻址方式 , 该
bit 为 0 表示寄存器寻址方式,为 1 表示立即数寻址方式,这就涉及到了指令的寻址方式。
寻址方式的出现不是为了使指令能有多种写法,而是受指令长度限制被迫产生的产物
。
以 MOV 指令为例,如果采用立即数寻址,立即数的长度不可能超过 shifer_operand 域的长
度( MOV 指令可以采用移位的方式装下部分更长的立即数,这些不在讨论之内 ) ,因此我
们就不可能使用
MOV R0, #0x12345678
这条指令。立即数 #0x12345678 是 32bits 数据,已经超过了 shifer_operand 域所能装下
的最长 12bits 数据,如果把 0x12345678 全部被存到指令中,那么该指令中将无法存储条件
码等其它指令信息,因此,这条指令在编译时就会报错。
为了解决这个问题,芯片设计人员就设计了寄存器寻址方式,在 ARM7 中每种模式 有
16 个通用寄存器 , 2 的 4 次方等于 16 , 因此只需要用 4bits 就可以为每个寄存器分配一个编
号 , R0~R15 寄存器分别对应 0~15 的编号 。 4bits 的寄存器编号完全可以存入 shifer_operan d
域。采用寄存器寻址时,指令先查到寄存器的编号,然后再从寄存器中取出使用的数据 , 这
样就解决了 MOV 指令受指令长度的限制而无法操作长立即数的问题。
13
从上述描述的过程来看采用寄存器寻址方式必须先将数据放入一个寄存器中 , 然后才能
使用 MOV 指令采用寄存器寻址 。 对比立即数寻址方式 , 它增加了指令的执行时间 , 也增加
了代码,还多用了一个寄存器,但它的优点是可以操作长的数据。
除了上面这两种寻址方式外 , ARM7 还有多种其它寻址方式 , 每种寻址方式都有其自身
的特点,适用不同的场景,这里不介绍了。
21~24bits ( opcode )是指令码,用来表明这条指令是什么指令,例如, MOV 指令的指
令码是 0b1101 ,看到 0b1101 ,芯片就将这条指令当做 MOV 指令来解析。
20bit ( S ) 就是指令中 S 标志的体现 , 该 bits 为 0 表示指令不带 S , 为 1 表示指令带 S
,
功能见上述指令介绍。
16~19bits ( SBZ )手册中没查到是什么意思, SBZ 应该是 should be zero 的意思,对比
了几条指令发现该域果然全是 0 ,应该是保留位。
12~15bits ( Rd )是指令中的目的寄存器,存放寄存器的 4bits 编号。
0~11bits ( shifter_operand ) ,指令的操作数。
下面我找了 4 条指令,将 MOV 指令做一个对比:
指令 机器码
指令格式
cond 00 I opcode S SBZ Rd shifer_operand
MOV R1, #0x 64 E3A010 64 1110 00 1 1101 0 0000 0001 000001100100
条件码 为
111 0 适用任
何条件
立即数
方式
MOV 的
指令码
指令没
有 S 标志
目的寄存
器为 R1
源操作数为立即
数 0x64
MOVS PC, R14 E1B0F00E 1110 00 0 1101 1 0000
1111
000000001110
条件码 为
111 0 适用任
何条件
寄存器
方式
MOV
的
指令码
指令有
S
标志
目的寄存
器为 R15
源操作数为寄存
器 R14
MOVLT R3, #0x1 B3A03001 1011 00 1 1101 0 0000 0011 000000000001
LT 的条件
码为 1011
立即数
方式
MOV 的
指令码
指令没
有 S 标志
目的寄存
器为 R3
源操作数为立即
数 1
MOVEQ R0, R1 01A00001 0000 00 0 1101 0 0000 0000 000000000001
EQ 的条件
码为 0000
寄存器
方式
MOV 的
指令码
指令没
有 S 标志
目的寄存
器为 R0
源操作数为寄存
器 R1
表 2 MOV 指令汇编格式对比
LDR 指令可以将 32bits 数据一次装入寄存器中,这里不再详细说明了,请读者自行参
考文档。
� STR
STR 是英文 Store Register 的缩写 , “ 存储寄存器 ” 的意思,将数据从寄存器存入内存
。
STR 指令与 LDR 指令功能相反,指令格式为:
STR 源寄存器 , [ 目的寄存器 ]
STR 指令将源寄存器中的数据存入目的寄存器中数据所指向的内存地址,将寄存器中
的数据存入内存时可以使用 STR 指令,如:
STR R1, [R0]
剩余193页未读,继续阅读
WangChao1227
- 粉丝: 2
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- 图书馆管理系统数据库设计与功能详解
- ***物流有限公司仓储配送业务SOP详解
- 机械专业实习经验与学习收获
- 阎良区生活垃圾卫生填埋场施工与运营管理详解
- 濮阳市生活垃圾无害化处理工程施工组织设计详解
- MATLAB均匀平面波仿真课程设计指南
- 北京市地铁9号线技术规格与设备详情
- 西门子PLC在中央空调自动控制系统的应用
- PLC驱动的电梯控制系统发展历程与未来趋势
- 外墙维修工程政府采购项目施工方案概述
- 项目方案委员会会议全程指南与文件清单
- Dreamweaver实战:创建简单网页与站点管理
- 国内升学与就业政策及信息搜集指南
- 国资公司2020上半年创新发展与资产管理工作总结
- 项目管理:目标控制与各方角色分工详解
- 构建项目管理体系:提升组织绩效的关键
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功