嵌入式系统的构成
软件:
应用程序
第三方库(Qt,libc,myclient)
操作系统:
引导程序
内核+驱动
文件系统
硬件:
底板:
外置芯片
网卡(DM9000)
声卡
ADC
电源
USB
接口:
串口
SD
LCD+触摸屏
摄像头
按键
核心板:
Soc(CPU+uart+timer)
DDR
Nand
ARM的体系结构
一、ARM的工作模式
用户模式
系统模式
快速中断模式
外部中断模式
特权模式
快速模式
未定义模式
除用户模式外,其它被称为特权模式
用户模式和系统模式外,其它被称为异常模式
二、ARM的寄存器
一共37个寄存器,用户模式和系统模式可以使用17个,其它模式可以使用18个(17+状态寄存器的备份)。
r0~r7:所有模式共用
r8~r12:快速中断模式有它私有的,其它模式共用。
r13~r14:用户模式和系统模式共用,其它模式有私有的。
r15、cpsr:所有模式共用
r15也叫pc:程序计数器,它记录着下一条要执行的程序,可以被赋值,这样就实现了跳转。
cpsr:用户来记录上一条指令的执行状态,进位、溢出、零、负数、当前模式,只有12位有效,其它位目前保留。
spsr:用户模式和系统模式下没有,其它模式有私有的。
与cpsr的格式一样,它是用来备份用户模式和系统模式的cpsr。
三、流水线
一条指令的执行需要六个步骤:
1、取指
2、译码
3、取数
4、计算
5、存储
6、回写
如果只是按顺序执行,那么执行其中一项操作时其它硬件都处于空闲状态,因此ARM引入了流水线的概念,每个控制单元只负责干一件事情,这样理论上,三级流水线就提高了三倍的性能,而5级流水线就提高了五倍的性能。
但实际情况其实达不到,因为流水线会被打断、暂停。
比如:
bl func //跳转指令
ldr r0,[r0,#0]
add r0,r0,r1 //在5级流水线上产生
四、ARM处理器寻址方式
1.立即寻址:#100
2.寄存器寻址:r0,把寄存器当变量使用
3.寄存器间接寻址:[r0],把寄存器当指针变量使用,*r0
4.寄存器偏移寻址:r0 << n,对寄存器进行左移或右移操作
5.基址变址寻址:[r0,#1],相当于对指针变量进行加减操作,*(r0+1);
6.多寄存器寻址:寄存器的批量操作,类似于数组初始化操作
7.堆栈寻址:在ARM汇编语句中也可以使用堆内存和栈内存,但前提是要设置好堆内存和栈内存的基地址,然后就可以向堆内存和栈内存读取、写入数据。
五、ARM指令集
1、ARM指令的格式
<opcode> {<cond>}{S} <Rd>,<Rn> <operand2>...
opcode 指令码
cond 条件码
S 是否影响状态寄存器
Rd 目标寄存器
Rn 源寄存器
{} 可以省略,而<>必须要有的
2、RM指令条件执行及标志位
CMP会自动把比较结果存储到状态寄存器
而数据处理指令需要在指令反加S才会把计算结果存储到状态寄存器。
EQ 相等
NE 不等
3、跳转指令
B 目标地址,是一种相对地址跳转,在当前地址的基础上加一个偏移值,进行跳转,这种跳转速度比较快,但是跳转的范围有限,正负32M以内。
BL 目标地址,是一种绝对地址跳转,需要是完整的一个地址,在跳转前会把下一条指令的地址存储到r14中,然后跳转到目标位置执行,当执行完成后,可以从r14中恢复到pc中,这样就实现了返回。
BLX 功能与BL类似,但会从ARM(32位状态),切换到Thumb(16位状态)。
BX 功能与B类似,但会从ARM(32位状态),切换到Thumb(16位状态)。
4、数据处理指令
MOV r0,#100 <=> r0 = 100
MOV R1,R3,LSL,#3 <=> r1 = r3 <<3
MVN r0,#100 <=> r0 = ~100
ADD r0,r1,#110 <=> r0=r1+110
SUB R0,R0,#1 <=> r0-=1 反减
RSB R3,R1,#0xFF00 <=> r3=0xff00-r1
ADDS R1,R1,R2
ADC R0,R0,R2 带进位的加
SUBS R0,R0,R2
SBC R1,R1,R3 带借位的减
RSBS R2,R0,#0
RSC R3,R1,#0 带借位的反减
AND R0,R0,#3 <=> r0 = r0&3
ORR R0,R0,#3 <=> r0 = r0|3
EOR R1,R1,#3 <=> r1 = r1^3
BIC R0,R0,#3 <=> r0 = r0&(~3)
CMP R1,R0 把两个数的比较结果影响状态寄存器
CMN R1,R0 把两个数求反后比较,并把比较结果结果影响状态寄存器
TST R0,#0x01 把两个数进行按位与操作,并把计算结果影响状态寄存器
TEQ R1,R2 把两个数进行按位异或操作,并把计算结果影响状态寄存器
5、程序状态寄存器传输指令
MRS R7,CPSR 把当前模式的状态寄存器备份到r7
MSR CPSR_cxsf,R3 把数据写入到状态寄存器
[31:24] 为条件标志位域,用f表示
[23:16] 为状态位域,用s表示
[15:8] 为扩展位域,用x表示
[7:0] 为控制位域,用c表示
6、Load、Store指令
Load 从内存加载数据到寄存器
LDR R0,#8
LDR R0,[R1,#8] <=> r0 = *(r1+8);
DMFD R13,{R0,R4‐R12,LR}
Store 把寄存器中的数据写到内存
STR #8,R0
STR R0,[R1,#8] *(r1+8) = r0
STMFD R13,{R0,R4‐R12,LR}
SWP r0,r1,r2 <=> r0 = r2; r2 = r1;
7、中断指令
SWI 0-16777215 一旦这条指令就会进入中断模式。
六、电源锁定:
1、找到厂家提供的代码,保存为start.S文件。
start:
ldr r0, =0xe010e81c
ldr r1, [r0]
orr r1, r1, #0x300
orr r1, r1, #0x1
str r1, [r0]
2、生成目标代码
arm-none-linux-gnueabi-gcc -c start.S ->start.o
3、生成可执行文件(设置代码段、不加入启动代码、不加入标准库)
arm-none-linux-gnueabi-gcc -Ttext 0xd0020010 -nostartfiles -nostdlib start.o -o lock
4、从可执行文件中拷贝出纯二进制指令
arm-none-linux-gnueabi-objcopy -O binary lock lock.bin
5、编译出添加校验和的工具(研究一下,明天我们自己写一份)
gcc mkv210_image.c -o mkv210
6、为lock.bin添加校验和
./mkv210 lock.bin lock_image.bin
7、把添加校验和后的文件烧写到SD卡中执行,效果:开发板能够持续供电。
原文地址:https://www.cnblogs.com/jiangyu0331/p/11791241.html