基于linux平台的嵌入式开发每日一练(五)

今天是2020.08.04 星期二 雨。
在前一节,我们学习了怎么在linux平台上编写,编译,下载一个裸机版的 led 驱动。其中我们发现这个下载烧录文件和我们平时遇到的不一样,它不是直接将编译生成的可执行文件(led.bin)直接烧录,而是使用一个烧录软件协助烧录,而且最终烧录到SD卡中的文件还不是led.bin文件,而是一个叫做load.imx的文件。那么这个烧录软件是什么?为什么要烧录到SD卡?为什么烧录的文件是load.imx?这个load.imx文件与led.bin文件有什么不相同?这一节就带着这一系列问题开始学习。

一、认识imxdownload

我们使用的是imx6ul芯片,因为这些“高级”一点的MCU本身内部是没有提供给用户使用的ROM和RAM,需要外部的NAND FLASH作为ROM,DDR储存器作为RAM。这样在芯片启动时就不仅要提供sp地址,而且还要初始化一些外设(DDR),将程序加载到DDR中运行。而i.mx6ull在启动时内部的ROM中有固化好的代码,可以完成DDR的初始化,但是需要提供一些DDR寄存器信息以及一些程序运行地址信息。所以i.mx6ull必须在自己编译完成的bin文件前在加一段数据提供信息,imxdownload就是做这个事情。
这些信息称为启动头文件,**由IVT、Boot Date和DCD组成,imxdownload实现的功能是将启动头文件加在用户代码前面。**首先,需要将要储存的信息保存成一个数组,放在头文件中,然后程序逻辑就是先利用fopen函数打开已经生成好的bin文件,在利用ftell函数计算bin文件大小,动态分配一个bin文件大小加3kb的空间,利用fread函数将bin文件中的二进制数据以字节的形式读取,用fwrite函数从分配空间的3kb之后写入,在将头文件中的数组写入前面的3kb,最后再将修改好在内存空间中的数据写到load.imx文件中,并将该文件刷到sd卡中。

二、I.mx6u启动方式

I.MX6U 支持多种启动方式以及启动设备,比如可以从 SD/EMMC、 NAND Flash、 QSPI Flash等启动。用户可以根据实际情况,选择合适的启动设备。不同的启动方式其启动方式和启动要求也不一样,比如上一节中的从 SD 卡启动。
如何选择启动方式?
启动模式选择:
在i.mx6u芯片上有两个引脚BOOT_MODE0、BOOT_MODE1。I.MX6U 芯片上电以后,芯片会根据 BOOT_MODE[1:0]的设置来选择 BOOT 方式。BOOT_MODE[1:0]的值是可以改变的,有两种方式,一种是改写 eFUSE(熔丝),一种是修改相应的GPIO 高低电平。第一种修改 eFUSE 的方式只能修改一次,后面就不能再修改了,所以我们不使用。我们使用的是通过修改 BOOT_MODE[1:0]对应的 GPIO 高低电平来选择启动方式,所有的开发板都使用的这种方式, I.MX6U 有BOOT_MODE1 引脚和BOOT_MODE0 引脚,这两个引脚对应这 BOOT_MODE[1:0]。
在这里插入图片描述
其中 BOOT_MODE1 和 BOOT_MODE0 在芯片内部是有 100KΩ下拉电阻的,所以默认是0。 BOOT_MODE1 和 BOOT_MODE0 这两个引脚我们也接到了底板的拨码开关上,这样我们就可以通过拨码开关来控制 BOOT_MODE1 和 BOOT_MODE0 的高低电平。
在这里插入图片描述
BOOT_CFG 的第一个开关拨到“ON”的时候,就相当于 BOOT_MODE1 引脚通过 R88 这个 10K 电阻接到了 3.3V 电源,芯片内部的 BOOT_MODE1 又是 100K 下拉电阻接地,BOOT_MODE1 的电压就是 100/(10+100)*3.3V= 3V,这是个高电平, 因此BOOT_CFG 的中的 8 个开关拨到“ON”就是高电平,拨到“OFF”就是低电平。

I.MX6U 有四个 BOOT 模式,这四个 BOOT 模式由BOOT_MODE[1:0]来控制,也就是
BOOT_MODE1 和 BOOT_MODE0 这两 IO, BOOT 模式配置如表所示:
在这里插入图片描述
- 串行下载
当 BOOT_MODE1 为 0, BOOT_MODE0 为 1 的时候此模式使能,串行下载的意思就是可以通过 USB 或者 UART 将代码下载到板子上的外置存储设备中,我们可以使用 OTG1 这个 USB口向开发板上的 SD/EMMC、 NAND 等存储设备下载代码。
- 内部BOOT模式
当 BOOT_MODE1 为 1, BOOT_MODE0 为 0 的时候此模式使能,在此模式下,芯片会执行内部的 boot ROM 代码,这段 boot ROM 代码会进行硬件初始化(一部分外设),然后从 boot 设备(就是存放代码的设备、比如 SD/EMMC、 NAND)中将代码拷贝出来复制到指定的 RAM 中,一般是 DDR。

I.BOOT ROM 初始化内容
设置 BOOT 模式为“内部 BOOT 模式”以后, I.MX6U 内部的 boot ROM 代码就会
执行,这个 boot ROM 代码都会做什么处理呢?

  • 首先肯定是初始化时钟
    boot ROM 设置的系统时钟如图所示:
    在这里插入图片描述
    BT_FREQ 模式为 0,可以看到, boot ROM 会将 I.MX6U 的内核时钟设置为
    396MHz, 也就是主频为 396Mhz。 System PLL=528Mhz, USB PLL=480MHz, AHB=132MHz,IPG=66MHz。
    内部 boot ROM 为了加快执行速度会打开 MMU 和 Cache,下载镜像的时候 L1 ICache 会打
    开,验证镜像的时候 L1 DCache、 L2 Cache 和 MMU 都会打开。一旦镜像验证完成, boot ROM就会关闭 L1 DCache、 L2 Cache 和 MMU。
    中断向量偏移会被设置到 boot ROM 的起始位置,当 boot ROM 启动了用户代码以后就可以重新设置中断向量偏移了。一般是重新设置到我们用户代码的开始地方。

启动设备选择:
当 BOOT_MODE 设置为内部 BOOT 模式以后,可以从一下设备中启动:
、接到 EIM 接口的 CS0 上的 16 位 NOR Flash。
、接到 EIM 接口的 CS0 上的 OneNAND Flash。
、接到 GPMI 接口上的 MLC/SLC NAND Flash, NAND Flash 页大小支持 2KByte、 4KByte和 8KByte, 8 位宽。
、 Quad SPI Flash。
、接到 USDHC 接口上的 SD/MMC/eSD/SDXC/eMMC 等设备。
、 SPI 接口的 EEPROM。
这些启动设备如何选择呢? I.MX6U 同样提供了 eFUSE 和 GPIO 配置两种, eFUSE 就不讲解了。重点看如何通过 GPIO 来选择启动设备,因为所有的 I.MX6U 开发板都是通过 GPIO来配置启动设备的。正如启动模式由 BOOT_MODE[1:0]来选择一样,启动设备是通过BOOT_CFG1[7:0]、 BOOT_CFG2[7:0]和 BOOT_CFG4[7:0]这 24 个配置 IO,这 24 个配置 IO 刚好对应着 LCD 的 24 根数据线 LCD_DATA0~LCDDATA23,当启动完成以后这 24 个 IO 就可以作为 LCD 的数据线使用。这 24 根线和 BOOT_MODE1、 BOOT_MODE0 共同组成了 I.MX6U的启动选择引脚。这26 个启动 IO 即可实现 I.MX6U 从不同的设备启动。除去启动模式选择使用的两个IO外,还剩下24个IO用于启动设备选择。但不是所有的24个IO都必须设置,我们只需设置其中一部分,其他的全部下拉接地即可。
在这里插入图片描述
大部分的 IO 都接地了,只有几个 IO 接高,尤其是 BOOT_CFG4[7:0]这 8 个 IO 都 10K 电阻下拉接地,所以我们压根就不需要去关注 BOOT_CFG4[7:0]。我们需要重点关注的就只剩下了 BOOT_CFG2[7:0]和 BOOT_CFG1[7:0]这 16 个 IO。这 16 个配置 IO 含
义在原理图如下:
在这里插入图片描述
而i.mx6ul将这十六个IO进一步减少,便于设置:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
至此我们知道了上一节为什么使用SD卡烧录文件。

三、镜像文件的烧录

由第一点我们知道了imxdownload 软件的作用就是在在 led.bin前面添加一些头信息,重新生成一个叫做 load.imx 的文件,最终实际烧写的是 laod.imx。
那添加的这部分信息究竟是什么?
答案:IVT(Image vector table)、Boot data、DCD(Device configuration data)
详细介绍添加的这部分信息如下:

  • IVT( Image vector table):包含了一系列的地址信息,这些地址信息在 ROM
    中按照固定的地址存放着。
  • Boot data:启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少等等。
  • DCD(Device configuration data):设备配置信息,重点是 DDR3 的初始化配置。

最终烧写到 I.MX6U 中的程序其组成为: IVT+Boot data+DCD+.bin。

I.IVT 和 Boot Data 数据
load.imx 最前面的就是 IVT 和 Boot Data, IVT 包含了镜像程序的入口点、指向 DCD 的指针和一些用作其它用途的指针。内部 Boot ROM 要求 IVT 应该放到指定的位置,不同的启动设备位置不同,而 IVT 在整个 load.imx 的最前面,其实就相当于要求 load.imx 在烧写的时候应该烧写到存储设备的指定位置去。整个位置都是相对于存储设备的起始地址的偏移,如图所示:
在这里插入图片描述
以 SD/EMMC 为例, IVT 偏移为 1Kbyte, IVT+Boot data+DCD 的总大小为 4KByte-1KByte=3KByte。假如 SD/EMMC 每个扇区为 512 字节,那么 load.imx 应该从第三个扇区开始烧写,前两个扇区要留出来。 load.imx 从第 3KByte 开始才是真正的.bin 文件。

1)那么 IVT 里面究竟存放着什么东西呢? IVT 里面存放的内容及格式如图所示:
在这里插入图片描述
IVT header 格式如图所示:
在这里插入图片描述
Tag 为一个字节长度,固定为 0XD1, Length 是两个字节,保存着 IVT 长
度,为大端格式,也就是高字节保存在低内存中。最后的 Version 是一个字节,为 0X40 或者0X41。

2)Boot Data 的数据格式如图:
在这里插入图片描述
这里可以打开上一节生成的load.imx文件,使用winhex打开,如图所示(此处只截取其中一部分):
在这里插入图片描述
load.imx 的一部分内容,从地址 0X00000000~0X000025F,共 608
个字节的数据。我们将前 44 个字节的数据按照 4 个字节一组组合在一起就是: 0X402000D1、0X87800000、 0X00000000、 0X877FF42C、0X877FF420、 0X877FF400、 0X00000000、 0X00000000、0X877FF000、 0X00200000、 0X00000000。这 44 个字节的数据就是 IVT 和 Boot Data 数据,按照前面所示的 IVT 和 Boot Data 所示的格式对应起来如表所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
DCD数据
复位以后, I.MX6U 片内的所有寄存器都会复位为默认值,但是这些默认值往往不是我们想要的值,而且有些外设我们必须在使用之前初始化它。为此 I.MX6U 提出了一个 DCD(DeviceConfig Data)的概念,和 IVT、 Boot Data 一样, DCD 也是添加到 load.imx 里面的,紧跟在 IVT和 Boot Data 后面, IVT 里面也指定了 DCD 的位置。 DCD 其实就是 I.MX6U 寄存器地址和对应的配置信息集合, Boot ROM 会使用这些寄存器地址和配置集合来初始化相应的寄存器,比如开启某些外设的时钟、初始化 DDR 等等。 DCD 区域不能超过 1768Byte, DCD 区域结构如图:
在这里插入图片描述
DCD 的 header 和 IVT 的 header 类似,如下:在这里插入图片描述
Tag 是单字节,固定为 0XD2, Length 为两个字节,表示 DCD 区域的大小,包含 header,同样是大端模式, Version 是单字节,固定为 0X40 或者 0X41。

CMD 就是要初始化的寄存器地址和相应的寄存器值,其结构如下:
在这里插入图片描述
Tag 为一个字节,固定为 0XCC。 Length 是两个字节,包含写入的命令数据长
度,包含 header,同样是大端模式。 Parameter 为一个字节,这个字节的每个位含义,其结构是:
在这里插入图片描述
bytes 表示是目标位置宽度,单位为 byte,可以选择 1、 2、和 4 字节。 flags
是命令控制标志位。
Address 和 Vlalue/Mask 就是要初始化的寄存器地址和相应的寄存器值,注
意采用的是大端模式!
根据上述描述的DCD的结构,结合上面截取的部分load.imx分析,可以得出该load.imx的DCD信息如下所示:
在这里插入图片描述
在这里插入图片描述
综合来看DCD包含了如下三部分的信息:
①、设置 CCGR0~CCGR6 这 7 个外设时钟使能寄存器,默认打开所有的外设时钟。
②、配置 DDR3 所用的所有 IO。
③、配置 MMDC 控制器,初始化 DDR3。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值