嵌入式 - ARM4

裸机实现LED闪烁

一、启动代码

1. 异常向量表配置

1. .global

汇编器指令,全局定义标签_start,作为汇编程序的默认起点

2. 配置标签

配置标签时可以前置加_ ,以便和普通标签或系统标签做区分

3. 异常向量表

ARM架构规定异常向量表位置固定,配置对应位置的异常向量

2. start函数

1. 操作CPSR寄存器 搭建运行环境

1. 配置irq模式

用于处理中断,确保各个部分的独立性

1. mrs 指令使cpsr寄存器 备份到r0中

2 . 修改模式为irq模式

先通过bic指令对后五位清零,便于后续修改模式

手册Label - ARM processor 查询模式代码,通过orr指令进行修改配置

3 . 打开终端I位

通过bic指令对第 I 位置1,打开中断,确保程序能响应中断

注:整个程序中断只用配置一次,后续修改 sys 模式时不用再次配置

**4.**msr指令将 r0 值 返回置 cpsr ,确保模式转换

2. 配置sys模式

可以使C语言执行,空间大

1. mrs 指令使cpsr寄存器 备份到r0中

2 . 修改模式为sys模式

sys模式代码为11111,可以省略清零准备步骤

3. 不用再次配置中断响应

**4.**msr指令将 r0 值 返回置 cpsr ,确保模式转换

2. CPS指令 搭建运行环境

1. 关闭中断

防止初始化过程被中断打断,确保原子操作

2. cps

手册376 CPS指令专用操作cpsr寄存器

配置中断: CPS<effect> <iflags>{, #<mode>}

配置模式: CPS #<mode>

CPS用于ARMv6v7架构,keil默认目标为ARMv5架构无法编译通过,可以使用操作CPSR寄存器的方式

3.分配空间

硬件ROM(加载域)的起始物理地址为0x8000 0000

为 irq 模式0x12分配 32M = 32 * 1024 * 1024 = 0200 0000 大小的空间,即0x8200 0000

为 sys 模式0x1F再分配 32M大小的空间,即 0x8400 0000

3. 开启实现目的程序

二、LED灯配置

1. led_init

1.​​ 功能复用配置

GPIO引脚初始化

手册C32 - IOMUXV Memory Map... - IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 p1571

引脚的功能复用(MUX)

cpp 复制代码
    // IO复用功能配置
    // 手册C32 - IOMUXV Memory Map... 
    // - IOMUXV Memory Map... - IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 p1571
    ldr r0, =0x020E0068
    ldr r1, =0x05                   // 0101 ALT5-GPIO1_IO03
    str r1, [r0]     
  1. 加载IOMUX控制寄存器地址

Address:20E_0000h base + 68h offset = 0x20E 0068

  1. 将引脚功能从默认模式切换为GPIO

模式GPIO_IO03 gpio1模式代码为 0101 = 0x05

  1. str指令将配置写回寄存器

将 r1 存放的内容存放在 r0 存放的地址内

即将0x05 模式存放在控制寄存器的地址,实现引脚初始化

2.​ ​电气特性配置

设置引脚的驱动能力、上下拉等电气参数

GPIO引脚初始化

手册C32 - IOMUXV Memory Map... - IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 p1793

引脚的​​电气特性​(PAD),滞回器、上拉/下拉电阻、开漏/推挽输出

cpp 复制代码
    // 引脚电气特性配置
    // 手册C32 - IOMUXV Memory Map... 
    // - IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 p1793
    ldr r0, =0x020E02F4
    ldr r1, =0x10B0                 
    str r1, [r0]      
  1. 加载PAD控制寄存器地址

Address:20E_0000h base + 2F4h offset = 0x20E 02F4

  1. 配置电气参数(驱动强度、压摆率、上下拉、开漏/推挽)

配置为0x10B0 = 0001 0000 1011 0000

对应部分参数为:12位 : 1:使能上拉

7-6位: 10:中速100MHZ

5-3位:110:中等驱动强度 ......

  1. str指令将配置写回寄存器

将 r1 存放的内容存放在 r0 存放的地址内

即将0x10B0 模式存放在PAD寄存器的地址,实现电气配置

3. ​ 方向配置

将引脚设置为输出模式

手册C28(外设) - GPIOx - GDIR

cpp 复制代码
    // 引脚方向
    // 手册C28(外设) - GPIOx - GDIR
    ldr r0, =0x0209C004             
    ldr r1, [r0] 
    orr r1, r1, #(1 << 3)
    str r1, [r0]  
  1. 加载GPIO1的GDIR(方向控制寄存器)地址

Address:Base address + 4h offset

  1. 设置输出模式

将GPIO_IO03设为输出,即通过orr指令将第三位置1

  1. str指令将配置写回寄存器

将 r1 存放的内容存放在 r0 存放的地址内

即将结果返回寄存器地址,实现配置输出模式

2. led_on

手册C28(外设) - GPIOx - DR

通过bic指令将GPIO_IO03位清零,通过硬件电气特征,此时LED点亮

3. led_off

通过orr指令将GPIO_IO03位置1,通过硬件电气特征,此时LED熄灭

4. led_delay

通过执行一个​​空循环 ​消耗CPU时间,实现​ 软件延时​​

三、编译与测试

1. 编译步骤

1. arm-linux-gnueabihf-gcc 只汇编不链接

arm-linux-gnueabihf-gcc -c start.S -o start.o -g

-o 只编译不链接

-g 保留编译信息

2. arm-linux-gnueabihf-ld 链接代码到特定地址

(得到可执行,可连接程序 linux executable linkable file)

arm-linux-gnueabihf-ld -Ttext 0x87800000 start.o -o start.elf

Ttext 指定代码段加载地址

-o 输出ELF格式可执行文件

3. arm-linux-gnueabihf-objcopy 格式转换

arm-linux-gnueabihf-objcopy -O binary -S -g start.elf start.bin

-O binary 输出二进制格式

-S 去除符号表

-g 去除调试信息

4. arm-linux-gnueabihf-objdump 反汇编(可省略)

arm-linux-gnueabihf-objdump -D start.elf > start.dis

-D 反汇编所有段

5. imxdownload 烧写程序到SD卡

./imxdownload start.bin /dev/sdb

插入SD卡后选择连接到虚拟机Ubuntu

使用 chmod +777 imxdownload 命令赋予 imxdownload 权限

通过 ls/imxdownload /dev/sdb 命令查看dev

刚插入SD卡就执行命令可能会出错,现象为少烧写速率以M为单位,此时需要重启虚拟机

6. 将SD卡插入板子观察现象

注:

修改板子工作模式为SD模式

插入SD卡时不要上电

BOOT工作模式:

2. Makefile

相关推荐
Stone.Wu5 天前
快速理解ARM Cortex-M流水线:指令执行过程通俗解释
arm
我在人间贩卖青春6 天前
汇编之分支跳转指令
汇编·arm·分支跳转
我在人间贩卖青春6 天前
汇编之加载存储指令
汇编·arm·寄存器加载存储
我在人间贩卖青春6 天前
汇编之状态寄存器访问指令
汇编·arm·状态寄存器
我在人间贩卖青春6 天前
汇编之软中断指令和协处理指令
汇编·arm·软中断·协处理
我在人间贩卖青春6 天前
汇编之数据处理指令
汇编·arm·数据处理指令
fly的fly9 天前
浅析 QT远程部署及debug方案
qt·物联网·arm
切糕师学AI11 天前
ARM标准汇编(armasm)中的标号(Label)
汇编·arm
CHENG-JustDoIt12 天前
嵌入式开发 | ARM Cortex-M 系列中M3、M4、M23 和 M33四款处理器的深度对比分析
arm开发·单片机·嵌入式硬件·arm
toradexsh19 天前
在NXP iMX8QM上使用 Jailhouse
arm·nxp·toradex·imx8mp·jailhouse