IMX6ULL裸机学习(4)— 编写汇编程序点亮LED

IMX6ULL裸机学习(4)— 编写汇编程序点亮LED

一、编写程序

新建一个led.S文件,然后编写如下代码。


.global  _start         /* .global表示_start是一个全局符号 */

_start:                 /* 标签_start,汇编程序的默认入口是_start */
    /* 1、设置 GPIO1_IO03 复用为 GPIO1_IO03 */
    LDR R0, = 0X020E0068 /* 将GPIO1_IO03复用模式寄存器的值写入R0 */
    LDR R1, [R0]        /* 读取该寄存器的值 */      
    ORR R1, R1, #0X05   /* 修改读出的值 */
    STR R1, [R0]        /* 写入修改后的值到该寄存器 */

    /* 2、把GPIO1_IO03设置为输出引脚 */
    LDR R0, = 0X0209C004
    LDR R1, [R0]
    ORR R1, R1, #(1<<3)
    STR R1, [R0]

    /* 3、设置GPIO1_IO03输出低电平 */
    LDR R0, = 0X0209C000
    LDR R1, [R0]
    BIC R1, R1, #(1<<3)
    STR R1, [R0]

    /* 4、loop死循环 */
loop:
    b loop

二、生成二进制文件

使用如下命令对led.S只编译不连接,其中-c参数表示只编译不链接,-o参数指定生成的文件名

arm-linux-gnueabihf-gcc led.S -c -o led.o

我们可以看到得到了led.o文件
在这里插入图片描述
然后使用命令对得到的led.o文件进行链接,其中-Ttext参数指定text段即代码段的链接地址为0X80100000

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

可以看到得到了led.elf文件,但是led.elf文件也不是我们最终需要的可供imx6ull芯片可执行的文件
在这里插入图片描述
因此需要将 led.elf 文件转换为.bin 文件,使用到 arm-linux-gnueabihf-objcopy 工具得到,-O参数指定以什么格式输出,后面的binary表示以二进制格式输出,-S表示不要复制源文件中的重定位信息和符号信息,-g表示不复制源文件中的调试信息。

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

可以看到得到了led.bin文件,这就是我们要得到的文件
在这里插入图片描述
另外我们可以使用arm-linux-gnueabihf-objdump 来将 elf 文件反汇编,-D选项表示反汇编所有的段,

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

完成以后就会在当前目录下得到 led.dis 文件,
在这里插入图片描述
然后我们可以打开led.dis来看一下,可以看到,在0X80100000 处就是全局标号_start,也就是程序开始的地方,也可以代码已经链接到了以 0X80100000 为起始地址的区域。
在这里插入图片描述
然后我们可以通过通过编写一个makefile来完成上述的操作


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

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

另外可以在编译时加上-g选项产生调试信息

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

然后我们可以看到在反汇编文件中得到多出来了调试信息
在这里插入图片描述
同时可以看到led.o的大小也改变了
在这里插入图片描述
但是led.bin的大小可以看到没有改变,还是64个字节
在这里插入图片描述
而从反汇编文件中我们就可以看到这64字节就是存放着从80100000到8010003c这64个地址的内容
在这里插入图片描述
我们可以通过能查看二进制文件的软件来查看一下led.bin,可以看到和反汇编文件中的内容一样
在这里插入图片描述

三、生成镜像文件

虽然我们已经得到了二进制文件,但是要得到可以烧写到SD卡的镜像文件还需要添加一些头部信息,包括三部分,如下所示为一个完整的镜像文件,其中我们的led.bin文件该存放的位置就为【User code and data】
在这里插入图片描述
然后我们使用mkimage工具来给bin文件添加一个头部信息。其中-T参数表示要生成的镜像类为imximage,然后-n参数在帮助上是说是镜像名字,但是在imximage镜像类型下是用来指定配置文件的,imximage.cfg.cfgtmp配置文件有NXP官方提供,-e参数表示入口地址,-d参数指定制作镜像的源文件,即【User code and data】位置存放的东西。

mkimage -T imximage -n ./tools/imximage.cfg.cfgtmp -e 0x80100000 -d led.bin led.imx

这样就得到了一个led.imx文件,但这还不是我们可以烧录到SD卡中的文件
在这里插入图片描述
我们还需要让led.imx偏移1K字节,在其前面写入1K字节的空数据,首先使用命令得到1K空字节的文件。dd命令是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。首先if=/dev/zero表示输入文件为/dev/zero

/dev/zero,是一个输入设备,你可你用它来初始化文件。该设备无穷尽地提供0,可以使用任何你需要的数目(设备提供的要多的多)。他可以用于向设备或文件写入字符串0。

of=1k.bin表示输出的文件为1k.binbs=1024表示同时设置读入/输出的块大小为1024个字节。 count=1表示拷贝1个块,块大小等于bs指定的字节数1024。

dd if=/dev/zero of=1k.bin bs=1024 count=1

得到1K.bin文件后在使用cat命令将其与led.imx合并为led.img文件

cat 1k.bin led.imx > led.img

可以看到,成功得到led.img文件
在这里插入图片描述

四、烧录到SD卡启动

接下来我们用Win32 磁盘映像工具来将镜像烧录到SD卡
在这里插入图片描述
然后我们设置开发板为从SD卡启动,并上电,可以看到,LED已经成功点亮
在这里插入图片描述

五、验证程序

我们修改程序,将LED引脚设置为高电平
在这里插入图片描述
重新编译链接,制作镜像文件加载到开发板中
在这里插入图片描述
可以看到,红色LED灯不再亮起了
在这里插入图片描述

六、使用USB烧录程序

使用100ask提供的烧写工具,下载方式

git clone https://e.coding.net/weidongshan/noos/doc_and_source_for_mcu_mpu.git

在目录【IMX6ULL\开发板配套资料\软件\烧写工具\100ask_imx6ull烧写工具v4】下找到【100ask_imx6ull_flashing_tool_v4.0.exe】文件,双击打开,然后点击【专业版】
在这里插入图片描述
接着将开发板启动方式设置为USB启动,上电,注意不要插SD卡,然后可以看到,提示设备已连接
在这里插入图片描述

1、烧写到DDR

接着我们点击【固件/裸机】按钮,选择我们生成的【led.imx】文件
在这里插入图片描述
然后点击【运行】,可以看到,烧写成功,开发板上的LED也成功亮起
在这里插入图片描述

2、烧写到EMMC

将开发板启动方式设置为USB启动,注意不要插SD卡,上电,然后我们选择设备为EMMC,然后点击【Boot/裸机】按钮,选择我们生成的【led.imx】文件,然后点击【烧写Boot/裸机】,可以看到,烧写成功
在这里插入图片描述
然后将设备设置为从EMMC启动,重新上电,可以看到LED亮起
在这里插入图片描述

3、烧写到SD卡

将开发板启动方式设置为USB启动,注意不要插SD卡,上电,上电后再插入SD卡,然后我们选择设备为SD/TF,然后点击【Boot/裸机】按钮,选择我们生成的【led.imx】文件,然后点击【烧写Boot/裸机】,可以看到,烧写成功
在这里插入图片描述

然后将设备设置为从SD启动,重新上电,可以看到LED亮起
在这里插入图片描述

七、附录

上一篇:IMX6ULL裸机学习(3)— 在Windows下搭建开发环境
下一篇:IMX6ULL裸机学习(5)— 编写C语言程序点亮LED

猜你喜欢

转载自blog.csdn.net/qq_38113006/article/details/111145051