ARM裸机开发:I.MX6U 启动方式

Posted JeckXu666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARM裸机开发:I.MX6U 启动方式相关的知识,希望对你有一定的参考价值。

ARM裸机开发:I.MX6U 启动方式

一、硬件平台:

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

二、启动方式选择

I.MX6U 支持多种启动方式以及启动设备,比如可以从 SD/EMMC、NAND Flash、QSPI Flash 等启动。用户可以根据实际情况,选择合适的启动设备。

芯片上电以后,芯片会根据 BOOT_MODE[1:0] 的设置来选择 BOOT 方式, BOOT_MODE[1:0] 的值有两者控制方式

  1. eFUSE(熔丝) 控制电平:修改 eFUSE 的方式通过熔断对应的熔丝修改电平,该方式只能修改一次(不推荐)
  2. 修改 BOOT_MODE[1:0] 对应的 GPIO 高低电平来选择启动方式

I.MX6U 使用的是控制 IO 电平来控制启动方式,原理图上位置如下:

BOOT_MODE[1:0] 与启动方式关系:

BOOT_MODE[1:0]BOOT 类型
00从FUSE 启动
01串行下载
10内部BOOT 模式
11保留

一般我们使用 01 和 10 启动方式

2.1 串行下载

BOOT_MODE[1:0] 为 01;

串行下载:可以通过 USB 或者 UART 将代码下载到板子上的外置存储设备中,比如载串行下载模式下,我们可以使用 OTG1 这个 USB 口向开发板上的 SD/EMMC、NAND 等存储设备下载代码

2.2 内部BOOT模式

BOOT_MODE[1:0] 为 10;

此模式下,芯片会执 行内部的 boot ROM 代码,这段 boot ROM 代码会进行部分硬件初始化,然后从 boot 设 备(就是存放代码的设备、比如 SD/EMMC、NAND)中将代码拷贝出来复制到指定的 RAM 中, 一般是 DDR

2.3 BOOT ROM初始化内容

在内部 BOOT 模式下,芯片执行 BOOT ROM 初始化内容,BOOT ROM 如何执行呢?

首先 BOOT ROM 代码先初始化时钟,按下下图初始化各个时钟总线的分配器

同时内部 boot ROM 为了加快执行速度会打开 MMU(内存管理单元) 和 Cache(缓存),下载镜像的时候 L1 ICache(1级指令缓存) 会打 开,验证镜像的时候 L1 DCache、L2 Cache 和 MMU 都会打开。一旦镜像验证完成,boot ROM 就会关闭 L1 DCache、L2 Cache 和 MMU

之后中断向量偏移会被设置到 boot ROM 的起始位置,当 boot ROM 启动了用户代码以后就可以重新设置中断向量偏移了

2.4 内部BOOT启动设备

当 BOOT_MODE 设置为内部 BOOT 模式以后,可以从以下设备中启动:

  • 接到 EIM 接口的 CS0 上的 16 位 NOR Flash
  • 接到 EIM 接口的 CS0 上的 NAND Flash
  • 接到 GPMI 接口上的 MLC/SLC NAND Flash,NAND Flash 页大小支持 2KByte、4KByte 和 8KByte,8 位宽。
  • Quad SPI Flash。
  • 接到 USDHC 接口上的 SD/MMC/eSD/SDXC/eMMC 等设备。
  • SPI 接口的 EEPROM

关于启动设备的选择,I.MX 6U 同样提供了 eFUSE 和 GPIO 量种配置方式,常用的是 GPIO 选择启动设备

启动设备是通过 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 的启动选择引脚

虽然有 24 个 IO,但是实际需要调整的只有那几个 IO,其它的 IO 全部下拉 接地即可,如下图,大部分 IO 一直保持下拉接地,只有几个 IO (BOOT_CFG2[7:0]和 BOOT_CFG1[7:0])需要我们关注:

IO 与启动设备的关系如下图:

各个模式间切换时,许多 IO 是基本保持不变的,所以进一步简化,只需要 LCD_DATA3 ~ LCDDATA7、LCD_DATA11 这 6 个 IO 也被引出来了,其中 LCD_DATA11 就 是 BOOT_CFG2[3],LCD_DATA3~LCD_DATA7 就是 BOOT_CFG1[3]~BOOT_CFG1[7]

对应的设备模式如下:

所以 I.MX6U 开发板从 SD 卡、EMMC、NAND 启动 的时候拨码开关各个位设置方式如表

12345678启动设备
01xxxxxx串行下载,可以通过 USB 烧写镜像文件。
10000010SD 卡启动。
10100110EMMC 启动。
10001001NAND FLASH 启动。

三、镜像烧写

学习 STM32 的时候我们可以直接将编译生成的.bin 文件烧写到 STM32 内部 flash 里面,但 I.MX6U 不能直接烧写编译生成的.bin 文件,我们需要在.bin 文件前面添加一些头信息构成 满足 I.MX6U 需求的最终可烧写文件

I.MX6U 的最终可烧写文件组成如下:

  • Image vector table,简称 IVT,IVT 里面包含了一系列的地址信息,这些地址信息在 ROM 中按照固定的地址存放着
  • Boot data,启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少等等
  • Device configuration data,简称 DCD,设备配置信息,重点是 DDR3 的初始化配置
  • 用户代码可执行文件,比如 led.bin

所以烧写文件的最终组成为: IVT + Boot data + DCD + usr.bin;其中 IVT + Boot data + DCD 大小为3KB

IVT 包含了镜像程序的入口点、指向 DCD 的指 针和一些用作其它用途的指针。内部 Boot ROM 要求 IVT 应该放到指定的位置,不同的启动设备位置不同,而 IVT 在整个 load.imx 的最前面,其实就相当于要求 imx 文件在烧写的时候应该烧写到存储设备的指定位置去。整个位置都是相对于存储设备的起始地址的偏移

3.1 IVT + Boot data 存放内容:

header

Tag 为一个字节长度,固定为 0XD1,Length 是两个字节,保存着 IVT 长度,大端格式(高字节保存在低地址)最后的 Version 是一个字节,为 0X40 或者 0X41

entry:入口地址,也就是镜像第一行指令所在的位置。 0X87800000 就是我们的链接地址

reserved1:保留位

dcd:DCD 地址,镜像地址为 0X87800000,IVT+Boot Data+DCD 整个大小为 3KByte。因此 .imx 文件的起始地址就是 0X87800000-0XC00=0X877FF400

Boot Data:boot 地址,header 里面已经设置了 IVT 大小是 32 个 字节,其结构如下:

  • start 整个 load.imx 的起始地址,包括前面 1KByte 的地址偏移。

  • length 镜像大小,这里设置 2MByte。镜像大小不能超过 2MByte。

  • plugin 插件

self: IVT 复制到 DDR 中以后的首地址

csf: CSF 地址

reserved2:保留,未使用

3.2 DCD数据

复位以后,I.MX6U 片内的所有寄存器都会复位为默认值,但是这些默认值往往不是我们想要的值,有些外设我们必须在使用之前初始化它。为此 I.MX6U 提出了一个 DCD (Device Config Data) 的概念,和 IVT、Boot Data 一样,DCD 也是添加到 load.imx 里面的,紧跟在 IVT 和 Boot Data 后面,IVT 里面也指定了 DCD 的位置。

DCD 其实就是 I.MX6U 寄存器地址和对应的配置信息集合,Boot ROM 会使用这些寄存器地址和配置集合来初始化相应的寄存器,比如 开启某些外设的时钟、初始化 DDR 等等。DCD 区域不能超过 1768Byte !

DCD 里面的初始化配置主要包括三方面:

  1. 设置 CCGR0~CCGR6 这 7 个外设时钟使能寄存器,默认打开所有的外设时钟
  2. 配置 DDR3 所用的所有 IO
  3. 配置 MMDC 控制器,初始化 DDR3

以上是关于ARM裸机开发:I.MX6U 启动方式的主要内容,如果未能解决你的问题,请参考以下文章

ARM裸机开发:C语言点亮LED

ARM裸机开发:I.MX6U官方SDK包使用

ARM裸机开发:输入中断

ARM裸机开发:按键输入实验

ARM裸机开发:蜂鸣器实验

I.MX6U启动方式详解