启动模式设置步骤
1.三大模式
- 熔丝:烧录一次,发布产品
- 外部:USB,串口deng
- 内部:SD卡,eMMc,NAND
设置方法:
(BOOT MODE0BOOT MODE1)
2.内部介质
- SD
- eMMC
- Nade
设置方法:
BT_CFG1[4:7]
3.接口编号
设置方法:
BOOT_CFG23
4.介质属性
- SD/eMMC:位宽(BT_CFG2[5])
镜像文件
1、boot ROM 程序
选择内部启方式,启动boot ROM程序
- 初始化时钟,外部DDR3
- 从外部存储介质加载代码
2.镜像五要素
![2023-09-21T13:50:48.png转存失败,建议直接上传图片文件][5]
1.空偏移
- 芯片厂商设定
![2023-09-21T14:05:49.png转存失败,建议直接上传图片文件][6]
2.lmage vector table,简称IVT
- 关键数据位置
![2023-09-21T14:13:00.png转存失败,建议直接上传图片文件][7]
3.Boot data,启动数据
- 镜像加载地址、大小
![2023-09-21T14:15:15.png转存失败,建议直接上传图片文件][8]
4.Device configuration data,简称DCD
- 关键外设的寄存器配置信息(时钟、DDR3相关)
![2023-09-21T14:17:52.png转存失败,建议直接上传图片文件][9]
、
5.bin文件
- 真正程序文件
三.SDK方式烧录镜像
1.获取NXP官方SDK
![2023-09-21T14:55:21.png转存失败,建议直接上传图片文件][11]
四.RAM-v7架构
1.运行模式
User(USR):用户模式
- linux系统用户进程。资源访问受限
System(SYS):系统模式
- linux内核,共用寄存器,资源自由访问
IRQ:一般中断模式
- 硬件产生中断信号
FIQ:快速中断模式
- 时间紧急的中断,高速信号的传输、采集
Supervisor(SVC):管理模式
- 默认模式,系统初始化,软中断
Abart(ABT):数据访问终止模式
- 非法访问地址或寄存器、段错误
Undef(UND):未定义指令模式
- 程序跑飞、篡改
Monitor:用于用户安全扩展横式
Hyp:用于虚拟化扩展
2.寄存器组
通用寄存器
- r0~r3:用来传递函数参数、暂存数据
- r4-r11:用来保存被调函数的局部变量、暂存数据
- r12:记录函数调用过程中上一次sp指针的值
- r13(sp):函数堆栈寄存器
- r14(lr):记录函数返回地址
- r15(pc):程序计数器
程序状态寄存器
- cpsr:该寄存器包含运算标志位、中断禁止位、当前运行模式标志等—些状态位以及一些控制位
- spsr:发生异常切换模式时,将cpsr复制到发生异常的模式下的spsr
系统寄存器 - cp15协处理器:内存、缓存、中断等
五.ARM常用汇编指令
汇编格式:
labe1: instruction @ comment
- label:标号
- instruction:具体汇编指令
- comment:注释内容
常用段名
- .text:代码段
- .data:初始化的数据段
- .bss:未初始化的数据段
- .rodata:只读数据段
- .section:自定义段
.section .vector
常见伪操作
.global:定义全局标号
.global _start
.align:字节对齐
.align 2
寄存器间数据传输
- mov:寄存器数据(或者是立即数)拷贝到另- 个寄存器
mov ro,r1
mov ro,#Ox12
- mrs:读程序状态寄存器
mrs ro, cpsr
- msr:写程序状态寄存器
msr cpsr ,ro
-
mrc:读cp15协处理器
-
mcr:写cp15寄存器
内存与寄存器数据传输
- ldr:把内存数据(或者是立即数)加载到寄存器
ldr r0,=Ox80000000
ldr r1,[r0]
- str:把寄存器数据写入到内存
ldr r0,=Ox80000000
str r1,[r0]
压栈和出栈
- push:把寄存器列表存入栈中
push{r0~r 3,r12}
- pop︰从栈中恢复寄存器列表
pop{rO~r 3,r12}
跳转
- b:跳转到目标地址
b main
- bl:跳转到目标地址,并把当前pc指针值保存在lr寄存器中
bl main
算术运算指令
- add: 加法运算
add r1,r2,r3 (r1=r2+r3)
add r1,r2 (r1=r1+r2)
- sub:减法运算
sub r1,r2,r3
- mul:乘法运算
mul r1,r2,r3
- udiv;除法运算
udiv r1,r2 ,r3
逻辑运算
- and: 与
and rl,r2 ,r3
- orr:或
orr ri,r2,r3
- bic:位清除
bic r1,r2,r3
六.GPIO工作原理
了解GPIO数量
5组GPIO (GPIO1 ~GPIO5),每组最多32个,共124个
GPIO1_IO0~GPIO1_IO31
GPIO2_IO0~GPIO2_IO21
GPIO3_IO0~~GPIO3_IO28
GPIO4_IO0~~GPIO4_IO28
GPIO5_IO0~GPIO5_IO11
时钟
GPIO1时钟
两个bit的不同取值,设置GPIO时钟的不同属性:
- 00:所有模式下都关闭外设时钟
- 01∶只有在运行模式下打开外设时钟
- 10:保留
- 11:除了停止模式以外,该外设时钟全程使能
引脚复用
- 相关寄存器IOMUxC_SW_MUX_CTL_PAD_XXX
注意:数据手册上对GPIO引脚的命令,不是严格按顺序命名的,而是根据Table 28来命名的
引脚属性
- HYS (bit16)∶用来使能迟滞比较器
- PUS (bit15-bit14) :用来设置上下拉电阻大小
- PUE (bit13):当I0作为输入的时候,这个位用来设置IO便用上下拉还是状态保持器
- PKE(bit12)∶用来使能或者禁止上下拉/状态保持器功能
- ODE (bit11) : IO作为输出的时候,此位用来禁止或者使能开漏输出。
- SPEED (bit7-bit6):当IO用作输出的时候,此位用来设置I0速度。
- DSE (bit5-bit3) :当IO用作输出的时候用来设置IO的驱动能力。
- SRE (bit0):设置压摆率
控制GPIO引脚
5组GPIO,每组GPIO有8个相关寄存器
- GPIOx_GDIR:设置引脚方向
- GPIOx_DR:设置输出引脚的电平
I
每个寄存器有32位。分别控制每位的gpio
七.控制GPIO总结
- 使能GPIO时钟
- 设置引脚复用为GPIO
- 设置引脚属性(上下拉、速率、驱动能力)
- 控制GPIO引脚输出高低电平
八.汇编点灯
代码
.global _start @汇编文件开始地方
_start:
@1.使能GPIO时钟
ldr r0,=0x20c40dc @将要使能的时钟地址加载到r0寄存器
ldr r1,=0xffffffff
str r1,[r0] @将该时钟所有功能都使用
@2.设置引脚复用为GPIO @将要复用引脚的寄存器地址加载到r0寄存器
ldr r0,=0x20e006c
ldr r1,=5 @将该引脚复用为GPIO功能
str r1,[r0]
@3.设置引脚属性(上下拉、速率、驱动能力
ldr r0,=0x20e02f8 @将设置引脚属性的寄存器地址加载到r0寄存器
ldr r1,=0x10b0
str r1,[r0]
@4.控制GPIO引脚输出高低电平
ldr r0,=0x0209c004 @将设置引脚方向寄存器地址加载到r0寄存器
ldr r1,=16 @设置第4个引脚为输出模式
str r1,[r0]
ldr r0,=0x0209c000 @将设置输出高低电平寄存器地址加载到r0寄存器
ldr r1,=0 @将所有引脚设置为输出低电平
str r1,[r0]
烧写过程
1.下载裸机的gcc编译器
sudo apt-get install gcc-arm-none-eabi
2.编译汇编文件为可重定位文件led.o
arm-none-eabi-gcc -c led.s -o led.o
3.把重定位文件链接起来,得到可执行文件(elf文件)
sudo arm-none-eabi-ld -Ttext 0x80000000 led.o -o led.elf
4.把elf文件去掉冗余的段和elf头,得到纯净的bin文件
sudo arm-none-eabi-objcopy -O binary led.elf led.bin
5.给bin文件添加6ull特殊的头部信息(IVT+boot+data+DCD),并烧录到SD卡
./mkimage.sh ~/demo/汇编/led.bin