[TOC]

Linux驱动开发:I.MX6U 程序编译下载(SD卡)

一、硬件平台:

正点原子I.MX6U阿尔法开发板

_533488159_IMG_20210803_235508_1628006109000_xg_0

二、编译程序

2.1 交叉编译工具链安装

在编写完程序之后,对程序进行交叉编译,在电脑上的Ubuntu下使用交叉编译工具链编译I.MX6u平台的可执行代码

交叉编译:交叉编译是在一个平台上生成另一个平台上的可执行代码,同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行 —来源百度

交叉编译前先安装交叉编译工具链(已经安装可以跳过),在编译器下载网页选择64位的压缩包(根据自己的电脑选择),复制下载链接

20210803220354

在Linux下使用wget下载工具链

1
wget + 下载地址

20210803220528

下载完成后,在目录/usr/local 本地系统管理员软件安装目录下创建工具链目录,指令如下:

/usr/local :本地系统管理员软件安装目录,主要安装系统级的应用,这是最庞大的目录,要用到的应用程序和文件几乎都在这个目录!

1
sudo mkdir /usr/local/arm #创建ARM目录

创建完成后将压缩包复制进去

1
sudo cp gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz /usr/local/arm/ -f

复制完成后进入/usr/local/arm目录解压压缩包

1
2
cd /usr/local/arm
sudo tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz

解压后就会有一个 gcc-linaro-4.9.4-2017.01-x86_64_arm-linuxgnueabihf 文件夹

20210803221437

然后打开系统环境变量文件(/etc/profile文件),在其中添加交叉编译器环境到系统环境中

1
sudo vim /etc/profile

在末尾添加如下调用声明

1
export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin

20210803222438

然后安装其它的链接库,命令如下:

1
sudo apt-get install lsb-core lib32stdc++6

查看交叉编译器链接版本号,确定是否安装了工具

1
arm-linux-gnueabihf-gcc -v

显示如下则表示交叉工具链安装完成

20210803222605

2.2 编译源程序

编译源程序有两个方法,一个是一个指令一个指令慢慢敲,一个是编写Makefile文件自动化构建

2.2.1 手敲指令法

有了交叉编译工具链之后,要对源程序进行编译,这里以led.s汇编点灯源程序为例子,使用 arm-linux-gnueabihf-gcc 指令编译:

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

其中 -g 选项是产生调试信息,GDB 能够使用这些 调试信息进行代码调试; -c 选项是编译源文件,但是不链接; -o 选项是指定编译产生的文 件名字,该指令生成 led.o文件,工程中所有的 C 文件和汇编文件都会编译生成一个对应的.o 文件,我们需要将这.o 文件链接起来组合成可执行文件

20210803223747

因为我们通过将程序烧写到SD卡,然后boot rom程序将可执行文件拷贝到链接地址处,此处链接地址为为 0X87800000,因为Linux通过Uboot进行启动,其后面的地址为0X87800000,使用如下命令将.o文件链接成为.elf文件

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

20210803225815

当然.elf文件并不是我们最终要烧写的文件,我们需要把他转化为.bin二进制文件,转化命令如下:

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

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

20210803230244

对于链接好的.elf文件,我们有时需要使用反汇编指令,查看其汇编代码,进行调试

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

执行指令后会生成一个.dis文件,打开后会显示程序详细汇编代码,包括指令地址等等

20210803230748

2.2.2 使用Makefile工具

编写Makefile文件实现快速编译,先使用touch创建一个makefile文件

Makefile语法参考入门篇文章Makefile篇: Linux驱动开发系列:2W字长文整理入门Ubuntu知识

1
touch Makefile #名称要相同

输入如下代码:

1
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.disclean:	rm -rf *.o led.bin led.elf led.dis

Makefile文件写好后,就可以直接在命令行使用构建指令了:

1
make #编译make clean #清除指定的文件

使用效果如下:

20210803232937

到此两个编译的方式就结束了

三、程序下载

NXP的 I.MX6U 内部有 96K 的 ROM,但是这 96K 的 ROM 不向用户开放, I.MX6U 相当于内部没有可用 flash ,为此,I.MX6U 支持从外置的 NOR Flash、NAND Flash、SD/EMMC、SPI NOR Flash 和 QSPI Flash 这些存储介质中启动,所以我们可以将代码烧写到这些存储介质中,本节我们下载到SD卡内

3.1 imxdownload配置

  • 将 imxdownload 拷贝到工程根目录下,和 led.bin 处于同一个文件夹下

20210803233904

  • 改变 imxdownload 为可执行权限
1
sudo chmod 777 imxdownload

20210803234141

  • 挂载目标SD卡

挂载SD卡的步骤可以参考我之前的文章: Linux驱动开发系列:2W字长文整理入门Ubuntu知识

  • imxdownload下载

使用 imxdownload 向 SD 卡烧写 led.bin 文件,下载格式为

1
./imxdownload bin文件 SD卡设备

本例子中代码为:

1
./imxdownload led.bin /dev/sdb1

下载完成结果:

20210803234723

其中3232 byte是烧写的大小,0.0264532s是下载时长,122kb/s是下载速度

3.2 代码上板测试

程序已经下载到SD上了,下一步我们把SD卡插到开发板上,然后将BOOT开关调节成为如下图(左下角拨码开关调节为SD卡启动),上电后程序LED0被点亮

_-1101144011_IMG_20210803_235355_1628006036000_xg

wechat