资讯详情

嵌入式Linux驱动开发笔记(五)

嵌入式Linux驱动开发笔记(5)

五、汇编 LED 灯实验

(1)I.MX6U GPIO 详解

I.MX6ULL 的 IO 分为两类: SNVS 域和通用 IO 本质上是一样的。

以常用 IO 例如,形如IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00”的就是 GPIO 命名形式为命名IOMUXC_SW_MUC_CTL_PAD_XX_XX后面的XX_XX”就是 GPIO 命名, 比如: GPIO1_IO01、 UART1_TX_DATA、 JTAG_MOD 等等 ,他是基于某个 IO 所拥有的功能来命名的

I.MX6U 的 GPIO 不止 GPIO1_IO00~GPIO1_IO09 这 10 个,其它的 IO 可复用 GPIO 来使用。 I.MX6U 的 GPIO 一共有 5 组: GPIO1、 GPIO2、 GPIO3、 GPIO4 和 GPIO5,其中 GPIO1 有 32 个 IO, GPIO2 有 22 个 IO, GPIO3 有 29 个 IO、 GPIO4 有 29 个 IO, GPIO5最少,只有 12 个 IO,这样一共有 124 个 GPIO。假如只想看每一个 IO 如果可以复用什么外设,可以直接查阅《IMX6ULL 参考手册第一 4 章“Chapter 4 External Signals and Pin Multiplexing”。假如只想看每一个 IO 如果可以复用什么外设,可以直接查阅《IMX6ULL 参考手册第一 4 章“Chapter 4 External Signals and Pin Multiplexing如果我们想编写代码,设置代码 IO 如果复用功能需要查阅第一个 32 章“Chapter 32: IOMUX Controller(IOMUXC)” ,第 32 所有的章节都详细列出了 IO 相应的复用配置寄存器。

I.MX6U 的 IO 和 STM如果某一个是一样的 IO 作为外设引脚使用, 复用寄存器需要配置。

寄存器 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 是用来配置 GPIO1_IO00 包括速度设置、驱动能力设置、压摆率设置等。

GPIO 是一个 IO 许多复用功能之一。比如 GPIO1_IO00 这个 IO 可复用为: I2C2_SCL、 GPT1_CAPTURE1、 ANATOP_OTG1_ID、ENET1_REF_CLK 、 MQS_RIGHT 、 GPIO1_IO00 、 ENET1_1588_EVENT0_IN 、SRC_SYSTEM_RESET 和 WDOG3_WDOG_B 这 9 个功能, GPIO1_IO00 就是其中之一,我们想把它拿走 GPIO1_IO00 任何外设都可以复用。

I.MX6U 的 IO 需要配置和输出,可以设置输出高低电平,也可以读取 GPIO 相应的电平。

I.MX6U 要使用外设,必须首先使用相应的时钟 ,每个外设时钟都可以独立使用或禁止,从而关闭未使用的外设时钟,以节省电力。

(2)编译下载验证

【1】arm-linux-gnueabihf-gcc 编译文件

我们要编译 ARM 在开发板上运行的可执行文件应使用交叉编译器 arm-linux-gnueabihf-gcc 来编译,

先将 led.s 编译成对应的.o 在终端中输入以下命令:

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

上述命令是将军 led.s 编译为 led.o,其中“-g选项是产生调试信息, GDB 代码调试可以使用这些调试信息。“-c选项是编译源文件,但没有链接。“-o选项是指定编译产生的文件名称,我们在此指定 led.s 编译后的文件名称为 led.o。执行上述命令后,将编译生成 led.o 文件 。

【2】arm-linux-gnueabihf-ld 链接文件

arm-linux-gnueabihf-ld 很多.o 将文件链接到指定的链接位置。

我们应该区分存储地址和运行地址的概念。存储地址是存储可执行文件的地方,可执行文件的存储地址可以随意选择。“运行地址”就是代码运行的时候所处的地址,这个我们在链接的时候就已经确定好了,代码要运行,那就必须处于运行地址处,否则代码肯定运行出错。比如 I.MX6U 支持 SD 卡、 EMMC、 NAND 启动代码可以存储到 SD 卡、 EMMC 或者 NAND 中间,但如果要运行,必须从代码开始 SD 卡、 EMMC 或者NAND 复制到其运行地址(链接地址),存储地址和运行地址可以相同,比如STM32 存储起始地址和运行起始地址均为 0X08000000。

本教程裸例程的所有链接地址都在 DDR链接的起始地址为 0X87800000。 I.MX6U-ALPHA 开发板的 DDR 容量有两种: 512MB 和256MB,起始地址都是 0X80000000,只不过 512MB 终止地址为 0X9FFFFFFF,而 256MB 容量终止地址为 0X8FFFFFFF。之所以选择 0X87800000 这个地址是因为后面要讲的 Uboot 链接地址是 0X这样我们就可以统一使用878万元 0X87800000 这个链接地址易记混。

确定链接地址后,即可使用 arm-linux-gnueabihf-ld 前面编译的 led.o 文件链接到 0X87800000 使用以下命令:

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

上述命令中-Ttext 指定链接地址,-o指定链接生成的选项 elf 我们在这里命名文件名 led.elf。上述命令执行后,将在项目目录下多一个 led.elf 文件, led.elf 文件不是我们最终烧写的 SD 我们想烧写的卡中的可执行文件.bin 因此,文件还需要 led.elf 文件转换为.bin 文件,我们需要在这里使用它 arm-linux-gnueabihf-objcopy 这个工具。

【4】arm-linux-gnueabihf-objcopy 格式转换

arm-linux-gnueabihf-objcopy 更像格式转换工具,我们需要使用它 led.elf 文件转换为led.bin 文件,命令如下:

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

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

【5】arm-linux-gnueabihf-objdump 反汇编

大多数情况下我们都是用 C 语言写试验例程的,有时候需要查看其汇编代码来调试代码,因此就需要进行反汇编,一般可以将 elf 文件反汇编,比如如下命令:

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

上述代码中的“-D”选项表示反汇编所有的段,反汇编完成以后就会在当前目录下出现一个名为 led.dis 文件 。

led.dis 里面是汇编代码,而且还可以看到内存分配情况。

总结一下我们为了编译 ARM 开发板上运行的 led.o 这个文件使用了如下命令:

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
(3)代码烧写

I.MX6U 虽然内部有 96K 的 ROM,但是这 96K 的 ROM 是 NXP自己用的,不向用户开放。所以相当于说 I.MX6U 是没有内部 flash 的,但是我们的代码得有地方存放啊,为此, I.MX6U 支持从外置的 NOR Flash、 NAND Flash、 SD/EMMC、 SPI NOR Flash和 QSPI Flash 这些存储介质中启动,所以我们可以将代码烧写到这些存储介质中中。在这些存储介质中,除了 SD 卡以外,其他的一般都是焊接到了板子上的,我们没法直接烧写。但是 SD 卡是活动的,是可以从板子上插拔的,我们可以将 SD 卡插到电脑上,在电脑上使用软件将.bin文件烧写到 SD 卡中,然后再插到板子上就可以了。其他的几种存储介质是我们量产的时候用到的,量产的时候代码就不可能放到 SD 卡里面了,毕竟 SD 是活动的,不牢固,而其他的都是焊接到板子上的,很牢固。

我们在调试裸机和 Uboot 的时候是将代码下载到 SD 中,是因为这样方便,当调试完成以后量产的时候要将裸机或者 Uboot 烧写到 SPI NOR Flash、 EMMC、 NAND 等这些存储介质中的。

正点原子专门编写了一个软件来将编译出来的.bin 文件烧写到 SD 卡中,这个软件叫做“imxdownload”

【1】将 imxdownload 拷贝到工程根目录下

【2】给予 imxdownload 可执行权限

我们直接将软件 imxdownload 从 Windows 下复制到 Ubuntu 中以后, imxdownload 默认是没有可执行权限的。我们需要给予 imxdownload 可执行权限,使用命令“chmod”,命令如下:

chmod 777 imxdownload

当给予 imxdownload 可执行权限以后其名字变成了绿色的,如果没有可执行权限的话其名字颜色是白色的。所以在 Ubuntu 中我们可以初步的从文件名字的颜色判断其是否具有可执行权限。

【3】确定要烧写的 SD 卡。

Ubuntu 下所有的设备文件都在目录“/dev”里面,所以插上 SD 卡以后也会出现在“/dev”里面,其中存储设备都是以“/dev/sd”开头的。我们要先看一下不插 SD 卡的时候电脑都有哪些存储设备,以防插入 SD 卡以后分不清谁是谁。输入如下所示命令:

ls /dev/sd*  

在这里插入图片描述 用读卡器将 SD 卡插到电脑

如果你的电脑没有找到 SD 卡的话,尝试重启一下 Ubuntu 操作!

拓展:

如果你的电脑没有找到 SD 卡,且重启Ubuntu 也还是无法识别到SD卡(U盘)可尝试做如下操作:

这种情况一般是插入USB设备后,”USB设备“都无法在Ubuntu下识别,且VMware中“连接(断开与主机连接)©”为灰色不可选中状态,如下图: 解决:首先关闭虚拟机系统,找到当前虚拟机的安装目录,找到【.vmx】文件,如下图 选用记事本工具打开,找到【usb.restrictions.defaultAllow = “FALSE”】配置,将“FALSE”修改为“TRUE”,然后保存并关闭文件,再次启动虚拟机系统,此时虚拟机就能正常识别“U盘设备”了。 然后我们再次输入【ls /dev/sd* 】指令,即可确认我们的SD卡的设备类型,【/dev/sdb】即是我的 SD 卡

【4】向 SD 卡烧写 bin 文件

使用 imxdownload 向 SD 卡烧写 led.bin 文件,命令格式如下:

./imxdownload <.bin file> <SD Card>  

其中.bin 就是要烧写的.bin 文件, SD Card 就是你要烧写的 SD 卡

例如:烧写 led.bin 到/dev/sdb 中:

./imxdownload led.bin /dev/sdb // 不能烧写到/dev/sda 或 sda1 设备里面!那是系统磁盘 

烧写的过程中可能会让你输入密码,输入你的 Ubuntu 密码即可完成烧写,烧写的最后一行会显示烧写大小、用时和速度 。注意这个烧写速度,如果这个烧写速度在几百 KB/s 以下那么就是正常烧写。如果这个烧写速度大于几十 MB/s、甚至几百 MB/s 那么肯定是烧写失败了!

烧写完成以后会在当前工程目录下生成一个 load.imx 的文件 ,load.imx 这个文件就是软件 imxdownload 根据 NXP 官方启动方式介绍的内容,在 led.bin 文件前面添加了一些数据头以后生成的。最终烧写到 SD 卡里面的就是这个 load.imx 文件,而非led.bin。

(4)代码验证

代码已经烧写到了 SD 卡中了,接下来就是将 SD 卡插到开发板的 SD 卡槽中,然后设置拨码开关为 SD 卡启动,拨码开关设置如图 8.4.4.1 所示: 设置好以后按一下开发板的复位键,如果代码运行正常的话 LED0 就会被点亮 ,能 LED0 之前会有一点微亮,那是因为 I.MX6U的 IO 默认电平可能让 LED0 导通了,但是 IO 的默认配置内部可能有很大的电阻,所以电流就很小,导致 LED0 微亮。但是我们自己编写代码、配置好 IO 以后就不会有这个问题, LED0 就很亮了。

标签: ddr4驱动电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台