硬件开发2-ARM裸机开发1-IMX6ULL - 汇编点灯

发布于:2025-09-13 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、概念概要

1、LED原理图

2、内核中对应的引脚 — GPIO

(1)概念

GPIO(通用输入/输出)详解
        GPlO(General-PurposeInput/Output)是嵌入式系统和微控制器中最基本的外设接口,用于
实现数字信号的输入和输出控制。它通过软件配置引脚功能,灵活连接外部设备,如传感器、LE
D、按键等。

        以默认功能命名规则 ->复用功能,使用前要明白引脚最初默认引脚

(2)GPIO 3控制器的起始地址 

3、 IOMUX6ULL 引脚功能复用原理

        类似于单刀多掷开关,(内部控制寄存器)实现多路复用开关,单刀多掷开关一般在多路复用时,默认一次仅连接一个功能通道,其他通道处于断开状态

原理类似图

                控制led灯一般在推挽模式,对于复杂SOC,对于一个引脚,需要进行交叉复用功能设置,对于一个引脚。可能有多种功能,同一时刻只能使用一种,需要提前配置。

4、引脚电器配置

5、GPIO 参考手册

使用时:GPIOx : x是几,使用时就将几号bit位置1

例如:GPIO3 ->    orr  r1, r1, #(1 << 3)

  • 数据相关:
    • GPIOx_DR:数据寄存器,直接读写引脚电平状态
      • 当引脚作为输出时,向对应的位写1使引脚为高电平,写0引脚为低电平
      • 当引脚作为输入时,读取到1表示引脚为高电平,读取到0表示引脚低电平
    • GPIOx_PSR:引脚状态寄存器,实时读取物理引脚电平(可能与DR存在差异)
  • 方向控制:
    • GPIOx_GDIR:方向寄存器,设置引脚为输入/输出模式(1=输出,0=输入)
  • 中断控制:
    • GPIOx_IMR:中断屏蔽,决定哪些引脚中断有效
    • GPIOx_ISR:中断状态,标志哪些引脚触发了中断
    • GPIOx_ICR1/ICR2:中断清除,写1清除对应位的中断标志
    • GPIOx_EDGE_SEL:边沿选择,配置中断触发条件(上升/下降/双边沿)

6、IO复用功能 目标寄存器的地址

7、引脚电器配置

8、引脚方向

9、延时设置

led_delay:

    ldr r0, = 0x7FFFF

loop:

    sub r0, r0, #1

    cmp r0, #0

    bgt loop

    bx lr

二、基本流程

1、代码书写

.global _start 

_start:    

     //异常向量表
    ldr pc, = _start_handler
    ldr pc, = _undefined_handler
    ldr pc, = _supervisor_handler
    ldr pc, = _prefetch_handler
    ldr pc, = _data_handler
    ldr pc, = _notused_handler
    ldr pc, = _irq_handler
    ldr pc, = _fiq_handler

_undefined_handler:
    b _undefined_handler

_supervisor_handler:
    b _supervisor_handler

_prefetch_handler:
    b _prefetch_handler

_data_handler:
    b _data_handler

_notused_handler:
    b _notused_handler

_irq_handler:
    b _irq_handler
_fiq_handler:
    b _fiq_handler

_start_handler:

  //古老的方法
/* 
    //进入irq
    mrs r0, cpsr
    bic r0, r0, #(0x1F << 0)
    bic r0, r0, #(1 << 7)
    orr r0, r0, #(0x12 << 0)    //irq
    msr cpsr, r0 
    ldr sp, = 0x82000000

    //进入irq
    mrs r0, cpsr
    orr r0, r0, #(0x1F << 0)    //sys
    msr cpsr, r0
    ldr sp, = 0x84000000
*/

   //新方法
    cpsid i     //关闭软中断,保证模式转换过程中不被打断

    cps #0x12
    ldr sp, = 0x82000000

    cps #0x1F
    ldr sp, = 0x84000000

    cpsie i      //开启软中断

//调用部分

    bl led_init
    b finish

finish:


    bl led_on
    bl led_delay

    bl led_off
    bl led_delay

    b finish

//led初始化

led_init:


    //IO复用功能配置
    ldr r0, = 0x020E0068     
    ldr r1, = 0x05
    str r1, [r0]            //将r1的内容写入r0地址

    //引脚电器配置
    ldr r0, = 0x020E02F4   
    ldr r1, = 0x10B0
    str r1, [r0]

    //引脚方向
    ldr r0, = 0x0209C004    //写
    ldr r1, [r0]            //读
    orr r1, r1, #(1 << 3)
    str r1, [r0]

    bx lr

led_on:
    ldr r0, = 0x0209C000
    ldr r1, [r0]
    bic r1, r1, #(1 << 3)
    str r1, [r0]
    bx lr

led_off:
    ldr r0, = 0x0209C000
    ldr r1, [r0]
    orr r1, r1, #(1 << 3)
    str r1, [r0]
    bx lr

//延时设置

led_delay:
    ldr r0, = 0x7FFFF
loop:
    sub r0, r0, #1
    cmp r0, #0
    bgt loop
    bx lr

2、编译

(1)汇编(.S → .o)

将汇编代码转为目标文件

arm-linux-gnueabihf-gcc -c start.S -o start.o -g            //-c 只汇编不链接,-g 保留调试信息

(2)链接(.o → .elf)

将目标文件链接到指定地址(i.MX6ULL 从 SD 卡启动时,代码加载地址为 0x87800000)

arm-linux-gnueabihf-ld -Ttext 0x87800000 start.o -o start.elf      //-Ttext 指定代码段起始地址

(3)格式转换(.elf → .bin)

ELF 文件包含调试信息,需转为纯二进制文件(开发板才能识别)

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

//-O binary 指定输出格式,-S/-g 去除符号/调试信息

(4)反汇编(.elf → .dis)

将 ELF 文件转为汇编代码(可选)

arm-linux-gnueabihf-objdump -D start.elf > start.dis                  // -D 反汇编所有段

3、烧录

(1)连接SD卡到Ubuntu

(2)拷贝下载工具imxdownload到Ubuntu工程目录下

(3)修改权限:改为可执行文件

                chmod +777 imxdownload

(4)烧写程序到SD卡

                        ./imxdownload start.bin /dev/sdb

注:注意烧写速率,如果上M的速度是不成功的,必须拔掉USB读卡器,重启Ubuntu

如下:

makefile

COPLITE=arm-linux-gnueabihf-
CC=$(COPLITE)gcc
LD=$(COPLITE)ld
OBJCOPY=$(COPLITE)objcopy
OBJDUMP=$(COPLITE)objdump
TAGRET=start

$(TAGRET).bin:$(TAGRET).S
    $(CC) -c -g $(TAGRET).S -o $(TAGRET).o
    $(LD) -Ttext 0x87800000 $(TAGRET).o -o $(TAGRET).elf
    $(OBJCOPY) -O binary -S -g $(TAGRET).elf $(TAGRET).bin
    $(OBJDUMP) -D $(TAGRET).elf > $(TAGRET).dis

clean:
    rm $(TAGRET).o $(TAGRET).elf $(TAGRET).bin $(TAGRET).dis -f


load:
    ./imxdownload $(TAGRET).bin /dev/sdb

4、测试

(1)将BOOT按照MicroSD进行操作

        将sd卡插入IMAXULL板子上,开启电源

(图中忘记扶上去)