一、开发板

二、点亮LED灯

步骤1:异常向量表初始化
CPU复位后第一条执行
Matlab
.global _start
_start:
ldr pc, =_reset_handler
ldr pc, =_undefine_handler
ldr pc, =_svc_handler
ldr pc, =_prefetch_abort_handler
ldr pc, =_data_abort_handler
ldr pc, =_reserved_handler
ldr pc, =_irq_handler
ldr pc, =_fiq_handler
步骤2:进入复位处理服务函数
设置CPU工作模式+各模式栈指针(irq、system模式)

Matlab
_fiq_handler:
ldr pc, =_fiq_handler
_irq_handler:
ldr pc, =_irq_handler
_reserved_handler:
ldr pc, =_reserved_handler
_data_abort_handler:
ldr pc, =_data_abort_handler
_prefetch_abort_handler:
ldr pc, =_prefetch_abort_handler
_svc_handler:
ldr pc, =_svc_handler
_undefine_handler:
ldr pc, =_undefine_handler
_reset_handler:
//irq mode
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x12
msr cpsr, r0
//irq_sp
ldr sp, =0x86000000
//system mode
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x1F
msr cpsr, r0
//system_sp
ldr sp, =0x84000000
//enble clock
bl _enable_clock
//init led
bl _init_led
//led on
bl _led_on
b finished
finished:
b finished
步骤3:使能所有外设时钟
GPIO属于外设,时钟不开,GPIO不工作
GPIO_CCGR0 ~ GPIO_CCGR6 32位引脚全部置1
Matlab
_enable_clock:
//CCGR0_clock
ldr r0, =0x020C4068
ldr r1, =0xFFFFFFFF
str r1, [r0]
//CCGR1_clock
ldr r0, =0x020C406C
ldr r1, =0xFFFFFFFF
str r1, [r0]
//CCGR2_clock
ldr r0, =0x020C4070
ldr r1, =0xFFFFFFFF
str r1, [r0]
//CCGR3_clock
ldr r0, =0x020C4074
ldr r1, =0xFFFFFFFF
str r1, [r0]
//CCGR4_clock
ldr r0, =0x020C4078
ldr r1, =0xFFFFFFFF
str r1, [r0]
//CCG5_clock
ldr r0, =0x020C407C
ldr r1, =0xFFFFFFFF
str r1, [r0]
//CCG6_clock
ldr r0, =0x020C4080
ldr r1, =0xFFFFFFFF
str r1, [r0]
bx lr
步骤4:初始化LED GPIO
LED0接的是GPIO 3引脚,GPIO 3默认为GPIO第一组的03号引脚
给低电平灯亮,给高电平灯灭
IOMUXC:IO引脚复用功能寄存器
点亮LED灯使用的是GPIO1_IO03 复用功能寄存器

(1)设置引脚为GPIO模式
将IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 (address:0x020E0068)配置为GPIO功能
Matlab
ldr r0, =0x020E0068
mov r1, #0x05
str r1, [r0]
(2)设置引脚的电气属性

将IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 (address:0x020E02F4)配置为电气属性
Matlab
ldr r0, =0x020E02F4
ldr r1, =0x10B0
str r1, [r0]
(3)设置GPIO为输出模式

将GPIO1_GDIR(sddress:0x0209C004) bit3 置1
Matlab
ldr r0, =0x0209C004
ldr r1, [r0] //将原有的数据读到r1寄存器中
orr r1, r1, #(1 << 3) //3引脚置1
str r1, [r0] //再将修改后的值回写到r0寄存器中
步骤5:点亮LED灯
LED灯负极接GPIO1_IO03,正极接VCC
GPIO输出0 -> 灯亮
GPIO输出1 -> 灯灭

即将GPIO1_RD(address:0x0209C000) bit3 清0,表示接低电平,灯亮
Matlab
ldr r0, =0x0209C000
ldr r1, [r0] //将原有的数据读到r1寄存器中
bic r1, r1, #(1 << 3) //3引脚清0,让led灯亮
str r1, [r0] //再将修改后的值回写到r0寄存器中
bx lr
三、编译
1.安装交叉编译器:
- 将交叉编译器安装包拷贝到虚拟机并解压
- 手动配置Ubun的ftp服务
- sudo apt-get install vsftpd
- 下载完成后用 VI命令打开/etc/vsftpd.conf
- 找到local_enable=YES write_enable=YES 确保这两行之前没有 #
- 最后重启ftp服务,sudo /etc/init.d/vsftpd restart
2.启用新安装的工具链
解压之后由于我们使用的Ubuntu之前安装过更古老版本的交叉工具链,我们必须先把原来那个屏蔽掉。方法是打开家目录下的.bashrc文件,将我们新安装的工具链启用起来:
- sudo vi /etc/profile
- 在文件末尾添加export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux gnueabihf/bin
- 重启Ubuntu,输入arm-linux-gnueabihf-gcc--v,能看到4.9.4字样,说明新工具链安装成功
3.使用编译器编译.asm文件
- 编译文件
- arm-linux-gnueabihf-gcc-g-c led.s-o led.o
- 链接文件
- arm-linux-gnueabihf-ld-Ttext 0x87800000 led.o-oled.elf
- 格式转换
- arm-linux-gnueabihf-objcopy-O binary-S-g led.elf led.bin
- 反汇编
- arm-linux-gnueabihf-objdump-D led.elf > led.dis
4.烧写程序
- 拷贝imxdownload文件到Ubuntu与.bin文件同一路径下
- chmod加上可执行权限 -x
- 电脑上插入SD卡,用ls /dev/sd*指令查看有哪些存储设备
- 使用命令./imxdownload led.bin /dev/sdb,把led.bin文件烧写到sd卡里
- 烧写完成以后会在当前工程目录下生成一个 load.imx 的文件,即为烧录到SD卡中的文件
5.运行程序
将SD卡插入开发板,设置拨码开关为 SD卡启动,拨码开关设置如图:

连接电源,按下电源开关键,即LED灯亮(红灯)