打印
[研电赛技术支持]

RT-Thread框架下,ENET初始化结束后,重新设置MAC方法

[复制链接]
401|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
coshi|  楼主 | 2023-7-12 10:23 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
前言
众所周知,每个以太网设备都有一个唯一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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

95

主题

3308

帖子

4

粉丝