前言
众所周知,每个以太网设备都有一个唯一MAC地址,用于通讯,因此带以太网的主板,都需要再出厂时写入mac地址,保存,然后每次主板上电都会读出该地址,用来初始化内部mac接口。
问题来了
而rtt框架下,操作外部flash一般使用fal或者sfud组件,,enet注册成以太网设备,在设备层初始化,,此时你无法通过调用FAL组件进行读外部falsh获取,应用程序存入的mac,,因为fal所依赖的spi_flash 、sfud均未初始化。
解决方法一
不利用RTT官方组件进行读写外部flash操作,和无系统裸机实现方法一样,自己初始化外部falsh接口(iic,spi等),按芯片手册要求读写寄存器控制。然后记住写入的mac在falsh的那个位置,上电时进行读取。
解决方法二
在初始化完后,应用层进行更改MAC操作。
步骤为:
1.用FAL读取对应地址,拿出存入的mac
2.向写mcu内部的对应寄存器写MAC地址(GD32F450为 ENET_MAC_ADDR0H 和 ENET_MAC_ADDR0L)
3.修改lwip的netif_list、netdev_list结构体,放mac地址部分。
具体实现如下,为了能通过RTT框架下设备模式实现写MAC功能,更改drv_enet.c文件下的,static rt_err_t gd32_emac_control(rt_device_t dev, int cmd, void *args)的函数,增加写mac功能。
static rt_err_t gd32_emac_control(rt_device_t dev, int cmd, void *args)
{
struct gd32_emac * gd32_emac_device = (struct gd32_emac *)dev;
struct rt_synopsys_eth * ETHERNET_MAC;
uint8_t index;
ETHERNET_MAC = gd32_emac_device->ETHERNET_MAC;
switch (cmd)
{
case NIOCTL_GADDR:
/* get mac address */
if (args) memcpy(args, &gd32_emac_device->dev_addr[0], MAX_ADDR_LEN);
else return -RT_ERROR;
break;
case WRITE_MAC_ADRESS:
/* Set mac address */
if (args) memcpy(&gd32_emac_device->dev_addr[0],args,MAX_ADDR_LEN);
else return -RT_ERROR;
// gd32_emac_init(dev);
/* MAC address configuration */
EMAC_MAC_Addr_config(ETHERNET_MAC, EMAC_MAC_Address0, (uint8_t*)&gd32_emac_device->dev_addr[0]);
for (index = 0; index < netdev_list->hwaddr_len; index ++)
{
netdev_list->hwaddr[index] = gd32_emac_device->dev_addr[index];
netif_list->hwaddr[index] = gd32_emac_device->dev_addr[index];
}
default :
break;
}
return RT_EOK;
}
应用层,通过设备组件更改mac
uint8_t mac[6];
rt_device_t e0;
memset(mac, 0, sizeof( mac) );
Read_mac ( u1a_mac, sizeof ( mac) ); //内部实现调用fal组件读取mac
//拿到mac 重新初始化网口设备
e0 = rt_device_find ( "e0" );
if ( e0 != NULL )
{
/* set hardware MAC address */
rt_device_control(e0, WRITE_MAC_ADRESS, mac);
}
————————————————
版权声明:本文为CSDN博主「灵魂Maker」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36720691/article/details/128085304
|