第一章 嵌入式系统导论
嵌入式系统概述
嵌入式系统的定义
- 嵌入式系统是嵌入式计算机系统的简称。顾名思义,它是一种嵌入在设备(或系统)内部,为特定应用而设计的专用计算机系统。
- 嵌入式系统是以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
嵌入式系统的组成
- 嵌入式系统一般由嵌入式硬件和软件组成,且软件与硬件是紧密集成在一起的。
- 硬件以嵌入式微处理器为核心集成存储器和系统专用的输入/输出设备。
- 软件包括初始化代码及驱动、嵌入式操作系统和应用程序等,这些软件有机地结合在一起,形成系统特定的一体化软件。
嵌入式系统的分类
嵌入式实时系统系统根据实时性强弱可进一步分类
- 硬实时系统
- 系统对系统响应时间有严格的要求,如果系统相应时间不能满足,就要引起系统崩溃或致命的错误。
- 软实时系统
- 系统对系统响应时间有要求,但是如果系统响应时间不能满足,不会导致系统出现致命的错误或崩溃。
【填空】按嵌入式系统软件结构分类
- 循环轮询系统
- 前后台系统(又称中断驱动系统)
- 单处理器多任务系统
- 多处理器多任务系统
第二章 嵌入式硬件组成
嵌入式硬件系统的基本组成
- 嵌入式系统的硬件是以嵌入式微处理器为核心,主要由嵌入式微处理器为核心的SoC,总线,存储器,输入/输出接口和设备组成。
嵌入式微处理器
嵌入式微处理器基本组成
- 片内存储器
- 外部存储器的控制器
- LCD控制器
- 中断控制器
- 定时器
- 多媒体加速器
- 总线
- 其他标准接口或外设
嵌入式微处理器体系结构
- 传统的微处理器采用的冯·诺依曼结构将指令和数据存放在同一存储空间中,统一编址,指令和数据通过同一总线访问。
- 哈佛结构主要特点是程序和数据存储在不同的存储空间中,即程序存储器和数据存储器是两个相互独立的存储器,每个存储器独立编制、独立访问。与之相对应的是系统中设置的两条总线(程序总线和数据总线),从而使数据的吞吐率提高了一倍。
嵌入式微处理器指令系统
精简指令集系统RISC和复杂指令集系统CISC
基于ARMv4的编程模型
【简答】ARM7的三级流水线
流水线技术是现代微处理器普遍采用的一种技术,它可以使得几条指令并行执行,因此可以大大提高处理器的运行效率。
- 取指:从程序存储器中读取指令,放入流水线中。
- 译码:操作码译码,决定执行什么功能。
- 执行:执行已译码的指令。
数据宽度(类型)
- 字节型数据
- 半字数据类型
- 数据宽度为16bits,存取时必须以2字节对齐的方式
- 字数据类型
- 数据宽度为32bits,存取时必须以4字节对齐的方式
工作状态和工作模式
ARM处理器有七种基本的工作模式,每一种工作模式只能访问自己的栈空间和不同的寄存器子集,有一些操作只能在特权模式下执行
- 用户模式(User)
- 系统模式(System)
- 异常模式
- FIQ ---- 快速中断处理。用于处理高速数据传送或通道处理。
- IRQ ---- 用于一般中断处理。
- Supervisor ---- 特权模式。用于系统初始化或操作系统功能。
- Abort ---- 存储器保护异常处理
- Undefined ---- 未定义指令异常处理。
通用寄存器
通用寄存器是R0~R15,可以分为3类
- 没有对应影子寄存器的寄存器R0~R7
- 所有模式下,R0~R7对应的物理寄存器都是相同的,这8个寄存器是真正意义上的通用寄存器。
- 有对应影子寄存器的寄存器R8~R14
- R8~R12只在FIQ模式下才有影子寄存器,各有2个物理寄存器:FIQ模式和非FIQ模式。
- R13、R14在FIQ、IRQ、Supervisor、Abort、Undefined模式下都有影子寄存器,各有6个物理寄存器,用户模式和系统模式共用,其他5个用于各异常模式。
- R13(SP指针)被用作栈指针,通常在系统初始化时需要对所有模式下的SP赋值,CPU会自动切换成相应模式下的值。
- R14(LR,链接寄存器)主要用于保存子程序返回地址或异常返回地址。
- 程序计数器R15(PC)
中断与异常
中断与异常的定义
- ARM处理器把外部中断、程序引起的软件中断以及CPU内部的异常事件都以异常模式来处理。
- 外部中断:由于CPU外部的原因而改变程序执行流程的过程,属于异步事件,又称为硬件中断,可被屏蔽。
- 软件中断(自陷):通过处理器拥有的软件指令,可预期地使处理器正在运行的程序的执行流程发生改变,以执行特定的程序。
- 异常:由CPU内部的原因(如遇到非法指令)或外部的原因(如访存的错误引起的事件。
- ARM CPU将引起异常的原因分为7种,分别利用5种异常模式来对应,并使用中断向量表的方式进行异常响应
ARM的外部中断
- ARM有两级的外部中断,FIQ和IRQ
- 绝大多数基于ARM的系统有两个以上的中断源,因此需要一个中断控制器来控制中断信号如何进入ARM芯片
异常的优先级
有些异常会同时发生,异常被赋以了优先级,据此决定被响应的顺序
嵌入式系统总线
嵌入式系统总线的定义
- 总线是计算机系统的公共信息传输通路,由系统中各个部件共享。
- 嵌入式系统的总线一般分为片内总线和片外总线。
AMBA总线
在AMBA总线规范中,定义了3种总线
- AHB(Advanced High-performance Bus):高级高性能总线。用于高性能系统模块的连接,可以连接处理器、片上和片外存储器,支持流水线操作。
- ASB(Advanced System Bus):高级系统总线。用于高性能系统模块的连接,已被AHB总线替代。
- APB(Advanced Peripheral Bus):高级外设总线。用于较低性能外设的简单连接,一般是接在AHB或ASB系统总线上的第二级总线。
串行总线
- UART:通用异步串行收发器。可以实现全双工传输。RS-232用来实现计算机与计算机之间、计算机与外设之间的数据通讯。
- I2C:同步串行半双工串行通信接口。是IC器件之间互联的两线制总线规范。
- SPI:全双工同步串行接口。可用于单主控器同标准外设芯片的通信,也可用于组建多主同步网络。
- USB:通用串行总线。由差分数据线D+、D-和电源VCC、地GND四根信号线组成,D+,D-用于传送数据,VCC和GND用于向从机提供电源。
嵌入式系统存储器
主存
- 大多数嵌入式系统的代码和数据都存储在处理器可直接访问的存储空间即主存中。
- 特点是速度快。
- ROM类:NorFlash、EPROM、E2PROM、PROM等。
- RAM类:SRAM、DRAM、SDRAM等。
外存
- 外存是处理器不能直接访问的存储器,用来存取用户的各种信息。
- 常用的电子盘:NandFlash、DOC、DOM、CF、SM、SD、MMC
第三章 ARM汇编程序设计
ARM嵌入式微处理器指令集
ARM指令集概述
- ARM属于RISC指令集,通过一系列简单的指令实现复杂的功能。
- ARM处理器主要实现两种指令集:
ARM指令集常用举例
- 数据处理指令
- 算术运算指令
- ADD:加法指令
- ADC:带进位加法指令
- SUB:减法指令
- SBC:带错位减法指令
- RSB:逆向减法指令
- RSC:带错位逆向减法指令
- 逻辑运算指令
- AND:逻辑与指令
- ORR:逻辑或指令
- EOR:异或指令
- BIC:位清零指令
- 比较运算指令
- CMP:比较指令
- CMN:比较反值指令
- TST:位测试指令
- TEQ:相等测试指令
- 数据传送指令
- 加载/存储指令
- 分支指令
- 状态寄存器访问指令
- MRS:CPSR或SPSR到通用寄存器的数据传送指令
- MSR:通用寄存器到CPSR或SPSR的数据传送指令
- 协处理器指令
- LDC:存储器到协处理器的数据传送指令
- STC:协处理器寄存器到存储器的数据传送指令
- 异常处理指令
- SWI:软件中断指令
ARM指令所使用的的条件后缀
后缀 |
含义 |
标志 |
EQ |
相等 |
Z置位 |
NE |
不相等 |
Z清零 |
CS/HS |
无符号大于或等于 |
C置位 |
CC/LO |
无符号小于 |
C清零 |
MI |
负数 |
N置位 |
PL |
正数或零 |
N清零 |
VS |
溢出 |
V置位 |
VC |
无溢出 |
V清零 |
HI |
无符号大于 |
C置位Z清零 |
LS |
无符号小于或等于 |
C清零Z置位 |
GE |
大于或等于 |
N等于V |
LT |
小于 |
N不等与V |
GT |
大于 |
Z清零且N等于V |
LE |
大于或等于 |
Z置位或N不等与V |
AL |
总是 |
无条件执行 |
ARM处理器基本寻址方式
; 第二个源操作数即为立即数,要求以"#"为前缀,对于十六进制表示的立即数,还要求在"#"后加上"0x",不加"0x"表示十进制数
MOV R0,#0x11 ;R0 = 0x11
ADC R0,R0,#99 ;R0 ← R0+99+C
; 利用寄存器中的数值作为操作数
ADD R0,R1,R2 ;R0 ← R1+R2
; 以寄存器中的值作为操作数地址,而操作数本身放在存储器中。用于间接寻址的寄存器必须用"[]"括起来
LDR R5,[R4] ;R5 ← [R4],间接寻址的寄存器是R4
STR R1,[R2] ;[R2] ← R1,间接寻址的寄存器是R2
; LSL:(逻辑左移),相当于无符号数x2
; ASR: (算术右移),相当于带符号的数除2
; LSR: (逻辑右移),相当于无符号数除2
; ROR:(循环右移),相当于位轮换
; RRX:(带扩展的循环右移),位轮换,从CF到MSB都参与
ADD R0,R1,R2,LSL #2 ;R0 = R1 + R2<<2
; 将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。变址寻址方式常用于访问某基地址附近的地址单元。
LDR R0,[R1,#3] ;R0 ← [R1+3]
STR R1,[R2,#6] ;[R2+6] ← R1
LDR R0,[R1,#3]! ;R0 ← [R1+3]、R1 ← R1+3
LDR R0,[R1],#3 ;R0 ← [R1]、R1 ← R1+3
LDR R0,[R1,R2] ;R0 ← [R1+R2]
STR R0,[R1,R2] ;[R1+R2] ← R0
; 块拷贝寻址又称多寄存器寻址,采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。
; 这种寻址方式可以用一条指令完成传送最多16个通用寄存器的值。
LDMIA R0,[R1,R2,R5,R9] ;R1 ← [R0]、R2 ← [R0+4]、R5 ← [R0+8]、R9 ← [R0+12]
; 满递增堆栈:堆找指针指向最后压入的数据,且由低地址向高地址生成
; 满递减堆栈:堆栈指针指向最后压人的数据,且由高地址向低地址生成
; 空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成
; 空递减堆找:堆找指针指向下一个将要放人数据的空位置,且由高地址向低地址生成
;与基址变址寻址方式相类似,相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。
BL Subrouhtine_A ;跳转到子程序Subrouhtine_A处执行
Subrouhtine_A
MOV PC,LR ;从子程序返回
ARM汇编
ARM汇编语法
-
{}{S} ,{,}
-
<指令的操作码>{<条件域>}{是否更新CPSR} <目的寄存器>,<第一个操作数>{,<第二个操作数>}
-
符号必须顶格书写,在指令和伪指令中,符号用作地址标号。
-
在伪操作中,符号用作变量或者常量。
-
而所有指令均不能顶格书写。
-
ARM汇编语言是以段为单位来组织源文件的。段是相对独立的、具有特定名称的、不可分割的指令或者数据序列。
ARM程序设计
实验课程序设计
完成两个64位数据的加法运算,数据来源和计算结果都在寄存器中
AREA Init,CODE,READONLY
ENTRY
CODE32
START
LDR R0,= 0x11111111 ;存储数据A的高32位
LDR R1,= 0x22222222 ;存储数据A的低32位
LDR R2,= 0x33333333 ;存储数据B的高32位
LDR R3,= 0x44444444 ;存储数据B的低32位
ADDS R1,R1,R3 ;R1+R3溢出,ADDS进位,c标志位置1,R1=0x44444444
ADC R0,R0,R2 ;高位相加,ADC是带进位的加 ,R0=0x66666666
B START
END
对一个32位立即数的最低4位分别实现置1、清零和取反操作
AREA Init,CODE,READONLY
ENTRY
CODE32
START
LDR R0,= 0x12345678
ORR R1,R0,#0x0F ;低4位置1
BIC R2,R0,#0x0F ;低4位清零
EOR R3,R0,#0x0F ;低4位取反
B START
END
将存储器中的一个字数据读取到寄存器R0中。使用DCD伪操作为数据分配存储空间和初始化数据
AREA Init,CODE,READONLY
ENTRY
CODE32
START
ADR R1,DATATEST ;将DATATEST的地址加载到R1
LDR R0,[R1] ;将DATATEST的数据加载到R1
DATATEST DCD 0x23 ;分配一片地址空间给DATATEST,并初始化位0x23
B START
END
已知8名学生成绩,求平均成绩、最高分和最低分,并统计不及格人数
AREA analysis,CODE,READONLY
ENTRY
INIT
LDR R0, =DATA ;加载数据
MOV R2, #0 ;按照学生人数设置循环次数
MOV R3, #0 ;R3存放总分
MOV R4, #0 ;R4存放不及格人数
MOV R5, #0 ;R5存放平均成绩
LDR R6, =0xFFFFFFFF ;R6存放最小值
LDR R7, =0x0 ;R7存放最大值
START
LDR R1, [R0], #4
ADD R3, R3, R1
CMP R1, R6
MOVLS R6, R1
CMP R1, R7
MOVHI R7, R1
CMP R1, #60
ADDLS R4, R4, #1
ADD R2, R2, #1
CMP R2, #8
BNE START
MOV R5, R3, LSR #3
B INIT
DATA
DCD 80,65,90,40,80,75,100,65,60,55
END
第四章 嵌入式软件系统
嵌入式软件系统分类和体系结构
按嵌入式软件结构分类
- 循环轮询系统
- 前后台系统
- 单处理器多任务系统
- 多处理器多任务系统
【综合】嵌入式软件系统体系结构
- 硬件驱动层
- 板级初始化程序
- 与系统软件相关的驱动
- 与应用软件相关的驱动:不一定需要与操作系统连接,这些驱动的设计和开发由应用决定
- 操作系统层
- 包括嵌入式内核、嵌入式TCP/IP网络系统、嵌入式文件系统、嵌入式GUI系统和电源管理等部分。
- 其中嵌入式内核是基础和必备的部分,其他部分要根据嵌入式系统的需要来确定。
- 中间件层
- 在一些复杂的嵌入式系统中也开始采用中间件技术,主要包括嵌入式CORBA、嵌入式Java、嵌入式DCOM和面向应用领域的中间件软件。
- 应用层
- 主要由多个相对独立的应用任务组成。
- 每个应用任务完成特定的工作,如I/O任务、计算任务、通信任务等,由操作系统调度各个任务的运行。
嵌入式操作系统
嵌入式内核的功能
- 任务管理
- 内存管理
- 通信管理
- 中断管理
- 时间管理
- 特定的应用编程接口
嵌入式软件开发工具
【简答】嵌入式软件开发环境
嵌入式软件的开发环境:嵌入式交叉开发环境,包括宿主机、目标机、工具集等。
- 宿主机:用于开发嵌入式系统的计算机。一般为PC机、工作站,具备丰富的软硬件资源,为嵌入式软件的开发提供全过程支持。
- 目标机:即面向应用所开发的嵌入式系统,嵌入式软件的运行环境。目标机一般是裸机,没有任何的软件资源。
嵌入式软件实现阶段的开发过程
- 生成:源代码程序的编写,编译成各个目标模块,链接成可供下载调试或固化的目标程序。
- 调试:调试器通过某种方式控制目标机上被调试程序的运行方式,采用交叉调试方式,广泛使用的是JTAG方式(下载、执行、调试和控制) 。
- 固化运行:程序代码需要完全烧写到目标板的非易失性存储器(如ROM或闪存)中,在真实的硬件环境上运行,这个过程叫做固化。
第五章 任务管理与调度
任务
任务定义及其主要特性
任务是一个具有独立功能的,无限循环的程序段的一次运行活动,是嵌入式实时操作系统内核的基本调度单位,具有动态性、并行性和异步独立性等特性。
- 动态性:任务状态是不断变化的。 一般分为就绪态、运行态和等待态。在多任务系统中,任务的状态将随着系统的需要不断进行变化。
- (并发)并行性:系统中同时存在多个任务,对于单处理器多任务系统,多个同时运行的任务宏观上看是并发的,微观上看是串行的。
- 异步独立性:每个任务各自按相互独立、不可预知的速度运行。
任务内容
- 代码,一段可执行的程序。
- 数据,程序所需要的相关数据(变量、工作空间、缓冲区等)。
- 堆栈,局部变量,子程序调用,任务上下文等。
- 程序执行的上下文环境。
任务的优先级
- 表示任务对应工作内容在处理上的优先程度。
- 优先级越高,表明任务越需要得到优先处理。
- C/OS中可以管理64个任务,每个任务必须有个不同的优先级。优先级的数值越低,任务的优先级就越高。C/OS总是选择优先级最高的任务执行。
任务管理
【综合】任务状态与变迁
- 只有获得资源的任务才可以执行。任务拥有的资源情况是不断变化的,导致任务状态也表现出不断变化的特性。
- 不同的实时内核实现方式对任务状态的定义不尽相同。
- 任务会在不同的状态之间进行转换,即任务状态的变迁,C/OS有5种不同的状态。
任务切换
- 保存当前任务的上下文,并恢复需要执行的任务的上下文的过程。
- 内核对任务管理是通过对任务控制块(TCB)内核对任务管理是通过对任务控制块。TCB包含任务相关信息的数据结构,包含了任务执行过程中所需要的所有信息。
- 引起任务切换的事件
- 中断、自陷
- 运行任务因缺乏资源而被阻塞
- 时间片轮转调度时
- 高优先级任务处于就绪时
任务调度
任务调度概述
- 调度用来确定多任务环境下任务执行的顺序和在获得CPU资源后能够执行的时间长度。操作系统通过一个调度程序来实现调度功能。
- 在多任务系统中,常用的调度算法有基于优先级的可抢占调度和时间片轮转调度。
- 当有多个任务同时就绪时,内核利用特定的算法求出当前具有最高优先级的就绪任务。在嵌入式实时操作系统中,常用的就绪算法是优先级位图算法。
基于优先级的可抢占调度算法
- 如果出现具有更高优先级的任务处于就绪状态时,当前任务将停止运行,实时内核进行任务切换,保存当前正在运行任务的上下文,把CPU的控制权交给具有更高优先级的任务,切换到具有更高优先级的任务的上下文,使更高优先级的任务得到执行。
时间片轮转调度算法
- 当有两个或多个就绪任务具有相同的优先级,且它们是就绪任务中优先级最高的任务时,任务调度程序按照这组任务就绪的先后次序调度。
优先级位图算法
- 优先级位图算法利用就绪表OSRdyTbl来存放不同优先级任务的就绪状态。
- 每个优先级占用一个bit。如果就绪,则相应bit置1,否则为0。
优先级反转
【简答】优先级反转概述
- 任何时候都只允许一个任务访问的资源称为临界资源,用于访问临界资源的代码段称为临界区或临界段。
- 理想情况下,高优先级任务就绪后,能够立即抢占低优先级任务而得到执行。但在有多个任务需要使用共享资源的情况下,有可能出现优先级反转:高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务的现象。
- 解决优先级反转的常用协议有优先级继承协议和优先级天花板协议。
优先级继承协议
- 当一个任务阻塞了一个或多个高优先级任务时,该任务将不使用其原来的优先级,而使用被该任务所阻塞的所有任务的最高优先级作为其执行临界区的优先级;
- 当该任务退出临界区时,又恢复到其最初的优先级。
优先级天花板协议
- 对于控制临界区的信号量,设置信号量的优先级天花板为需要申请该信号量的所有任务中具有最高优先级任务的优先级;
- 如果任务成功获得信号量,任务的优先级将被抬升为信号量的优先级天花板;
- 任务执行完临界区,释放信号量后,其优先级恢复到其最初的优先级。
第六章 同步、互斥和通信
概述
执行体之间的关系
在多任务系统中,任务和中断服务例程(ISR)可被统称为执行体。
- 相互独立:仅仅竞争CPU资源。
- 互斥:竞争除CPU外的其他共享资源。
- 同步:协调彼此运行的步调,保证协同运行的各个任务具有正确的执行次序。
- 通信:彼此间传递数据或信息,以协同完成某项工作。
嵌入式操作系统内核提供的同步、互斥与通信机制
- 信号量(semaphore),用于互斥与同步。
- 事件(组)(event group),用于同步。
- 异步信号(asynchronous signal),用于同步。
- 邮箱(mailbox)、消息队列(message queue),用于消息通信。
- 管道(pipe),提供非结构化数据交换(通信)和实现同步。
信号量
信号量的种类及用途
- 信号量用于实现任务与任务之间、任务与中断处理程序之间的同步与互斥。
- 信号量一般分为三种。
- 互斥信号量:用于解决互斥问题,可能会引起优先级反转问题。初始值为1
- 二值信号量:用于解决同步问题,同步的二值信号量初始值为0
- 计数信号量:用于解决资源计数问题,初始值为N
- 用互斥信号量保护的代码区称作“临界区”,互斥信号量初始化为1,μC/OS-Ⅱ在使用该临界资源之前,必须获得保护该资源的互斥信号量,并将值设为0。使用完资源后,释放信号量,将该值置1。
消息邮箱
【简答】消息邮箱的概述及目的
- 消息邮箱是一种通信机制,它能使任务或中断服务向另一个任务发送一个指针型的变量,这个指针指向一个包含指定“消息”的数据结构。消息邮箱发送的不是消息本身,而是消息的地址指针。
- 主要用于两种目的:
第七章 中断、时间、内存和I/O管理
中断管理
中断的分类
【简答】按硬件中断是否可以被屏蔽分类
- 可屏蔽中断:能够被屏蔽掉的中断。
- 外部设备的中断请求信号一般需要先通过CPU外部的中断控制器,再与CPU相应的引脚相连。
- 可编程中断控制器可以通过软件进行控制,以禁止或是允许中断。
- 不可屏蔽中断:在任何时候都不可屏蔽的。
- 一个比较典型的例子是掉电中断,当发生掉电时,无论程序正在进行什么样的运算,它都将无法正常运行。这种情况下,急需进行的是一些掉电保护的操作。对这类中断,应随时进行响应。
按中断源分类
按中断信号的产生分类
按中断服务程序的调用方式分类
中断控制器的功能
- 对多个可屏蔽中断源进行管理,使CPU核心能和更多的中断资源相联系。
- 能够对中断进行排队
- 避免中断信号的丢失
- 对不同的中断进行优先级配置,使高优先级中断能够中断低优先级中断。
【填空】中断处理过程
实时内核的中断服务程序通常包括三个方面的内容:
- 中断前导:保存中断现场,进入中断处理。
- 用户中断服务程序:完成对中断的具体处理。
- 中断后续:恢复中断现场,退出中断处理。
【简答】内存保护内容
内存保护包含两个方面的内容:
- 防止地址越界:每个应用程序都有自己独立的地址空间,当应用程序要访问某个内存单元时,由硬件检查该地址是否在限定的地址空间之内,只有在限定地址空间之内的内存单元访问才是合法的,否则需要进行地址越界处理;
- 防止操作越权:对于允许多个应用程序共享的存储区域,每个应用程序都有自己的访问权限,如果一个应用程序对共享区域的访问违反了权限规定,则进行操作越权处理。