当然可能存在字符打错了之类的细节问题。我已经重复了5次以上,同样的问题没有解决。按教程来操作设备是识别不到网口2的,但是uboot原子的是能识别且呢能够ping通。我把
配置改到网口1,可以识别到,并初始化。就是ping不通。然后进linux可以ping通。当然我朋友也遇到类似的问题,他是编译器版本的问题。我这不存在,在移植的时候基本都是复制粘贴教程的内容。
既然解决不了问题,我决定去原子的uboot仔细查看他们的内容,并记录其过程
1:第一步就是配置 mx6ull_alientek_emmc_defconfig里的默认文件,咱们就复制粘贴改个名字
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ullevk/imximage-ddr512.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_14X14_EVK=y
CONFIG_CMD_GPIO=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_emmc/imximage-ddr512.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y
CONFIG_CMD_GPIO=y
不知道为什么原子的教程跟源码货不对板,可能是时间久了,这里的cfg文件就不改了,反正到时候也是复制改名
2:咱们速战速决,直接来到应该复制的freescale飞思卡尔的板集支持包的头文件内看看,当然要自己先复制一份,路径看手册就行
mx6ull_alientek_emmc.h <--> mx6ullevk.h
2.1 先把头文件的防止重定义的改了
#ifndef __MX6ULLEVK_CONFIG_H
#define __MX6ULLEVK_CONFIG_H
//修改
#ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H
#define __MX6ULL_ALIENTEK_EMMC_CONFIG_H
因为原子是有nand版本的,所以使用emmc版本的伙伴直接跳过带nand的宏定义,有兴趣的可以自己看看,我暂时没兴趣。
2.2 不知道这个图看的清除吗,反正关键是这里多了一个宏定义。
#define CONFIG_OF_BOARD_SETUP
2.3 其他的网口配置是一点没改,然后下面多了一个
#define CONFIG_PHY_REALTEK
2.4 这里的PHY一听就耳熟,这不是后面要改的phy.c文件同名吗?还有上面的board,肯定也是原子自己板子定制的宏定义,我们去看看有什么
我们在对应的c文件里找到了他的引用
如果定义这个宏就。。。,是个条件编译。它又定义了下面这个宏,ENET1不就是网口1的名字吗
我们看不懂,不管是不是真的看不懂,丢给chatai--》我用的是kimi
好,他的作用是设置对应的以太网。从这我大致知道了我们用的是网口1,那为什么教程里还是网上搜的都是网口2的设置啊
#define CONFIG_FEC_ENET_DEV 1
#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x0
#define CONFIG_FEC_XCV_TYPE RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x1
#define CONFIG_FEC_XCV_TYPE RMII
#endif
#define CONFIG_ETHPRIME "FEC"
我们搜一下FDT_PATH_ENET1 "/soc/aips-bus@02000000/ethernet@020b4000/mdio/ethernet-phy@2",在放大镜窗口搜一下。只在该文件里找到其应用,其值为一串字符串,是以太网1的接口
,好我们已经给以太网接口1判死刑了,就是它了。
2.5 这个板集宏设置算完了。回到前面的CONFIG_PHY_REALTEK这个宏,搜一下。有重大发现
它在phy.c文件里有宏编译
这个是注册驱动的,具体怎么注册就不再过多了解。
我们回到h头文件
这里几个跟video有关的文件,我就不做屏蔽了,我猜测就是nxp的芯片开机画面,就是nxp这三个字符,后面如果出问题了,我再来屏蔽它。头文件的异同算看完了。然后,咱们把几个要配置的文件复制粘贴到3里,然后再将c文件
3:改文件(粘贴)
3.1 在phy里加一个宏编译,符合原子的网络方案的初始化软复位操作
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); /* Read the default value of BCMR register */
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); /* Software reset*/
mdelay(10);
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg); /* Write the default value to BCMR register */
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);
/*
* If we already saw the link up, and it hasn't gone down, then
* we don't need to wait for autoneg again
*/
if (phydev->link && mii_reg & BMSR_LSTATUS)
return 0;
if ((phydev->autoneg == AUTONEG_ENABLE) &&
!(mii_reg & BMSR_ANEGCOMPLETE)) {
int i = 0;
printf("%s Waiting for PHY auto negotiation to complete",
phydev->dev->name);
while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
/*
* Timeout reached ?
*/
if (i > PHY_ANEG_TIMEOUT) {
printf(" TIMEOUT !\n");
phydev->link = 0;
return 0;
}
if (ctrlc()) {
puts("user interrupt!\n");
phydev->link = 0;
return -EINTR;
}
if ((i++ % 500) == 0)
printf(".");
udelay(1000); /* 1 ms */
mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
}
printf(" done\n");
phydev->link = 1;
} else {
/* Read the link a second time to clear the latched state */
mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
if (mii_reg & BMSR_LSTATUS)
phydev->link = 1;
else
phydev->link = 0;
}
return 0;
}
3.2 去arch/arm/cpu/armv7/mx6里把Kconfig修改一下,让它支持我们配置的mx6ull_alientek_emmc这个板级文件
//前面任意位置都可以加
config TARGET_MX6ULL_ALIENTEK_EMMC
bool "Support mx6ull_alientek_emmc"
select MX6ULL
select DM
select DM_THERMAL
...
...
//在末尾加上
source "board/freescale/mx6ull_alientek_emmc/Kconfig"
#endif
4:mx6ull_alientek_emmc.c文件夹
复制512的cfg进你的文件,至于为什么:因为ddr需要校准,在裸机实验的时候左盟主已经向我们展示了用nxp官方的ddr测试软件,修改要校准的inc文件,具体的配置可以看手册,这里我就直接复制了
4.1 imximage-ddr512.cfg,路径不要忘了改
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*
* Refer docs/README.imxmage for more details about how-to configure
* and create imximage boot image
*
* The syntax is taken as close as possible with the kwbimage
*/
#define __ASSEMBLY__
#include <config.h>
/* image version */
IMAGE_VERSION 2
/*
* Boot Device : one of
* spi/sd/nand/onenand, qspi/nor
*/
#ifdef CONFIG_SYS_BOOT_QSPI
BOOT_FROM qspi
#elif defined(CONFIG_SYS_BOOT_EIMNOR)
BOOT_FROM nor
#else
BOOT_FROM sd
#endif
#ifdef CONFIG_USE_PLUGIN
/*PLUGIN plugin-binary-file IRAM_FREE_START_ADDR*/
PLUGIN board/freescale/mx6ull_alientek_emmc/plugin.bin 0x00907000
#else
#ifdef CONFIG_SECURE_BOOT
CSF CONFIG_CSF_SIZE
#endif
/*
* Device Configuration Data (DCD)
*
* Each entry must have the format:
* Addr-type Address Value
*
* where:
* Addr-type register length (1,2 or 4 bytes)
* Address absolute address of the register
* value value to be stored in the register
*/
/* Enable all clocks */
DATA 4 0x020c4068 0xffffffff
DATA 4 0x020c406c 0xffffffff
DATA 4 0x020c4070 0xffffffff
DATA 4 0x020c4074 0xffffffff
DATA 4 0x020c4078 0xffffffff
DATA 4 0x020c407c 0xffffffff
DATA 4 0x020c4080 0xffffffff
DATA 4 0x020E04B4 0x000C0000
DATA 4 0x020E04AC 0x00000000
DATA 4 0x020E027C 0x00000030
DATA 4 0x020E0250 0x00000030
DATA 4 0x020E024C 0x00000030
DATA 4 0x020E0490 0x00000030
DATA 4 0x020E0288 0x000C0030
DATA 4 0x020E0270 0x00000000
DATA 4 0x020E0260 0x00000030
DATA 4 0x020E0264 0x00000030
DATA 4 0x020E04A0 0x00000030
DATA 4 0x020E0494 0x00020000
DATA 4 0x020E0280 0x00000030
DATA 4 0x020E0284 0x00000030
DATA 4 0x020E04B0 0x00020000
DATA 4 0x020E0498 0x00000030
DATA 4 0x020E04A4 0x00000030
DATA 4 0x020E0244 0x00000030
DATA 4 0x020E0248 0x00000030
DATA 4 0x021B001C 0x00008000
DATA 4 0x021B0800 0xA1390003
DATA 4 0x021B080C 0x00000000
DATA 4 0x021B083C 0x01380138
DATA 4 0x021B0848 0x40402E32
DATA 4 0x021B0850 0x40403432
DATA 4 0x021B081C 0x33333333
DATA 4 0x021B0820 0x33333333
DATA 4 0x021B082C 0xf3333333
DATA 4 0x021B0830 0xf3333333
DATA 4 0x021B08C0 0x00944009
DATA 4 0x021B08b8 0x00000800
DATA 4 0x021B0004 0x0002002D
DATA 4 0x021B0008 0x1B333030
DATA 4 0x021B000C 0x676B52F3
DATA 4 0x021B0010 0xB66D0B63
DATA 4 0x021B0014 0x01FF00DB
DATA 4 0x021B0018 0x00201740
DATA 4 0x021B001C 0x00008000
DATA 4 0x021B002C 0x000026D2
DATA 4 0x021B0030 0x006B1023
DATA 4 0x021B0040 0x0000004F
DATA 4 0x021B0000 0x84180000
DATA 4 0x021B0890 0x00400000
DATA 4 0x021B001C 0x02008032
DATA 4 0x021B001C 0x00008033
DATA 4 0x021B001C 0x00048031
DATA 4 0x021B001C 0x15208030
DATA 4 0x021B001C 0x04008040
DATA 4 0x021B0020 0x00000800
DATA 4 0x021B0818 0x00000227
DATA 4 0x021B0004 0x0002552D
DATA 4 0x021B0404 0x00011006
DATA 4 0x021B001C 0x00000000
#endif
4.2 修改Kconfig文件,当然添加的SOC那一项可选,因为我在前面的文件里看见有配置的
if TARGET_MX6ULL_14X14_EVK || TARGET_MX6ULL_9X9_EVK
config SYS_BOARD
default "mx6ullevk"
config SYS_VENDOR
default "freescale"
config SYS_CONFIG_NAME
default "mx6ullevk"
endif
//修改后
if TARGET_MX6ULL_ALIENTEK_EMMC
config SYS_BOARD
default "mx6ull_alientek_emmc"
config SYS_VENDOR
default "freescale"
config SYS_SOC
default "mx6"
config SYS_CONFIG_NAME
default "mx6ull_alientek_emmc"
endif
4.3 修改MAINTAINERS文件,为了保持一致性,教程是删了14x14和9x9.我怕出现问题就不删了,并且多添加一项我们的
MX6ULLEVK BOARD
M: Peng Fan <peng.fan@nxp.com>
S: Maintained
F: board/freescale/mx6ullevk/
F: include/configs/mx6ullevk.h
F: configs/mx6ull_14x14_evk_defconfig
F: configs/mx6ull_9x9_evk_defconfig
//修改后
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
F: configs/mx6ull_14x14_evk_defconfig
F: configs/mx6ull_9x9_evk_defconfig
F: configs/mx6ull_alientek_emmc_defconfig
4.4 修改MAKEFILE的目标文件
# (C) Copyright 2015 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := mx6ullevk.o
extra-$(CONFIG_USE_PLUGIN) := plugin.bin
$(obj)/plugin.bin: $(obj)/plugin.o
$(OBJCOPY) -O binary --gap-fill 0xff $< $@
// 修改后
# (C) Copyright 2015 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := mx6ull_alientek_emmc.o
extra-$(CONFIG_USE_PLUGIN) := plugin.bin
$(obj)/plugin.bin: $(obj)/plugin.o
$(OBJCOPY) -O binary --gap-fill 0xff $< $@
5:重头戏:改c文件
这里我们直接添加原子的网口复位按键的IO配置相关即可,不用去删nxp的,我都怀疑前面的网络设置为什么没改,估计都没起作用,那个不是条件编译吗,我怀疑都没有定义,所以直接关于nxp的网络配置都没进行编译。
5.1 添加2个IO口
#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)
5.2 到#ifdef CONFIG_FEC_MXC下面去添加这两个IO的配置,什么电气属性之类的,直接用宏真方便
MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), /* ETH1 RESET PIN */
//与
MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL), /* ETH2 RESET PIN */
//整体
#ifdef CONFIG_FEC_MXC
/*
* pin conflicts for fec1 and fec2, GPIO1_IO06 and GPIO1_IO07 can only
* be used for ENET1 or ENET2, cannot be used for both.
*/
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), /* ETH1 RESET PIN */
};
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), /* ETH2 RESET PIN */
};
5.3 修改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);
}
mdelay(150);
}
5.4 修改RGBLCD的属性,以我这个是4.3寸800*480为例,裸机程序里都有
struct display_info_t const displays[] = {{
.bus = MX6UL_LCDIF1_BASE_ADDR,
.addr = 0,
.pixfmt = 24,
.detect = NULL,
.enable = do_enable_parallel_lcd,
.mode = {
.name = "TFT4384",
.xres = 800,
.yres = 480,
.pixclock = 31746,
.left_margin = 46,
.right_margin = 210,
.upper_margin = 32,
.lower_margin = 13,
.hsync_len = 48,
.vsync_len = 3,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED
} } };
关于背光我们就先不移植了,直接接着走
5.5 复制前面提到的网口1的条件编译
#ifdef CONFIG_OF_BOARD_SETUP
#define FDT_PATH_ENET1 "/soc/aips-bus@02000000/ethernet@020b4000/mdio/ethernet-phy@2"
int ft_board_setup(void *blob, bd_t *bd)
{
int off;
int err;
unsigned int phy_value = 0;
off = fdt_path_offset(blob, FDT_PATH_ENET1);
if (off < 0) {
printf("WARNING: can't find %s node\n", FDT_PATH_ENET1);
}
if (!getenv("enet1"))
return 0;
err = fdt_setprop(blob, off, "reg", &phy_value, sizeof(phy_value));
if (err < 0)
printf("WARNING: could not set reg property, %s\n", fdt_strerror(err));
return 0;
}
#endif
灯也不移植了。
5.6 移植板名称
int checkboard(void)
{
if (is_mx6ull_9x9_evk())
puts("Board: MX6ULL 9x9 EVK\n");
else
puts("Board: I.MX6U ALPHA|MINI\n");
return 0;
}
行文至此,我们c文件移植完毕,我该去编译烧写试一下了。再不行,再ping不了,我也没办法了。
6:错误
6.1错误1:如果屏蔽掉某个条件编译不能用双斜杠,出错地点u-boot.lds,进去查看找到错误
//#define CONFIG_PHY_MICREL
arm-linux-gnueabihf-ld.bfd:u-boot.lds:1: ignoring invalid character `#' in expression
arm-linux-gnueabihf-ld.bfd:u-boot.lds:1: syntax error
Makefile:1174: recipe for target 'u-boot' failed
改为
/*#define CONFIG_PHY_MICREL*/
至此,关于一个想入行嵌入式的菜鸟已经移植成功他的uboot,开发板正点原子imx6ull-mini。版本2.2,已经移植失败5次,并求助于openedv无果。所以在这里我希望告诉大家,如果真的没人给你解答,就去逆向搞。正向的教程可能不太适合我们的板子了。就像我从咸鱼买了一个战舰的老古董,连资料都没有,原子的资料都不包含那款板子,而且板子看着就廉价,很老的版本,所以我再没买过二手的。
7:总结
检查的时候我发现了重要的一点,因为板子教程出来都是19年了,我现在的mini板子是2.2,因为
/* alientek imx6ull alpha board version <= 2.2, mini board <= 1.8, CONFIG_FEC_MXC_PHYADDR = 0x0 */
/* #define CONFIG_FEC_MXC_PHYADDR 0x0 */
所以我不用去改这个地址。
整体要操作的基本都在board里,还有配置默认设置编译defconfig,然后就是include里的h头文件
80%的selient什么的错误,肯定是你跟defconfig相关的名字错了,至于在哪,要你自己去找了。
多余的操作就是网口使用不同方案,要去修改驱动phy。移植的作用就是在通用框架下加入或修改特殊的部分。原子的配置与nxp无异,在网口方案上选择了其他方案。lcd方面屏幕的参数不会一样。多了nand版本的配置。