嵌入式 - 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

相关推荐
Janspran1 天前
嵌入式 - ARM1
arm
武文斌772 天前
ARM工作模式、汇编学习
汇编·嵌入式硬件·学习·arm
christine-rr4 天前
CPU架构的演进:从冯·诺依曼到未来计算
架构·arm·cpu
大聪明-PLUS5 天前
像 Docker 一样创建虚拟网络
linux·嵌入式·arm·smarc
jzzy_hony6 天前
移植Qt4.8.7到ARM40-A5
qt·ubuntu·arm·终端
漫步企鹅1 个月前
【VS Code - Qt】如何基于Docker Linux配置Windows10下的VS Code,开发调试ARM 版的Qt应用程序?
linux·qt·docker·arm·vs code·开发调试
普中科技1 个月前
【普中STM32精灵开发攻略】--第 11 章 SysTick系统定时器
stm32·单片机·嵌入式硬件·物联网·arm·普中科技
普中科技1 个月前
【普中STM32精灵开发攻略】--第 10 章 STM32位带操作
stm32·单片机·嵌入式硬件·物联网·arm·普中科技·位带操作
普中科技1 个月前
【普中STM32精灵开发攻略】--第 7 章 库函数模板创建
stm32·单片机·嵌入式硬件·物联网·arm·普中科技