[I.MX6UL] U-Boot移植(六) 网络驱动修改 LAN8720A

[I.MX6UL] U-Boot移植(六) 网络驱动修改 LAN8720AI.MX6UL/ULL内部有个以太网MAC外设,也就是ENET,需要外接一个PHY芯片来实现网络通信功能,也就是内部MAC+外部PHY芯片的方案。I.MX6UL/ULL有两个网络接口ENET1和ENET2,I.MX6U-ALPHA开发板提供了这两个网络接口,其中ENET1和ENET2都使用LAN8720A作为PHY芯片。NXP官方的I.MX6ULLEVK开发板使用KSZ8081这颗PHY芯片,LAN8720A相比KSZ8081具有体积小、.

大家好,又见面了,我是你们的朋友全栈君。

I.MX6UL/ULL 内部有个以太网 MAC 外设,也就是 ENET,需要外接一个 PHY 芯片来实现网络通信功能,也就是内部MAC+外部 PHY 芯片的方案。

I.MX6UL/ULL 有两个网络接口 ENET1 和 ENET2,I.MX6U-ALPHA 开发板提供了这两个网络接口,其中 ENET1 和 ENET2 都使用 LAN8720A 作为 PHY 芯片。

NXP 官方的I.MX6ULL EVK 开发板使用 KSZ8081 这颗 PHY 芯片,LAN8720A 相比 KSZ8081 具有体积小、外围器件少、价格便宜等优点。
直接使用 KSZ8081 固然可以,但是我们在实际的产品中不一定会使用 KSZ8081,有时候为了降低成本会选择其他的 PHY 芯片。
这个时候就有个问题:换了PHY 芯片以后网络驱动怎么办?为此,I.MX6U-ALPHA 开发板将 ENET1 和 ENET2的 PHY 换成了LAN8720A,这样就可以给大家讲解更换 PHY 芯片以后如何调整网络驱动,使网络工作正常。
在这里插入图片描述
I.MX6U-ALPHA 开发板的 ENET1 引脚与 NXP 官方的 I.MX6ULL EVK 开发板基本一样,唯独复位引脚不同。从图可以看出,I.MX6U-ALPHA 开发板的 ENET1 复位引脚ENET1_RST 接到了 I.M6ULL 的SNVS_TAMPER7 这个引脚上。

LAN8720A 内部是有寄存器的,I.MX6ULL 会读取 LAN8720 内部寄存器来判断当前的物理链接状态、 连接速度(10M 还是 100M)和双工状态(半双工还是全双工)。 I.MX6ULL 通过 MDIO接口来读取 PHY 芯片的内部寄存器,MDIO 接口有两个引脚,ENET_MDC 和 ENET_MDIO, ENET_MDC 提供时钟,ENET_MDIO 进行数据传输。一个 MIDO 接口可以管理 32 个 PHY 芯片,同一个 MDIO 接口下的这些 PHY 使用不同的器件地址来做区分,MIDO 接口通过不同的器件地址即可访问到相应的 PHY 芯片。I.MX6U-ALPHA 开发板 ENET1 上连接的 LAN8720A器件地址为 0X0,
所以我们要修改 ENET1 网络驱动的话重点就三点:

①、ENET1 复位引脚初始化。 ENET1_RST –>SNVS_TAMPER7
②、LAN8720A 的器件 ID。0x0
③、LAN8720 驱动

在这里插入图片描述

修改 ENET2网络驱动的话重点就三点:

①、ENET1 复位引脚初始化。 ENET1_RST –>SNVS_TAMPER8
②、LAN8720A 的器件 ID。0x1
③、LAN8720 驱动

下面开始修改文件。

  1. 终端输入:gedit include/configs/mx6ull_mybsp_emmc.h

下图为修改后:
在这里插入图片描述

  1. 删除 uboot 中 74LV595 的驱动代码,因为 NXP 官方I.MX6ULL EVK 开发板使用 74LV595 来扩展
    IO,两个网络的复位引脚就是由 74LV595 来控制的。I.MX6U-ALPHA 开发板并没有使用
    74LV595,因此我们将代码删除掉。

终端输入:gedit board/freescale/mx6ull_mybsp_emmc/mx6ull_mybsp_emmc.c

修改前:

#define IOX_SDI IMX_GPIO_NR(5, 10)
#define IOX_STCP IMX_GPIO_NR(5, 7)
#define IOX_SHCP IMX_GPIO_NR(5, 11)
#define IOX_OE IMX_GPIO_NR(5, 8)

修改后:

#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)
  1. ENET1 的复位引脚连接到 SNVS_TAMPER7 上,对应 GPIO5_IO07,ENET2 的复位引脚连 接到
    SNVS_TAMPER8 上,对应 GPIO5_IO08。
    继续在 mx6ull_mybsp_emmc.c 中找到如下代码,将这个结构体全部删除:
static iomux_v3_cfg_t const iox_pads[] = { 
    
    /* IOX_SDI */ 
    MX6_PAD_BOOT_MODE0__GPIO5_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), 
    /* IOX_SHCP */ 
    MX6_PAD_BOOT_MODE1__GPIO5_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), 
    /* IOX_STCP */ 
    MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), 
    /* IOX_nOE */ 
    MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL), 
}; 
  1. 继续在mx6ull_mybsp_emmc.c 中找到函数 iox74lv_init和iox74lv_set,将这两个函数全部删除掉!
  2. 在 mx6ull_mybsp_emmc.c 中找到 board_init 函数,此函数是板子初始化函数,会被board_init_r 调用。

board_init 会调用 imx_iomux_v3_setup_multiple_pads 和 iox74lv_init 这两个函数来初始化
74lv595 的 GPIO,将这两行删除掉。至此,mx6ull_mybsp_emmc.c 中关于 74LV595 芯片的驱
动代码都删除掉了。在这里插入图片描述

添加 I.MX6U-ALPHA 开发板网络复位引脚驱动

在 mx6ull_mybsp_emmc.c 中找到关键词:
①static iomux_v3_cfg_t const fec1_pads[]
②static iomux_v3_cfg_t const fec2_pads[]

需要追加下面内容:
在这里插入图片描述

MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),/* 初始化ETH1 RESET引脚 */

在这里插入图片描述

MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),/* 初始化ETH2 RESET引脚 */

继续在文件 mx6ull_mybsp_emmc.c 中找到函数 setup_iomux_fec。将这两个 IO 设置为输出并且硬件复位一下 LAN8720A,这个硬件复位很重要!否则可能导致 uboot 无法识别 LAN8720A。
追加内容如下:
在这里插入图片描述

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(100);
		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(100);
		gpio_set_value(ENET2_RESET, 1);
	}
}

修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link

uboot 中的 LAN8720A 驱动有点问题,打开文件drivers/net/phy/phy.c,找到函数 genphy_update_link,这是个通用 PHY 驱动函数,此函数用于更新 PHY 的连接状态和速度。

终端输入:gedit drivers/net/phy/phy.c
搜索关键字:genphy_update_link
修改如下:
在这里插入图片描述

	/* LAN8720 must software*/
#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);		/* 读取寄存器BMCR默认值 */
		phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); 	/* 软件复位,自动清零 */
		while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR) & BMCR_RESET) { 
   
			udelay(100);			
		}
		phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg); 	/* BMCR写入原来的值 */
		lan8720_flag = 1;
	}
#endif

重新编译uboot

./mx6ull_mybsp_emmc.sh
或
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_mybsp_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16

下载烧录验证:

chmod 777 imxdownload  

//给予 imxdownload 可执行权限 
./imxdownload u-boot.bin /dev/sdg 
 
//烧写 u-boot.bin 到 SD 卡中

烧写完成以后将 SD 卡插入 I.MX6U-ALPHA 开发板的 TF 卡槽中,最后设置开发板从 SD卡启动。打开 SecureCRT,设置好开发板所使用的串口并打开,复位开发板。

在 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  
//保存环境变量 

SecureCRT的uboot中使用ping命令。

ping 192.168.1.250 

在这里插入图片描述
有“host 192.168.1.250 is alive”这句,说明 ping 主机成功。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/151761.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • CMakeLists.txt 语法介绍与实例演练

    CMakeLists.txt 语法介绍与实例演练一、Cmake简介cmake是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。二、常用命令1.指定cmake的最小版本cmake_minimum_required(VERSION3.4.1)这行命令是可选的,我们可以不写这句话,但在有些情况下,如果CMakeLists.tx…

    2022年6月21日
  • 随机梯度下降优化算法_次梯度下降

    随机梯度下降优化算法_次梯度下降5、优化方法:随机梯度下降法5.1介绍在上衣章,我们介绍了图像分类任务中的两个关键部分:一个参数化的评分函数将原始图像像素映射到类得分(例如线性函数) 一个损失函数,它测量预测的分类得分与实际的分类之间的一致程度,来量化一组特定参数集的质量。我们看到有很多方法和版本(例如SoftMax、SVM)。回顾一下,线性评分函数是这样的:f(Xi,W)=WXi,SVM损失的公式为:…

    2022年9月10日
  • UNIX的常用命令

    UNIX的常用命令Unix常用命令介绍:  多命令行:“;”多行命令:“\”1、系统关闭reboot、halt/shutdown、poweroff2、passwd命令:修改系统用户密码passwd[username]3、su命令:切换系统用户su[-username]username为空表示root用户4、cat命令:将指定的文件在标准输出到显示器cat [-AbET] [文件名列表]-A      …

    2022年5月31日
  • 【数据分析报告】携程客户分析与流失预测

    【数据分析报告】携程客户分析与流失预测目录一、项目背景与目的二、探索性分析2.1数据指标预览2.2数据概况2.3数据分布2.3.1数据分布总览2.3.2预定日期和入住日期2.3.3访问时间段2.3.4客户价值2.3.5消费能力指数2.3.6价格敏感指数分布2.3.6入住酒店平均价格2.3.7酒店星级偏好2.3.8订单取消率2.3.9用户年订单数分布2.3.10新老客户流失率三、数据预处理3.1去除不需要的字段与重复字段3.2数据类型转换3.3异常值处理3.3.1负数处理3.3.2极值处理3.4缺失值处理3.

    2022年10月18日
  • 傅里叶变换 意义_傅里叶变换表达式

    傅里叶变换 意义_傅里叶变换表达式看到论坛有一个朋友提问为什么傅里叶变换可以将时域变为频域?这个问题真是问到了灵魂深处。在这我只能简单讲讲我的理解,要深刻理解翻信号处理教科书是最好的方法。1.如何描述信号我们常常用数学模型去抽象物理事件。信号也可以用数学模型来表示。有了信号的数学模型,我们就可以利用数学计算对信号模型做各种各样的改变。如果加以计算机,模电,数电的相关知识,我们就可以将我们对信号模型的改变转换为对物理信号的…

    2022年10月20日
  • c 语言条件运算符,C 语言条件运算符详细讲解

    c 语言条件运算符,C 语言条件运算符详细讲解C语言条件运算符详细讲解如果希望获得两个数中最大的一个,可以使用if语句,例如:if(a>b){max=a;}else{max=b;}不过,C语言提供了一种更加简单的方法,叫做条件运算符,语法格式为:表达式1?表达式2:表达式3条件运算符是C语言中唯一的一个三目运算符,其求值规则为:如果表达式1的值为真,则以表达式2的值作为整个条件表达式的值,否则以表达式3的值作为整…

    2022年10月2日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号