单片机
返回首页

【IMX6ULL学习笔记】五、U-BOOT移植与解析

2025-03-05 来源:cnblogs

一、移植自定义开发板流程

1、添加 mx6ull_kodo_emmc_defconfig 配置文件(.config)

在 /config s目录下,复制 mx6ull_14x14_evk_emmc_defconfig 文件,重命名为 mx6ull_kodo_emmc_defconfig 并修改其中内容,如下:


CONFIG_SYS_EXTRA_OPTIONS='IMX_CONFIG=board/freescale/mx6ull_kodoboard/imximage.cfg,MX6ULL_EVK_EMMC_REWORK'

CONFIG_ARM=y

CONFIG_ARCH_MX6=y

CONFIG_TARGET_MX6ULL_KODO_EMMC=y

CONFIG_CMD_GPIO=y


注: 在执行 make xxx_defconfig 生成 .config 时,会将 mx6ull_kodo_emmc_defconfig 中定义的配置项写入到 .config 文件中,如:
image
image

2、添加 mx6ull_kodo_board.h 配置文件

在 /include/configs 目录下定义了开发板的配置头文件 ,复制 mx6ullevk.h 重命名为 mx6ull_kodo_board.h 并修改文件中的条件编译,如下:


/*

 * Copyright (C) 2016 Freescale Semiconductor, Inc.

 *

 * Configuration settings for the Freescale i.MX6UL 14x14 EVK board.

 *

 * SPDX-License-Identifier: GPL-2.0+

 */

#ifndef __MX6ULL_KODOBOARD_CONFIG_H

#define __MX6ULL_KODOBOARD_CONFIG_H


#include

#include

#include 'mx6_common.h'

#include


3、添加 mx6ull_kodoboard 板级文件夹

添加板级文件,在 /board/freescale 目录下,复制 mx6ullevk 文件夹重命名为 mx6ull_kodoboard 并修改文件夹内的文件名,文件夹中内容对比如下:
image

将板级文件名修改为自定义的开发板名称,这里修改 mx6ullevk.c 文件为 mx6ull_kodoboard.c 文件。还需要修改 imximage.cfg 、Kconfig、Makefile中的内容,依次如下所示:


(1) imximage.cfg 文件:文件定义了 i.mx6ull 芯片启动的头部信息

#ifdef CONFIG_USE_PLUGIN/*PLUGIN    plugin-binary-file    IRAM_FREE_START_ADDR*/PLUGIN board/freescale/mx6ull_kodoboard/plugin.bin 0x00907000  //指向mx6ull_kodoboard目录#else

注:必须指向 /board/freescale/mx6ull_kodoboard 目录 plugin.bin 文件。


(2)Kconfig文件:执行 xxx_defconfig 时被调用

if TARGET_MX6ULL_KODO_EMMCconfig SYS_BOARD default 'mx6ull_kodoboard'           //定义自定义板级文件夹名config SYS_VENDOR default 'freescale'                  //使用芯片厂商config SYS_CONFIG_NAME default 'mx6ull_kodo_board'          //开发板的配置头文件名endif

注:①、②、③、④、⑤

①、if TARGET_MX6ULL_KODO_EMMC 配置项

正确定义:CONFIG_TARGET_MX6ULL_KODO_EMMC=y

image
错误定义:CONFIG_TARGET_MX6ULL_KODO_EMMC_1=y
image
make xxx_defconfig 生成 .config 时,会根据 mx6ull_kodo_emmc_defconfig 中的 “CONFIG_TARGET_MX6ULL_KODO_EMMC=y” 配置项,使用'if TARGET_MX6ULL_KODO_EMMC'来决定 Kconfig 文件中的内容是否要写入到 .config 文件中去 ,所以:
'TARGET_MX6ULL_KODO_EMMC' : 必须与 “CONFIG_TARGET_MX6ULL_KODO_EMMC=y” 中的内容一致。

② default 'mx6ull_kodoboard' 配置项
image
make 执行时会到文件夹名字为 'mx6ull_kodoboard' 的目录下寻找 Makefile 文件,所以:
'mx6ull_kodoboard': 必须与 /board/freescale 目录下自定义的板级文件夹名字相同。

③ default 'freescale' 配置项
image
make 执行时会到文件夹名为 'freescale' 的目录下寻找名为 'mx6ull_kodoboard' 的文件夹下的 Makefile 文件,所以:
'freescale' :必须与 /board 目录下个产商板级文件夹名字相同。

④ default 'mx6ull_kodo_board' 配置项
错误定义:default 'mx6ull_kodo_board_1'
image
导致 config.h 错误引用:mx6ull_kodo_board_1.h
image
导致编译报错:/include/configs 目录下没有 mx6ull_kodo_board_1.h 文件
image
make 执行过程中会生成 config.h 文件,config.h 文件会引用 /include/configs 目录下名为 'mx6ull_kodo_board' 的头文件,所以:
'mx6ull_kodo_board' :必须与 /include/configs 目录下自定义的配置头文件名相同。

⑤ 在执行 make xxx_defconfig 生成 .config 时,会将 Kconfig 中定义的配置项写入到 .config 文件中
image

(3)Makefile文件:

# (C) Copyright 2015 Freescale Semiconductor, Inc.## SPDX-License-Identifier: GPL-2.0+#obj-y  := mx6ull_kodoboard.o                  #依赖mx6ull_kodoboard.c文件extra-$(CONFIG_USE_PLUGIN) :=  plugin.bin$(obj)/plugin.bin: $(obj)/plugin.o $(OBJCOPY) -O binary --gap-fill 0xff $< $@

注:obj-y :依赖 /board/freescale/mx6ull 目录下的mx6ull_kodoboard.c文件


4、修改 Kconfig 文件

修改 /arch/arm/cpu/armv7/mx6/Kconfig 文件,添加开发板配置项:


config TARGET_MX6ULL_KODO_EMMC bool 'mx6ull_kodo_emmc' select MX6ULL select DM select DM_THERMAL

image

并在文件尾部添加如下内容:

source 'board/freescale/mx6ull_kodoboard/Kconfig'

image

5、LCD 驱动修改

一般 uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的,

比如 mx6ull_kodoboard.h 和 mx6ull_kodoboard.c 这两个文件。

一般修改 LCD 驱动重点注意以下几点:

①、LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。

②、LCD 背光引脚 GPIO 的配置。

③、LCD 配置参数是否正确。


开发板 LCD 的 IO 和背光 IO 和 NXP 官方 I.MX6ULL 开发板一致,所以 IO 部分就不用修改了。只需要修改 LCD 参数,打开文件 mx6ull_kodoboard.c,找到如下所示内容:


struct display_info_t const displays[] = {{    .bus = MX6UL_LCDIF1_BASE_ADDR,    .addr = 0,    .pixfmt = 24,    .detect = NULL,    .enable = do_enable_parallel_lcd,    .mode = {        .name = 'TFT43AB',        .xres = 480,        .yres = 272,        .pixclock = 108695,        .left_margin = 8,        .right_margin = 4,        .upper_margin = 2,        .lower_margin = 4,        .hsync_len = 41,        .vsync_len = 10,        .sync = 0,        .vmode = FB_VMODE_NONINTERLACED} } };

示例代码中定义了一个变量 displays,类型为 display_info_t,这个结构体是 LCD 信息结构体,其中包括了 LCD 的分辨率,像素格式,LCD 的各个参数等,定义在文件 arch/arm/include/asm/imx-common/video.h 中,定义如下:


struct display_info_t {    int bus;    int addr;    int pixfmt;    int (*detect)(struct display_info_t const *dev);    void (*enable)(struct display_info_t const *dev);    struct fb_videomode mode;};

pixfmt 是像素格式,也就是一个像素点是多少位,如果是 RGB565 的话就是 16 位,如果是 888 的话就是 24 位,一般使用 RGB888。结构体 display_info_t 还有个 mode 成员变量,此成员变量也是个结构体,为 fb_videomode,定义在文件 include/linux/fb.h 中,定义如下:


struct fb_videomode {    const char *name; /* optional */    u32 refresh; /* optional */    u32 xres;    u32 yres;    u32 pixclock;    u32 left_margin;    u32 right_margin;    u32 upper_margin;    u32 lower_margin;    u32 hsync_len;    u32 vsync_len;    u32 sync;    u32 vmode;    u32 flag;};

结构体 fb_videomode 里面的成员变量为 LCD 的参数,这些成员变量函数如下:


name:LCD 名字,要和环境变量中的 panel 相等。xres、yres:LCD X 轴和 Y 轴像素数量。pixclock:像素时钟,每个像素时钟周期的长度,单位为皮秒。left_margin:HBP,水平同步后肩。right_margin:HFP,水平同步前肩。upper_margin:VBP,垂直同步后肩。lower_margin:VFP,垂直同步前肩。hsync_len:HSPW,行同步脉宽。vsync_len:VSPW,垂直同步脉宽。vmode:大多数使用 FB_VMODE_NONINTERLACED,也就是不使用隔行扫描。

像素时钟 pixclock 的含义:以正点原子的 7 寸 1024*600 分辨率的屏幕(ATK7016)为例,屏幕要求的像素时钟为 51.2MHz,因此:


pixclock=(1/51200000)*10^12=19531

移植使用的LCD为4.3寸800x480的屏幕,最终修改的配置参数如下:


struct display_info_t const displays[] = {{ .bus = MX6UL_LCDIF1_BASE_ADDR,         //LCD base address .addr = 0, .pixfmt = 24,                          //RGB 24 BIT .detect = NULL,                        

.enable = do_enable_parallel_lcd,      //RESET AND ENABLE .mode = { .name = 'KODO_TFT4384', .xres           = 800, .yres           = 480, .pixclock       = 32258,       //PIXCLOCK = (1/31000000)*10^12 .left_margin    = 88, .right_margin   = 40, .upper_margin   = 32, .lower_margin   = 12, .hsync_len      = 48, .vsync_len      = 3, .sync           = 0, .vmode          = FB_VMODE_NONINTERLACED} } };size_t display_count = ARRAY_SIZE(displays);#endif

除修改屏幕参数,还需修改默认的屏幕环境变量,在mx6ull_kodoboard.h 文件中找到所有如下语句:


panel=TFT43AB

将其改为:


panel=KODO_TFT4384

也就是设置 panel 为 KODO_TFT4384,panel 的值要与屏幕参数结构体中的.name 成员变量的值一致。


6、网络驱动修改

LAN8720A 内部是有寄存器的,I.MX6ULL 会读取 LAN8720 内部寄存器来判断当前的物理链接状态、连接速度(10M 还是 100M)和双工状态(半双工还是全双工)。


I.MX6ULL 通过 MDIO 接口来读取 PHY 芯片的内部寄存器,MDIO 接口有两个引脚,ENET_MDC 和 ENET_MDIO,ENET_MDC 提供时钟,ENET_MDIO 进行数据传输。一个 MDIO 接口可以管理 32 个 PHY 芯片,同一个 MDIO 接口下的这些 PHY 使用不同的器件地址来做区分,MIDO 接口通过不同的器件地址即可访问到相应的 PHY 芯片。


I.MX6U-ALPHA 开发板 ENET1 上连接的 LAN8720A 器件地址为 0X0,ENET1 引脚与 NXP 官方的 I.MX6ULL EVK 开发板基本一样,唯独复位引脚不同,所示要修改 ENET1 网络驱动的话重点就三点:

①、ENET1 复位引脚初始化。

②、LAN8720A 的器件 ID。

③、LAN8720 驱动


ENET2 网络驱动的修改也注意一下三点:

①、ENET2 的复位引脚,从图 33.2.7.2 可以看出,ENET2 的复位引脚 ENET2_RST 接到了 I.MX6ULL 的 SNVS_TAMPER8 上。

②、ENET2 所使用的 PHY 芯片器件地址为 0X1。

③、LAN8720 驱动,ENET1 和 ENET2 都使用的 LAN8720,所以驱动肯定是一样的。


在 uboot 中使用网络之前要先设置几个环境变量,命令如下:


setenv ipaddr 192.168.1.55       //开发板 IP 地址setenv ethaddr b8:ae:1d:01:00:00 //开发板网卡 MAC 地址setenv gatewayip 192.168.1.1     //开发板默认网关setenv netmask 255.255.255.0     //开发板子网掩码setenv serverip 192.168.1.250    //服务器地址,也就是 Ubuntu 地址saveenv                          //保存环境变量

二、自定义开发板参数如何被写入 .config ,以及如何参与源码编译的

make xxx_defconfig

前面分析 U-boot 顶层 Makefile 时,执行该命令后会生成一个 conf 的软件 ,然后调用 conf 软件去执行源码根目录下的 Kconfig 文件,最终命令如下:


@ scripts/kconfig/conf --defconfig=arch/../configs/xxx_defconfig Kconfig

打开源码根目录的 Kconfig 文件,有以下内容:


## For a description of the syntax of this configuration file,# see Documentation/kbuild/kconfig-language.txt.#mainmenu 'U-Boot $UBOOTVERSION Configuration'config UBOOTVERSION string option env='UBOOTVERSION'# Allow defaults in arch-specific code to override any given heresource 'arch/Kconfig'menu 'General setup'

对比 menuconfig 配置界面:

image
图中的第一项配置 Architecture select 和 第二项配置 ARM architecture 应该在 source 'arch/Kconfig' 包含的文件中定义,打开 /arch 目录下的 Kconfig 文件,有以下定义:
image
正好对应第一项配置 Architecture select ,该配置为“使用芯片所属架构”的配置,ARM架构对应 ARM architecture ,该文件后面调用了 'arch/arm' 目录下的 Kconfig 文件:
image
'arch/arm' 目录下的 Kconfig 文件中有以下内容 :
image
正好对应第二项配置 ARM architecture,该配置为“不同厂商不同系列的ARM架构芯片”的配置,其中就有 Freescale 的 MX6 系列,如下:
image
该文件调用了 'arch/arm/cpu/armv7/mx6' 目录下的 Kconfig 文件,如下:
image
打开 'arch/arm/cpu/armv7/mx6' 目录下的 Kconfig 文件,在移植 U-BOOT 时恰好在该文件中添加了自定义开发板的内容,如下:
image
image

该文件调用了 /board/freescale 目录下自定义的开发板板级文件夹 mx6ull_kodoboard 目录下的 Kconfig 文件,其内容如下:
image
而在 /configs 目录下自定义的 mx6ull_kodo_emmc_defconfig 文件中有以下定义:
image

在执行make xxx_defconfig 时,传入 mx6ull_kodo_emmc_defconfig 文件中定义的配置项,Kconfig 读取配置项的值来使能响应的功能,并把结果写入到 .config 文件中,其内容大致如下图所示:
image
图中内容与 Makefile 语法中的变量定义一样,于是可以在 Maakefile 中直接调用,完成源码的编译。


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 家用电器遥控器

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • DS1669数字电位器

  • HA1377 桥式放大器 BCL 电容 17W(汽车音频)

    相关电子头条文章