ARM接口与技术
1、应用层课程:C、linux-c、数据结构、IO、进程线程、网络编程、c++、qt
底层课程: ARM、系统移植、驱动开发、stm32&nbiot
嵌入式开发岗位: 嵌入式应用开发 C/C++ 应用 协议
嵌入式驱动开发 驱动 bsp
初级--》中级--》高级--》专家(系统架构)
--》PM--》。。。
2、问题
(1)为什么要学习底层课程? open
1 解释应用层
2 为我们的职业发展更长远做准备
(2)为什么要学习ARM?
1 学习一款硬件平台,一款主流的嵌入式平台
2 为后边底层课程做铺垫
3 找工作
(3)ARM课程学什么?汇编语言(arm指令集)+裸机编程
3、ARM课程大纲
day1:ARM介绍 环境搭建 汇编指令
day2: 汇编指令
day3: 汇编指令、 软中断
day4: c和汇编的混合编程、led驱动
day5: uart驱动、硬件中断
day6: 硬件中断、看门狗
day7: pwm、考试
嵌入式软件: 有OS:OS+app
无OS:app
嵌入式硬件:输入 + 输出 + 控制器 + 运算器 + 存贮器 + 总线
控制器:是整个嵌入式系统的指挥中心
运算器(ALU):是对信息做运算的和处理的部件
存贮器:用来存放数据和程序的部件,是设备的记忆装置
处理器图片:
处理器(SOC):片内系统system on chip
CPU:在处理器(soc) 内部,包含(控制器,运算器,寄存器组)
内存:(sdram)
硬盘:(flash)
接口(gpio):用来接外设,如led灯
实时时钟:(rtc)
数模转换器:(adc)
嵌入式设备有哪些存储器?外存、 内存、 高速缓存器(cache)、寄存器
内存:sdram。存放当前正在执行的程序和数据-->cpu能直接访问
外存:也称为辅助存储器(硬盘 磁盘 U盘 光盘 SD卡。。。)用来永久存放
程序和数据,cpu不能直接访问
寄存器:用来存放CPU运算过程中的数据和结果值。
高速缓存器:(cache)存放当前正在执行的程序中的活跃部分--》cpu能直接访问
总结:
soc=cpu+外围组件
cpu=控制器+运算器+寄存器组(通用)
总线(bus):连接嵌入式硬件各模块;传输数据
USB:大接口
USB OTG:老安卓接口
flash: 硬盘
nor flash -->存放数据+运行程序 (非常贵)
nand flash -->存放数据(常用)
1.3.1 arm是什么?
第一,ARM是公司的名字,ARM公司,该公司的主要业务是设计处理器内核。
处理器内核 = 处理器架构 = 控制时序电路 + arm指令集/thumb指令集
第二,ARM代表一款处理器的架构,ARM不是芯片,ARM公司向芯片厂商
提供内核,芯片厂商用ARM内核 + 外围组件设计出了处理器芯片。
1.3.2 编程模型
ARM 采用的是32位架构:32位指的是CPU一次处理指令的能力是32位。
ARM 约定:
Byte : 8 bits
Halfword : 16 bits (2 byte)
Word : 32 bits (4 byte)
Doubleword 64-bits(8byte)(Cortex-A处理器)
大部分ARM core 提供:
ARM 指令集(32- bit)à arm态使用arm指令集
Thumb 指令集(16-bit )à thumb态使用thumb指令集
1.3.4 arm内核的 “状态“ 和 “工作模式“
ARM内核有两种工作状态:
ARM态 à 默认状态 à 使用ARM指令集(32bits)
thumb态à使用Thumb指令集(16bits)
当ARM内核处于ARM态时,该内核有8种工作模式:
User : 非特权模式,大部分任务执行在这种模式
FIQ : 当一个高优先级(fast) 中断产生时将会进入这种模式
IRQ : 当一个低优先级(normal) 中断产生时将会进入这种模式
Supervisor :当复位或软中断指令执行时将会进入这种模式 svc
Abort : 当存取异常时将会进入这种模式
Undef : 当执行未定义指令时会进入这种模式
System : 使用和User模式相同寄存器集的特权模式
Monitor :( Cortex-A特有模式):是为了安全而扩展出的用于执行安全监控
代码的模式;也是一种特权模式
1.3.5寄存器
寄存器作用:用来在指令的执行过程中存放运算数据和结果值。
ARM内核提供的寄存器容量是多大呢?
普通的arm有37个寄存器(通用寄存器),每个寄存器容量是4byte
容量 = 37 * 4 = 148 byte
contex-A的arm有40个寄存器(通用寄存器),每个寄存器容量是4byte
容量 = 40 * 4 = 160 byte
如何标识寄存器?
r0,r1...r15,cpsr,spsr
40个寄存器是如何计算的? 8+5+5+14+1+1+6=40
r0~r7在各个模式下是公用的,所以r0 ~ r7 算作8个寄存器
r8 ~ r12 有5个
r8_fiq ~ r12_fiq有5个
r13 ~ r14 各个模式下都有自己的寄存器,2*7=14个
r15各个模式共用一个
cpsr各个模式共用一个
spsr 前两个模式没有spsr其他各个模式都不一样,6个
综上:共40个寄存器
40个寄存器中有5类是特殊的寄存器:用来辅助运算
r13(sp):存放sp指针
r14(1r):在执行中断或函数调用时,用来保存当前指令的下一条指令地址
r15(pc):存放pc程序的取指位置
cpsr:当前程序状态寄存器,保存当前处理器的状态信息。
spsr:是cpsr的备份寄存器,通常在发生“中断”或“异常”时使用。
1.3.6 CPSR
cpsr共32bits,每一个bit位都有其特殊的含义
高四位:条件位。(31~28位)
31位(N位):
N = 1表示 ALU运算结果为负数。
N = 0表示 ALU运算结果为正数 或 0
30位(Z位):
Z = 1,表示运算结果为 0
Z = 0,表示运算结果为 非0
29位(C位):进/借 位标志位
加法有进位C = 1,无进位C = 0
减法有进位C = 0,无进位C = 1
28位(V位):
V = 1。ALU运算溢出
V = 0,ALU运算没有一处
低五位:处理器工作模式位(0~4位)
状态位:
中断位:
字节序:不同CPU主机存储多字节的方式不同,有大端序存储,有小端序存储
大端序主机:数据的高字节存放在内存的低地址处
小端序主机:数据的高字节存放在内存的高地址处
(网编讲过,看一看)
(1)ARM8种工作模式:
User、快速中断FIQ、普通中断IRQ、Abort、Undef、Supervisor特权模式、
system模式、Monitor模式
(2)ARM核有多少个寄存器?
普通ARM有37个
contex – A ARM有40个
(3)PC和LR寄存器的别名是什么?
PC是R15
LR是R14
(4)R13的别名
sp
(5)那种模式下使用寄存器最少?
User模式:17个寄存器,User模式下没有Spsr寄存器
(6)cpsr的哪两位反映了处理器的状态
T位、J位
(7)thumb指令的对齐方式
16bit位对齐
协处理器:
SOC:
1.3.7指令流水线 并行 pc指针(pc指针只有一个)
假如执行每一条指令都需要3秒,是不是就要9秒呢?
不是,指令执行是 “相对并行” 的
分3个阶段:取指令à译码à执行:
ARM内核处理指令,可以分成多个阶段,多个阶段可以并行执行,
例如:可以将一条指令的处理分成3个阶段:取指 译码 执行。那么可以
在对第三条指令做取指时,对第二条指令做译码,对第一条指令做执行。
并行:只花了5秒执行。指令被分为3个阶段,这就是三级指令流水线。
三级指令流水线:指令被分为3个阶段,以相对并行的方式处理指令。提高效率。
三级指令流水线为最佳指令流水线。
pc指向正在取指的指令而非正在执行的指令,取指的指令和执行的指令刚好差了8个字节
pc指向的是当前指令地址
那么上一条指令地址就是pc-4
上上一条指令地址是pc-8
因为arm是32位,所以相差4字节
下载压缩包:arm模拟环境
(1)解压“arm模拟环境”
(2)右键点击文件“arm-2011.09-70-arm-none-linux-gnueabi”-->点击“属性”
-->点击“兼容性”-->勾选“以兼容模式润兴这个程序”
(3)双击运行“arm-2011.09-70-arm-none-linux-gnueabi”进行安装,一路全点Next
路径也都默认。
(4)双击运行“MDK454”一路全点Next。最后弹出黑框,点击不安装
(5)打开keil4-->file-->License Management, 复制CID
打开解压出来的文件,点击“realview MDk 注册机 支持realview4.01”打开程序“arm keygen”
输入复制的CID,Target选择 ”ARM“ 点击”Generate“ 生成代码,
复制并粘贴到keil4的”New License ID Code“
点击Add LIC 。
创建工程文件夹“ /ARM_code / test “
复制解压包的文件“map.lds“到“ /ARM_code / test “
在“ /ARM_code / test “下新建文本文档改名为”start.s“
注意:若改名后显示strat.s不是.s文件就打开“此电脑“à查看à勾选文件扩展名
打开keil4àprojectà 创建位置选择刚刚的“test“,并命名为”test“
芯片选择samsang的S3C2410Aàok à否
(1)右键Target1选择ManageComponents
(2)点击Folders/Extensions,勾选Use GCC
输入:arm-none-linux-guneabi
选择:C:\Program Files (x86)\CodeSourcery\Sourcery_CodeBench_Lite_for_ARM_GNU_Linux
(3)右键Target1 选择“Options for Target Target1“
(4)选择linker点击那三个点
(5)选择拷贝过来的”map.lds”à打开àOK
(6)右击Source àAdd File To Grope
(7)文件类型:选择最后一项à选择start.sàAddàClose
创建成功
代码格式:
汇编指令:
//相当于int a = 3,因为arm是32位即4字节
注释一行:@
注释多行:
.if0
……
.endif
调试:
点击: 进入debug ,再次点击退回编辑状态
全部执行: 单步执行:
r0 和r15初始时都为0
单步执行后r0=0x3,r15=0x4 因为arm一条指令的位宽是32位(4byte),所以是4
各种进制的表示方法:
使用ldr指令,超过8位不能用mov,要用ldr
注意:ldr指令也不能超过32位
ldr伪指令:不是arm集中的指令
eg: add
eg:有进位的add
如果不给add加s就不显示cpsr的C位变化
给指令add加s:让 进位/借位 影响标志位cpsr的(C位)显示出来
cpsr的(C):有进位C = 1,
无进位C = 0
比较指令:cmp
使用条件码助记符可以比较两个操作数的相等,不等,大于,小于
使用条件码助记符:
eq:相等
ne:不等
跳转指令:b loop 等价于 goto loop 和c中得goto效果一样
nop:空指令,占4字节,纯粹耗费cpu时间