【Linux 裸机篇(二)】I.MX6ULL 汇编 LED 驱动

目录

  • 一、LED 汇编驱动
  • 二、编译代码
    • 1. 编译
    • 2. 链接文件
    • 3. 格式转换
    • 4. 反汇编
  • 三、编写 Makefile
  • 四、代码烧写(SD卡)
    • 1. imxdownload 工具
    • 2. SD 卡
    • 3. 烧写 bin 文件

一、LED 汇编驱动

采用 GPIO1_IO03 进行 LED 点灯,流程如下:

  1. 使能 GPIO1 时钟
    GPIO1 的时钟由 CCM_CCGR1 的 bit27 和 bit26 这两个位控制,将这两个位都设置位 11 即
    可(实验中将 I.MX6ULL 所有外设时钟都打开)。
  2. 设置 GPIO1_IO03 的复用功能
    找到 GPIO1_IO03 的复用寄存器“IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03”的地址为0X020E0068,然后设置此寄存器,将 GPIO1_IO03 这个 IO 复用为 GPIO 功能,也就是 ALT5。
  3. 配置 GPIO1_IO03 的电气属性
    找到 GPIO1_IO03 的配置寄存器“IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03”的地址为0X020E02F4,根据实际使用情况,配置此寄存器。
  4. 配置 GPIO1_IO03 为输出模式
    GPIO1_GDIR 的 bit3 要设置为 1,表示输出。
  5. 控制 GPIO1_IO03 的输出电平
    向 GPIO1_DR 寄存器的 bit3 写入 0 即可控制 GPIO1_IO03 输出低电平,打开 LED。
.global _start @全局标记

_start:
    /* 使能所有外设时钟 */
    ldr r0, =0x020c4068   //CCGR0 寄存器地址
    ldr r1, =0xffffffff   //要向CCGR0写入的数据
    str r1, [r0]          //将0xffffffff写入到CCGR0寄存器中

    ldr r0, =0x020c406c   //CCGR1 寄存器地址
    str r1, [r0]          //将0xffffffff写入到CCGR1寄存器中

    ldr r0, =0x020c4070   //CCGR2 寄存器地址
    str r1, [r0]          //将0xffffffff写入到CCGR2寄存器中

    ldr r0, =0x020c4074   //CCGR3 寄存器地址
    str r1, [r0]          //将0xffffffff写入到CCGR3寄存器中

    ldr r0, =0x020c4078   //CCGR4 寄存器地址
    str r1, [r0]          //将0xffffffff写入到CCGR3寄存器中

    ldr r0, =0x020c407c   //CCGR5 寄存器地址
    str r1, [r0]          //将0xffffffff写入到CCGR3寄存器中

    ldr r0, =0x020c4080   //CCGR5 寄存器地址
    str r1, [r0]          //将0xffffffff写入到CCGR3寄存器中


    /* 配置GPIO1——IO03的引脚复用为GPIO
     * 寄存器:IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
     * 寄存器地址:0X020E0068 
     * 写入值:0x5
     */
    ldr r0, =0x020E0068   //IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器地址
    ldr r1, =0x5          //要写入的数据
    str r1, [r0]          //将0x5写入寄存器中


    /* 配置GPIO1_IO03的电气属性
     * 寄存器:IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
     * 寄存器地址:0x020e02f4
     * bit0:        0低速率
     * bit2:1:      00
     * bit5:3:      110 R0/6驱动能力
     * bit7:6:      10 100MHz速度
     * bit11:       0 关闭开路输出
     * bit12:       1 使能pull/kepper
     * bit13:       0 kepper
     * bit15:14     00 100K下拉
     * bit16:       0 关闭HYS
     × 写入值:0x10b0
     */
     ldr r0, =0x020e02f4
     ldr r1, =0x10b0
     str r1, [r0]

    /*配置GPIO1_IO03为输出模式
     *寄存器:GPIO1_GDIR
     *寄存器地址:0x0209c004
     *写入值:0x8
     */
     ldr r0, =0x0209c004
     ldr r1, =0x8
     str r1, [r0]

    /*配置GPIO1_IO03输出为0 (点亮LED)
     *寄存器:GPIO_DR
     *寄存器地址:0x0209c000
     */
     ldr r0, =0x0209c000
     ldr r1, =0
     str r1, [r0]

loop:
    b loop

二、编译代码

使用 arm-linux-gnueabihf-gcc 工具进行编译


1. 编译

将 led.s 编译为对应的 .o 文件

arm-linux-gnueabihf-gcc -g -c led.s -o led.o

-g:产生调试信息
-c:编译源文件,但是不链接
-o:指定编译产生的文件名字


2. 链接文件

将众多的 .o 文件链接到一个指定的链接位置,本实验链接地址为:0X87800000

arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf

-Ttext:指定链接地址
-o:指定链接生成的 elf 文件名,命名为 led.elf


3. 格式转换

将 .elf 文件转换为 .bin 文件

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

-O:指定以什么格式输出,“ binary”表示以二进制格式输出
-S:不要复制源文件中的重定位信息和符号信息
-g:不复制源文件中的调试信息


4. 反汇编

有时候需要查看其汇编代码来调试代码,因此就需要进行反汇编,一般可以将 elf 文件反汇编

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

-D:表示反汇编所有的段


三、编写 Makefile

led.bin:led.s
	arm-linux-gnueabihf-gcc -g -c led.s -o led.o
	arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
	arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
	arm-linux-gnueabihf-objdump -D led.elf > led.dis

clean:
	rm -rf *.o led.bin led.elf led.dis

四、代码烧写(SD卡)

1. imxdownload 工具

将 imxdownload 拷贝至 bin 文件同目录下,再给予 imxdownload 可执行权限:chmod 777 imxdownload


2. SD 卡

需将 SD 卡以 FAT32 格式格式化,SD 卡存储在 /dev 目录下,快速查看:ls /dev/sd*


3. 烧写 bin 文件

使用 imxdownload 工具向 SD 卡烧写 led.bin 文件,工具会在 bin 文件前面添加一些数据头生成 load.imx 文件,最终将 load.imx 文件烧入 SD 卡中

./imxdownload led.bin /dev/sdb1

你可能感兴趣的:(linux,汇编)