嵌入式 - ARM4

发布于:2025-09-12 ⋅ 阅读:(20) ⋅ 点赞:(0)

裸机实现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)

    // 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

2. 将引脚功能从默认模式切换为GPIO
        模式GPIO_IO03 gpio1模式代码为 0101 = 0x05

3. str指令将配置写回寄存器
        将 r1 存放的内容存放在 r0 存放的地址内
        即将0x05 模式存放在控制寄存器的地址,实现引脚初始化

2.​ ​电气特性配置

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

GPIO引脚初始化

        手册C32 - IOMUXV Memory Map... - IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 p1793
        引脚的​​电气特性​(PAD),滞回器、上拉/下拉电阻、开漏/推挽输出

    // 引脚电气特性配置
    // 手册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

2. 配置电气参数(驱动强度、压摆率、上下拉、开漏/推挽)
        配置为0x10B0 = 0001 0000 1011 0000
        对应部分参数为:12位  :    1:使能上拉
                                     7-6位:  10:中速100MHZ
                                     5-3位:110:中等驱动强度        ......

3. str指令将配置写回寄存器
        将 r1 存放的内容存放在 r0 存放的地址内
        即将0x10B0 模式存放在PAD寄存器的地址,实现电气配置

3. ​方向配置

        将引脚设置为输出模式
        手册C28(外设) - GPIOx - GDIR

    // 引脚方向
    // 手册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 

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

3. 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


网站公告

今日签到

点亮在社区的每一天
去签到