笔记

1.首先编译原厂uboot
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
2.把编译得到的uboot.bin烧进板子就可以看到那些部分是支持,那些是不支持的,不支持的就需要我们的移植工作了

2.1.SD 卡和 EMMC 驱动检查
(1)使用命令 mmc list 列出当前的 MMC 设备
(2)检查每个 MMC 设备信息

mmc dev 0 #检查emmc设备0信息
mmc info

2.2.lcd驱动一般需要修改
2.3.uboot 启动的时候提示“Board Net Initialization Failed”和“No ethernet found.”这两行,说
明网络驱动也有问题,正常情况下应该是:

NET: FEC0
3.添加默认配置文件

复制一份与自己板子接近的defconfig文件并重命名

cd configs
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_alientek_emmc_defconfig

修改mx6ull_alientek_emmc_defconfig 中的内容

CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y
CONFIG_CMD_GPIO=y

只是第 1 行和第 4 行修改成了重命名的名称。

3.添加头文件

复制一份与自己板子接近的头文件并重命名

cd include/configs
cp mx6ullevk.h mx6ull_alientek_emmc.h

修改头文件里面的头文件命名,这个头文件的主要内容就是配置或者裁剪 uboot。

4.添加板级文件夹

uboot 中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上外设驱动文件等等。NXP 的 I.MX 系列芯片的所有板级文件夹都存放在 board/freescale 目录下,在这个目录下有个名为 mx6ullevk 的文件夹,这个文件夹就是 NXP 官方 I.MX6ULL EVK 开发板的板级文件夹。

cd board/freescale/
cp mx6ullevk/ -r mx6ull_alientek_emmc

进 入 mx6ull_alientek_emmc 目 录 中 , 将 其 中 的 mx6ullevk.c 文 件 重 命 名mx6ull_alientek_emmc.c,命令如下:

cd mx6ull_alientek_emmc
mv mx6ullevk.c mx6ull_alientek_emmc.c

4.1 修改 mx6ull_alientek_emmc 目录下的 Makefile 文件

obj-y := mx6ull_alientek_emmc.o
extra-$(CONFIG_USE_PLUGIN) := plugin.bin
$(obj)/plugin.bin: $(obj)/plugin.o
$(OBJCOPY) -O binary --gap-fill 0xff $< $@

重点是第1 行的 obj-y,改为 mx6ull_alientek_emmc.o,这样才会编译 mx6ull_alientek_emmc.c这个文件。
4.2 修改imximage.cfg
将 imximage.cfg 中的下面一句:

PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000

改为:

PLUGIN board/freescale/mx6ull_alientek_emmc /plugin.bin 0x00907000

4.3 修改Kconfig

if TARGET_MX6ULL_ALIENTEK_EMMC
 
config SYS_BOARD
    default "mx6ull_alientek_emmc"
 
config SYS_VENDOR
    default "freescale"
 
config SYS_CONFIG_NAME
    default "mx6ull_alientek_emmc"
 
endif

4.4 修改 MAINTAINERS

MX6ULL_ALIENTEK_EMMC BOARD
M:  Peng Fan <peng.fan@nxp.com>
S:  Maintained
F:  board/freescale/mx6ull_alientek_emmc/
F:  include/configs/mx6ull_alientek_emmc.h

2.4:修改uboot图形界面配置文件:arch/arm/cpu/armv7/mx6/Kconfig

config TARGET_MX6ULL_ALIENTEK_EMMC
    bool "Support mx6ull_alientek_emmc"
    select MX6ULL
    select DM
    select DM_THERMAL

在最后一行的 endif 的前一行添加如下内容

source "board/freescale/mx6ull_alientek_emmc/Kconfig"
5.新建脚本编译新建的uboot
#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8

编译完成以后就使用 imxdownload 将新编译出来的 u-boot.bin 烧写到 SD 卡中测试。
此时的 Board 还是“MX6ULL 14x14 EVK”,因为我们参考的 NXP官方的 I.MX6ULL 开发板来添加自己的开发板。如果接了 LCD 屏幕的话会发现 LCD 屏幕并没有显示 NXP 的 logo,而且此时的网络同样也没识别出来。

6.修改lcd驱动

①LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。
②LCD 背光引脚 GPIO 的配置。
③LCD 配置参数是否正确。
6.1 一般驱动的配置都在xxx.h与.c文件中,在mx6ull_alientek_emmc.c中修改如下(board_init_r > init_sequence_r > stdio_add_devices > drv_video_init > board_video_skip > displays[])

struct display_info_t const displays[] = {{
    .bus = MX6UL_LCDIF1_BASE_ADDR,
    .addr = 0,
    .pixfmt = 24,
    .detect = NULL,
    .enable = do_enable_parallel_lcd,
    .mode   = {
        .name           = "TFT7016",
        .xres           = 480,
        .yres           = 272,
        .pixclock       = 19531,
        .left_margin    = 140,
        .right_margin   = 160,
        .upper_margin   = 20,
        .lower_margin   = 12,
        .hsync_len      = 20,
        .vsync_len      = 3,
        .sync           = 0,
        .vmode          = FB_VMODE_NONINTERLACED
} } };

成员变量函数如下:
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,也就是不使用隔行扫描。

可以看出,这些参数和我们第二十四章讲解 RGB LCD 的时候参数基本一样,唯一不同的像素时钟 pixclock 的含义不同,以正点原子的 7 寸 1024*600 分辨率的屏幕(ATK7016)为例,屏幕要求的像素时钟为 51.2MHz,因此:pixclock=(1/51200000)*10^12=19531。在根据其他的屏幕参数,可以得出 ATK7016 屏幕的配置参数。
打开 mx6ull_alientek_emmc.h,找到所有如下语句:

panel=TFT43AB

将其改为:

panel=TFT7016

uboot 中修改 panel 的值为 TFT7016,在 uboot 的命令模式下输入如下命令:

setenv panel TFT7016
saveenv
7.网络驱动修改

修改 ENET1 网络驱动。
①ENET1 复位引脚初始化。
②LAN8720A 的器件 ID(网络PHY地址)。
③LAN8720 驱动
ENET2同理
7.1 在mx6ull_alientek_emmc.c中修改网络PHY地址
注释的三个地方为要修改的地方。

#define CONFIG_CMD_NET#ifdef CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_FEC_ENET_DEV     	1
 
#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE            	ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR  	0x1	//要修改的网络PHY地址
#define CONFIG_FEC_XCV_TYPE         RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE            	ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR      0x0	//要修改的网络PHY地址
#define CONFIG_FEC_XCV_TYPE     	RMII
#endif
#define CONFIG_ETHPRIME         	"FEC"
 
#define CONFIG_PHYLIB
#define CONFIG_PHY_SMSC  //产品公司名称,使能 SMSC 公司的 PHY 驱动
#endif

7.2 在mx6ull_alientek_emmc.c中删除掉74LV595 的驱动代码;两个网口的复位引脚修增加如下

#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)

2.7.3:在mx6ull_alientek_emmc.c中添加复位引脚驱动

static iomux_v3_cfg_t const fec1_pads[] = {
    MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
    MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
    MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
 
static iomux_v3_cfg_t const fec2_pads[] = {
    MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
    MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
 
    MX6_PAD_ENET2_TX_DATA0__ENET2_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET2_TX_DATA1__ENET2_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
    MX6_PAD_ENET2_TX_EN__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
 
    MX6_PAD_ENET2_RX_DATA0__ENET2_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET2_RX_DATA1__ENET2_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
};

函数 setup_iomux_fec 就是根据 fec1_pads 和 fec2_pads 这两个网络 IO 配置数组来初始化I.MX6ULL 的网络 IO。我们需要在其中添加网络复位 IO 的初始化代码,并且复位一下 PHY 芯片,修改后的 setup_iomux_fec 函数如下:

static void setup_iomux_fec(int fec_id)
{
    if (fec_id == 0)
    {
        imx_iomux_v3_setup_multiple_pads(fec1_pads,
                         ARRAY_SIZE(fec1_pads));
        gpio_direction_output(ENET1_RESET, 1);
        gpio_set_value(ENET1_RESET, 0);
        mdelay(20);
        gpio_set_value(ENET1_RESET, 1);
    }
    else
    {
        imx_iomux_v3_setup_multiple_pads(fec2_pads,
                         ARRAY_SIZE(fec2_pads));
        gpio_direction_output(ENET2_RESET, 1);
        gpio_set_value(ENET2_RESET, 0);
        mdelay(20);
        gpio_set_value(ENET2_RESET, 1);
    }
}

7.4 修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link,添加如下代码段
函数 genphy_update_link,这是个通用 PHY 驱动函数,此函数用于更新 PHY 的连接状态和速度。使用 LAN8720A 的时候需要在此函数中添加一些代码,修改后的函数 genphy_update_link 如下所示:

int genphy_update_link(struct phy_device *phydev)
{
	unsigned int mii_reg;

	#ifdef CONFIG_PHY_SMSC
		static int lan8720_flag = 0;
		int bmcr_reg = 0;
		if (lan8720_flag == 0) {
			bmcr_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
			phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
			while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR) & 0X8000) {
			udelay(100);
		}
		phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg);
		lan8720_flag = 1;
		}
	#endif
	
	/*
	* Wait if the link is up, and autonegotiation is in progress
	* (ie - we're capable and it's not done)
	*/
	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
	......
	
	return 0;
}

7.5 修改网络环境变量进行ping命令测试网络
uboot启动界面显示Net: FEC1”这一行,提示当前使用的 FEC1 这个网口,也就是 ENET2。在 uboot 中使用网络之前要先设置几个环境变量,命令如下:

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

使用ping命令进行测试

ping 192.168.1.250

有“host 192.168.1.250 is alive”这句,说明 ping 主机成功,说明ENET2网络工作正常。再来测试一下ENET1的网络是否正常工作,打开mx6ull_alientek_emmc.h,将 CONFIG_FEC_ENET_DEV 改为 0,然后重新编译一下 uboot 并烧写到 SD 卡中重启。重启开发板,有“Net:FEC0”这一行,说明当前使用的 FEC0 这个网卡,也就是ENET1,同样的 ping 一下主机,显示alive说明ping主机成功!

Logo

更多推荐