1.arm指令结构包括32位arm指令集和16位thumb指令集。
arm指令要满足字边界对齐。
thumb指令满足半字边界对齐。
由arm进入到thumb寄存器Rm的状态位bit[0] = 1时,执行BX Rm 指令跳转。
由thumb进入arm寄存器Rm的状态位bit[0] = 0时,执行BX Rm 指令跳转。当处理器进入异常处理时,则从异常向量地址开始执行,系统自动进入arm。
例:从arm到thumb
LDR R0,=Lable + 1
BX R0
例:从thumb到arm
LDR R0,=Lable
BX R0
arm处理器支持字节(8位),半字节(16位),字(32位)。
大端格式:较高的字节存放在较低的存储字节地址。
小端格式:较高的字节存放在较高的存储字节地址。
例:0x12345678 起始地址为:0x8000
大: 小:
0x78 0x8003 0x12
0x56 0x8002 0x34
0x34 0x8001 0x45
0x12 0x8000 0x78
arm处理的7种模式:
CPSR[4:0] 模式 用途
1000 用户 用户模式
特权模式: { 异常模式:{ 1001 FIQ 快速中断
1002 IRQ 普通中断
1003 SVC 软件中断
1004 中止 处理存储器故障,实现虚拟存储器和存储器保护
1005 未定义 处理未定义的指令陷进}
1006 系统 运行特权操作系统任务}
arm处理器共有37个寄存器,分为:31个通用寄存器和6个状态寄存器。
FIQ处理程序可以不必保存和恢复中断现场,从而使FIQ中断的处理过程更加的迅速。
R13(SP):称为堆栈指针SP,应用程序在对每一种异常模式进行初始化时,都要初始化该模式下的R13使其指向相应的堆栈,
退出异常模式时,将保存在R13所指的堆栈中的寄存器值弹出。
R14(LR) : 用来存放子程序的返回地址,执行完后将R14的值复制到pc,子程序即可返回。
R15(PC) : 向R15写入一个地址值,程序会跳到该地址。
状态寄存器:CPSR,SPSR
CPSR 1,4个条件代码标志 :负,零,进位,溢出
2,2个中断禁止位
3,5个编码位
4,1个指示是arm还是thumb
N Z C V - - - I F T M4 M3 M2 M1 M0
条件代码标志 保留位 控制位
异常向量地址表:异常中断种类
地址 类型 进入模式 进入I的状态 进入F的状态 优先级
0x0000 0000 复位 管理 禁止 禁止 1
0x0000 0004 未定义指令 未定义 禁止 F 6
0x0000 0008 SWI 管理 F 7
0x0000 000C 中止 中止 F 5
0x0000 0010 数据中止 中止 F 2
0x0000 0014 保留 保留 F
0x0000 0018 IRQ 中断 F 4
0x0000 001C FIQ 快中断 禁止 禁止 3
S3C2440分为三个部分:arm902T,AHB总线,APB总线。
arm920t内核16位/32位RISC微处理器。
AHB用于连接高时钟频率和高性能的系统模块。
APB以低性能,慢速外设提供较为简单的接口。
ADC带进位的加法器
ADD加法器
AND逻辑与
B分支跳转
BIC位清零
BL带连接分支跳转
BX分支和状态切换跳转
CDP协处理器数据处理
CMN负数比较
CMP比较
EOR逻辑异或
LDC加载数字数据,从存储器到协处理器,协处理器加载
LMD加载数字数据,从存储器到多寄存器,栈操作
寄存器寻址:
MOV R1,R2 ;R1 < R2
SUB R0,R1,R2 ;R0 < R1 - R2
立即寻址:
ADD R0,R0,#1 ;R0 < R0 + 1
MOV R0,#0XFF00 ;R0 < 0XFF00
寄存器移位寻址:
MOV R0,R2,LSL #3 ;R0 < R2 << 3
ADD R3,R2,R2,LSR #2 ;R3 < R2 + R1 >> 2
寄存器间接寻址:
LDR R0,[R1] ;R0<-[R1]
STR R0,[R1] ;[R1]<-R0
基地址加偏址寻址
前地址变化:LDR R0,[R1 , #4] ;R0 <-[R1 + 4]
自动地址变化:LDR R0,[R1,#4]! ;R0 <-[R1 + 4],R1 <- R1 + 4
!自动变址功能
后变址模式:LDR R0,[R1],#4 ;R0 <- [R1]传数据,R1 <- R1 + 4传地址
例:
LDR R0,[R1,R2] ;R0 <- [R1 + R2]
LDR R0,[R1,R2,LSL#2] ;R0 <- [R1 + R2*4]
数据传送指令MOV
MOV R1,R2 ;将寄存器R0的值传到寄存器R1,下同
MOV PC,R14
MOV R1,R0,LSL #3
数据取反传送:MVN
MVN R0,#0 ;将0取反传到R0中
比较指令:CMP
CMP R1,R0 ;R1与R0相减,根据结果设置CPSR标志位
BIC位清零
BIC R0,R0,#0XB ;清除R0中0,1,3位,其余保持不变
B跳转
CMP R1,#1 ;R1的值减0,设置CPSR的标志位
BEQ Lable ;带条件的跳转,当CPSR的标志位Z置位时,程序跳到Lable
带状态切换的转移指令BX
如果Rn中的最低位为1,则将CPSR的T标志置为1切换到Thumb指令集
MOV R6 ,#0X8000
BX R6 ;转换到地址为0x8000处的Thumb指令
带返回的转移指令BL
BL Lable ;程序无条件跳到Lable处执行,同时将PC的值保存到R14中。
带返回且带状态返回的转移指令BLX
乘法指令和乘加指令(MUL,MLA)
MUL R0,R1,R2 ;R0 = R1 * R2
MULS R0,R1,R2 ;R0 = R1 * R2 同时设置CPSR的相关标志位
MLA R0,R1,R2,R3 ;R0 = R1 * R2 + R3
MLAS R0,R1,R2,R3 ;R0 = R1 * R2 + R3 同时设置CPSR的相关标志位
长乘法指令(SMULL,UMULL)
SMULL表示64位有符号乘法运算:
SMULL R0,R1,R2,R3,R4 ;R0 = (R2 * R3)的底32位,R1 = (R2 * R3)的高32位
UMULL表示64位有符号乘法运算:
UMULL R0,R1,R2,R3,R4 ;R0 = (R2 * R3)的底32位,R1 = (R2 * R3)的高32位
字数据加载命令:LDR,上面有举例
字节数据加载命令:LDRB
LDRB R0,[R1] ;将存储器地址为R1的字节数据读入寄存器R0,并将R0的高24位清0
LDRB R0,[R1,#8] ;将存储器地址为R1 + 8的字节数据读入寄存器R0,并将R0的高24位清0
半字数据加载指令:LDRH
LDRH R0,[R1] ;将存储器地址为R1的半字节数据读入寄存器R0,并将R0的高16位清0
LDRH R0,[R1,#8] ;将存储器地址为R1 + 8的半字节数据读入寄存器R0,并将R0的高16位清0
LDRH R0,[R1,R2] ;将存储器地址为R1 + R2的半字节数据读入寄存器R0,并将R0的高16位清0
字数据存储指令:STR
STR R0,[R1],#8 ;R1 <- R0 传数据,R1 <- R1 + 8传地址
STR R0,[R1,#8] ;R1 + 8 <- R0
字节数据存储指令:STRB 将源寄存器中位于底8位的字节数据传送到存储器
STRB R0,[R1]
STRB R0,[R1,#8]
半字数据存储:STRH 将源寄存器中位于16位的字节数据传送到存储器
STRH R0,[R1]
STRH R0,[R1,#8]
字数据交换指令:SWP
SWP R0,R1,[R2] ;R0 <- R2 , R2 <- R1
字节数据交换指令:SWPB 高24位清零,低8位交换
SWPB R0,R1,[R2] ;R0 <- R2 , R2 <- R1
程序状态寄存器到通用程序寄存器的数据传送:MRS
MRS R0,CPSR ;R0 <- CPSR
MRS R0,SPSR ;R0 <- SPSR
通用程序寄存器到程序状态寄存器的数据传送:MSR
MSR CPSR,R0 ;CPSR <- R0
MSR SPSR,R0 ;SPSR <- R0
MSR CPSR_C,R0 ;CPSR <- R0仅修改控制位域
ARM微处理器可以支持16个协处理器,
1,数据操作指令:CDP
CDP P2,5,C12,C10,C3,4 ;完成协处理器p2的初始化,让p2在c10,c3上执行操作5和4,并把结果存入c12中。
2,数据加载指令:LDC P5,C3,[R0] ;P5的C3 <- R0
3,数据存储指令:STC P8,C8,[R2,#4]! ;(R2 +4) <- P8的C8 , R2 <- R2 + 4
4,寄存器到协处理器的数据传送指令:MCR
MCR P3,3,R0,C4,C5,6 ;R5中的数据传到P3的C4和C5中
5,协处理器到寄存器的数据传送指令:MRC
MRC P15,2,R5,C0,C2,4 ;P15寄存器的数据传到R5中,C0,C2为协处理器寄存器,存放原操作数,操作码1为我,操作码2为4。
软件中断:SWI
MOV R0,#34 ;设置功能号为34
SWI 12 ;产生软件中断,中断号为12
符号定义指示符号:
GBLA定义全局算术变量,初始化为0
GBLL定义全局逻辑变量,初始化为false
GBLS定义全局串变量,初始化为NULL
例:GBLS S1 ;声明全局串变量S1
局部变量声明:
LCLA
LCLL
LCLS ;跟上面一样
设置变量值:
SETA
SETL
SETS ;意义跟上面一样
例: 是S1 SETS "string"
给符号名一个常数值:
num2 EQU 25 ;给符号num2指定值为25
ADR是小范围的地址读取伪指令,它将基于PC 相对偏移的地址值读取到寄存器中。而ldr获取的是内存的值,像指针一样间接寻址。
test1
MOV r1,#0
ADR r2,test1 ;产生一条SUB指令,装去地址test1到r2,
使用LDR的两个主要目的,1是当一个立即数的值由于超出了范围,不能用MOV和MVN指令装到寄存器时,用LDR指令产生一个文字池常数,2是装入一个相对程序或外部的地址到一个寄存器。
汇编语言中的命令不能用大小写混用。
PC代表程序计数器,流水线使用三个阶段,因此指令分为三个阶段执行:
1.取指(从存储器装载一条指令);2.译码(识别将要被执行的指令);3.执行(处理指令并将结果写回寄存器)。
而R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令。
一般来说,人们习惯性约定将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC总是指向第三条指令。
当ARM状态时,每条指令为4字节长,所以PC始终指向该指令地址加8字节的地址,即:PC值=当前程序执行位置+8;
嵌入式处理器S3C2440可以工作在400MHZ时钟频率,所以片内集成了时钟管理单元,主要由锁相环和分频器构成。
S3C2440芯片内部的时钟信号为FCLK,HCLK,和PCLK。
S3C2440有两个锁相环:MPLL和UPLL。MPLL产生三种信号:FCLK,HCLK,PCLK,FCLK用于arm920T,HCLK用于AHB总线,PCLK用于APB总线
USB锁相环UPLL产生的时钟信号UCLK用于USB,UPLL专用于USB设备
/* 设置MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0)
* m = MDIV+8 = 92+8=100
* p = PDIV+2 = 1+2 = 3
* s = SDIV = 1
* FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M
系统时钟初始化
开机系统后的基本设置:
ldr r0, =0x53000000 //关闭看门狗计时器
ldr r1, =0
str r1, [r0]
/* 设置MPLL, FCLK : HCLK : PCLK = 400m : 100m : 50m */
/* LOCKTIME(0x4C000000) = 0xFFFFFFFF *///设置为默认值
ldr r0, =0x4C000000
ldr r1, =0xffffffff
str r1, [r0]
/* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8 *///设置三个的基本比例
ldr r0, =0x4C000014
ldr r1, =0x5
str r1, [r0]
/* 设置CPU工作于异步模式 */
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
/* 设置MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0)
* m = MDIV+8 = 92+8=100
* p = PDIV+2 = 1+2 = 3
* s = SDIV = 1
* FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M
*/
ldr r0, =0x4C000004 //设置fclk为400MHZ
ldr r1, =((92<<12) | (1<<4) | (1<<0))
str r1, [r0]/* 一旦设置PLL, 就会锁定lock time直到PLL输出稳定
* 然后CPU工作于新的频率FCLK
*/
/* 设置内存: sp 栈 */
/* 分辨是nor/nand启动
* 写0到0地址, 再读出来
* 如果得到0, 表示0地址上的内容被修改了, 它对应ram, 这就是nand启动
* 否则就是nor启动
*/
mov r1, #0
ldr r0, [r1]
str r1, [r1]
ldr r2, [r1]
cmp r1, r2
ldr sp,=0x40000000+4096
streq r0,[r1]
bl main
halt:
b halt
定时器时钟频率 = PCLK / ((8位预分频器 + 1) * 时钟分频值)
TCNTBn和TCMPBn的双缓冲特征保证了改变频率和占空比定时器产生稳定的输出。
PWM脉冲宽度通过TCMPBn来实现,频率由TCNTBn决定。
看门狗定时器的工作频率 = PCLK / ((预分频值 + 1) / 分频系数)
S3c2440的存储控制器包括以下特性:
1.系统支持大/小端数据存储格式
2.储存空间分为8个bank,每个bank有128M字节空间,全部可寻址空间总共有1GB,使用nGCS0~nGCS7作为对应各bank选择信号。
3,除bank0外,其余bank都可编程访问,宽度为8,16,32位。
4.bank1 ~ bank5可以使用ROM和SRAM,bank6和7可以使用ROM/SRAM/SDRAM
5.bank0~bank6开始地址固定,bank7开始地址和大小可编程。
存储系统一般由Flash(闪存) 和 SDRAM构成。
Nor flash特点:容量小,造价高,可靠性高,寿命短,读速快。系统可以直接在norflash运行指令,用于启动和引导系统。主要用于存放启动代码。
nandflash : 容量大,价格底,寿命长,写速度快,不能用于主存,只能按扇区读写,可以作为小硬盘。主要用来存放数据和程序。也可以从nandflash启动和引导系统,在SDRAM上执行主程序。
在嵌入式硬件系统中一般把bank6和bank7用作SDRAM存储区。
bank0的数据总线可以配置为16位和32位的宽度。bank0是作为引导ROM,映射到0x00000000。因此在第一次ROM访问就决定bank0的总线宽度,方法就是通过复位时OM[1:0]的逻辑电平。
nandflash启动,nandflash控制器会自动把前4K的数复制到SRAM上,并把SRAM上的数据映射到nGCS0(0x000000000)上。系统从SRAM中启动
norflash启动:需要根据norflash的位宽来配置OM1和OM0引脚,当位宽为16bit时,OM1和OM0应该分别是低电平和高电平,为32位时反过来。此时norflash被映射到0x00000000地址