主篇文章主要记录imx6的研究过程,将工作中有的到的重要部分提炼出来,主要描述与硬件相关的内容,也会涉及到一部分底层软件。

相关文章:i.MX 6ULL研究笔记_软件篇

i.MX 6ULL分类

i.MX 6ULL有几大系列(Y0,Y1,Y2,Y7),各系列接口资源不一样,各系列还可以根据主频不同再细分,另外还有工业级和消费级之分

Y0系列:基础系列,只有528Mhz 一种主频,有工业级和消费级

Y1系列:比Y0多1个USB,添加1个CAN

Y2系列:接口丰富,主频可选,相应的价格也比较贵

Y7系列:增加电子墨水屏接口,没有工业级

Ethernet USB 工业级 消费级 CAN EPDC LCD/CSI
Y0@528Mhz 1 1 - - -
Y1@528Mhz 1 2 1 - -
Y2@528Mhz 2 2 2 - 1
Y2@792Mhz 2 2 - 1
Y2@900Mhz 2 2 - 1
Y7@528Mhz 1 2 - 1 1
Y7@900Mhz 1 2 - 1 1

其他常用接口(UART、I2C、SPI、PWM)各系列都有,满足常规应用,特殊需求需要查看手册

i.MX 6ULL核心电压设计

i.MX6中ARM的核心有2个:VDD_ARM_CAP 和 VDD_SOC_CAP,这两个都是由VDD_SOC_IN经过LDO产生,如下图所示:

不同的工作主频,需要的VDD_ARM_CAP电压不同,频率越高需要的电压越高,手册中描述,为保证LDO的正常工作,需要满足VDD_SOC_IN比VDD_ARM_CAP高125mV

官方的代码中的对应关系,如下所示

主频(kHz) VDD_ARM_CAP电压(uV) 对应的VDD_SOC_IN
996000 1275000 1.4 V
792000 1225000 1.35 V
528000 1175000 1.3 V
396000 1025000 1.15 V
198000 950000 1.075 V

因此需要根据CPU运行的主频选择合适的VDD_SOC_IN电压,比如希望CPU能运行在792Mhz,则外部的VDD_SOC_IN需要1.35V,当然如果能够通过软件动态调试VDD_SOC_IN的电压就最好的,官方的硬件设计可以支持动态调试电压,具体可以参考官方DEMO板的原理图

还有另外一个方案,如果CPU只运行在528Mhz频率及以下,可以关闭LDO功能,则VDD_SOC_IN可以设计更低的电压1.175V(手册描述最低1.15V)

支持的内存

CPU可以支持以下3种内存

Parameter DDR3 DDR3L LDDDR2
Clock frequency 400 MHz 400 MHz 400 MHz
Bus width 16-bit 16-bit 16-bit
Channel Single Single Single
Chip selects 2 2 2

可支持的内容颗粒密度(256 Mbits–8 Gbits)

总共最大可支持2GB内存

内存的参数配置存放在uboot头里,后续会讲到

CPU超频

为什么研究超频,如果最便宜的在Y0系列接口满足要求,但主频(或者说性能)不满足要求时也可尝试提高CPU主频,当然这个要经过长时间的测试来检测其稳定性。

官方没有提供超频的用法及相关的测试数据,但手册中有如下描述

PLL1 (also referred to as ARM_PLL) - This is the PLL clocking the ARM core complex. It is a programmable integer frequency multiplier capable of output frequency of up to 1.3 GHz. Note that this frequency is higher than the maximum chip supported frequency 1.0 GHz

CPU的核心频率由PLL1控制,可以通过修改PLL1的参数修改核心频率,从手册上来看是可以超频的。

测试也是可以的,具体方法不在这里描述。

eFUSE

eFUSE是一块配置区域,使用熔丝技术,即只能配置一次(每个bit只能由0写成1

eFUSE的总大小为256字节:8个bank 8个word * 4个bytes,其中大部分已经被厂家定义了其使用目的,比如启动配置、网口MAC地址等,目前有44 bytes可用于通用目的。

可根据具体业务来决定是否使用这块区域

引脚规划

引脚选择主要考虑向后兼容性,保留LCD引脚

GPIO选择

CPU的绝大部分引脚可用于GPIO功能,但为便于向后兼容,应优先考虑使用SNVS_TAMPERx,这里有10个可用的GPIO(SNVS_TAMPER默认是GPIO功能)

如果还是不够用,可以考虑从CSI引脚中选取(工业产品使用CSI的可能性比较小
​ CSI_DATA04 ~ CSI_DATA07计划用一SPI
GPIO1_IO0x 中有部分已经用于其他功能,可以使用的GPIO已经不多
GPIO1_IO00、GPIO1_IO05:OTG_ID(不使用时要拉低)
GPIO1_IO02 ~ GPIO1_IO03:I2C1
GPIO1_IO06 ~ GPIO1_IO07:MDIO
GPIO1_IO08 ~ GPIO1_IO09:PWM

WDOG

Watchdog有一个非常有用的功能,输出复位信号,可以用于控制设备重新上电,推荐使用LCD_RESET引脚

串口

Y0系列最多4个串口,Y1、Y2系列最多8个串口,使用注意事项:

  • 尽量使用UART1 ~ UART5,有专门的引脚,不容易与其他功能产生引脚冲突,其中UART1 ~ UART3有专门的流控引脚
  • 调试串口尽量选择UART1
    官方代码默认使用UART1,有可能后期需要使用官方的DEMO程序做对比测试
  • 使用485功能时,尽量选择UART2
    UART1 ~ UART3有专门的引脚可用于收、发切换
    UART1用于调试串口
    UART3的收、发切换会复用成CAN

CAN

Y0系列没有CAN,Y1系列有1路CAN,Y2系列有2中CAN

CPU设计时没给CAN专用的引脚,需要从其他引脚复用,推荐的复用方法:
CAN1:UART3_CTS、UART3_RTS
CAN2:UART2_CTS、UART2_RTS(UART2的CTS/RTS可选择UART3RX/TX引脚,不使用UART3)
使用2路CAN的可能性不大,如果确实要使用,则牺牲UART3接口

I2C

CPU支持多路I2C,一般的硬件用2路就足够了, 建议使用:
I2C1:GPIO1_IO2、GPIO1_IO3
I2C2:UART5_TX_DATA、UART5_RX_DATA

SPI

CPU支持多路SPI,一般的硬件用1路就足够了, 建议使用:
ECSPI1:
​ MISO:CSI_DATA07
​ MOSI:CSI_DATA06
​ SCLK: CSI_DATA04
​ CS: CSI_DATA05

SAI

SAI是串行音频接口,建议将其引出来,可以使用JTAG引脚来复用

注:作音频功能时,同时需要用到I2C接口

PWM

CPU支持多路PWM,一般不需要使用,暂时保留2个
PWM1:GPIO1_IO08
PWM2:GPIO1_IO09

系统启动

内部ROM

  1. CPU复位后从内部(on-chip)ROM开始运行,内部ROM几个主要功能:
    • 可以从多种不同外设加载启动程序进行启动;
    • 支持USB/UART升级
    • DCD配置(用于内存初始化,后续会讲到
    • 执行加密的boot(目前没有使用)
    • 唤醒设备(目前没有使用)
  2. 支持的外部存储设备类型
    • NOR flash
    • NAND flash
    • OneNAND flash
    • SD/MMC(注:可支持3.3V和1.8V,但也有使用前提)
    • SPI NOR flash 或者 EEPROM
    • QSPI flssh

内部ROM运行的具体流程图可以参考datasheet

启动模式配置

启动模式由BOOT_MODE和GPIO(或eFUSE)决定,批量使用时,一般使用GPIO,而不使用eFUSE

具体的启动模式如下图所示:

其中红色部分为选择的配置
建议硬件预留或其他办法,保证后续可以使用Serial Download模式(USB下载模式,设备作为从模式连接PC),可用于内存校准身等硬件调试

具体细节也请查看datasheet

8.2.1 Boot mode pin settings
8.5 Boot devices (internal boot)
8.5.3.1 Expansion device eFUSE configuration

IVT头

CPU启动时,内部ROM从指定的外部存储器中读取一段数据用于初始化,该数据需要包含一定的格式,称之为IVT(Image Vector Table );

内部ROM从eMMC的0x400(1KB)位置读取IVT,读取大小4kB;

标准u-boot编译成生的文件是u-boot.bin,imx6的u-boot编译会把IVT头放在uboot.bin文件最前面,大小为3KB,生成u-boot.imx文件;

将u-boot.imx烧录到eMMC时需要偏移1KB进行烧录

如此设计原因:eMMC最前面512 bytes可用于MBR,方便eMMC的分区操作,然后再预留512 bytes

DCD数据

IVT头中最重要的一部分数据是DCD(Device Configuration Data),DCD有什么作用呢?

在CPU复位后,所有的寄存器都保持在默认的状态,内部ROM启动后会做一些基础的必要配置,但这些配置远远不够,因为内部ROM不知道最终的硬件形态,无法做外设的初始化,特别是内存的初始化,因此内部ROM执行初始化时需要从外部导入一些配置项进行,这些配置项就是DCD数据。

DCD数据的格式:

Header: Tag+ Length+ Version,其中Length表示有多少个配置需要执行
[CMD]:具体的配置命令: Address(4 bytes) + Value(4 bytes),意思是,向Address写入Value
[CMD]:同上

DCD的数据在u-boot中,路径:board/freescale/xxx/imximage.cfg (xxx是板子名,目前是hd_mx6ull_ddr3)

通过eMMC启动

背景知识介绍

配置eMMC启动,需要了解这些背景知识

  • eMMC中包含2个boot分区+1个用户分区(硬件分区,与平时的软件分区概念不一样),可以选择其中一个存放boot程序,新eMMC会有更多的分区,这些可以在Linux的启动打印中看到
  • eMMC中有几个重要的配置寄存器(掉电不丢失),用于配置是否使用boot分区、当前使用哪个分区等;
  • CPU启动时可以配置成从eMMC的boot分区加载boot程序;
  • eMMC的每一个硬件分区都是独立编址的,所以在访问前要先指定访问哪一个分区;

eMMC boot相关寄存器

PARTITION_CONFIG

Bit 7 Bit 6 Bit [5:3] Bit [2:0]
Reserved BOOT_ACK BOOT_PARTITION_ENABLE PARTITION_ACCESS

BOOT_ACK:CPU加载boot程序时是否使用ACK,需要与CPU端的配置保持一致

BOOT_PARTTION_ENABLE:是否使用boot功能,使用哪个分区存放boot程序,一般选择boot1分区

PARTTION_ACCESS:当前访问的是哪个分区,烧录boot时需要将其他指定到正确的分区,一般是boot1分区,烧录完成后需要改成0(正常模式)

BOOT_BUS_WIDTH

Bit [7:5] Bit [4:3] Bit 2 Bit [1:0]
Reserved BOOT_MODE RESET_BOOT_BUS_WIDTH BOOT_BUS_WIDTH

BOOT_MODE:读取boot程序的工作模式,需要与CPU端保持兼容

RESET_BOOT_BUS_WIDTH:未知

BOOT_BUS_WIDTH:读取boot程序的数据宽度,需要与CPU端保持一致
0:1bit, 1:4bit, 2:8bit

boot_mode说明:

硬件引脚

为保证eMMC能正常启动,且后续能通过TF卡来升级,使用USDHC1接TF卡(可用于生产烧录),使用USDHC2接eMMC,具体的引脚如下连接如下:

Signal USDHC1 USDHC2 备注
CLK SD1_CLK NAND_RE_B.alt1
CMD SD1_CMD NAND_WE_B.alt1
DATA0 SD1_DATA0 NAND_DATA00.alt1
DATA1 SD1_DATA1 NAND_DATA01.alt1
DATA2 SD1_DATA2 NAND_DATA02.alt1
DATA3 SD1_DATA3 NAND_DATA03
DATA4 NAND_DATA04 USDHC1接TF卡,不需要DATA4-7
DATA5 NAND_DATA05
DATA6 NAND_DATA06
DATA7 NAND_DATA07
VSELECT GPIO1_IO05 GPIO1_IO08 使用固定电压3.3V,可以不接
RESET_B GPIO1_IO09 NAND_ALE 不使用reset功能,可以不接
CD_B UART1_RTS_B TF烧录时需要使用CD脚

TF卡烧录原理

当配置的启动设备(eMMC)无法启动时,会从uSDHC1(硬件接TF卡)启动

When the internal boot and recover boot (if enabled) failed, the SDMMC_MFG_DISABLE fuse bit isn’t set and the EEPROM recovery fuse bit is set, the boot goes to the SD/MMC manufacture mode before the serial download mode. In the manufacture mode, one bit bus width is used despite of the fuse setting.

In the manufacture mode, the SD or MMC card will be scanned on the uSDHC1. If a card is detected and a valid boot image is found in the card, the boot image is loaded and executed. Pad of SD1_CD is used to detect whether a card is inserted or not

因此SD1_CD一定要接,另外manufacture mode默认是打开的

看门狗

CPU内部有一个看门狗,看门狗的作用就不多说了,这里主要讲一下CPU自的看门狗特点:

  • 看门狗的周期0.5s ~ 128s,相比硬件看门狗固定的周期(很小),使用起来更方便
  • 看门狗事件产生之前可以触发中断,通过中断程序可以检测系统的一些状态
  • 看门狗可以产生一个复位信号出来(复位信号的时间可配置)

通过合理的硬件设计,可以通过硬件看门狗给设备重新上电,实现硬复位功能,可参考imx6ull的DEMO设计

USB

i.MX 6ULL最多可支持2个USB接口,均为OTG接口

如果需要使用OTG功能,则需要正确使用OTG_ID引脚

如果只使用host模式,可将OTG_ID引脚拉低,不要将OTG_ID引脚用于其他功能,便于软件做兼容处理

imx6 中USB phy有一个驱动器电流补偿功能,可以通过配置来设置补偿大小,如果USB不稳定可以信尝试修改补偿值

SNVS&实时时钟

SNVS(Secure Non-Volatile Storage),对于常规应用,有以下几个功能:

  • 一个实时时钟计数器
  • 一个通用功能寄存器(非易失的,在SNVS_LP中)
  • 开关机管理(自动&手动)

SNVS内部包含2部分:

  • SNVS_HP(高功耗部分,由主电源供电)
  • SNVS_LP(低功耗部分,主电源存在时由主电源供电,主电源不存在时由纽扣电池供电)

    从图可看出,ARM核心只与SNVS_HP通讯,读取SNVS_LP寄存器时需要通过SNVS_HP

手册中描述SNVS的典型工作电流是25uA,需要实际测试,可尝试关闭一部分功能看是否会更低