5

6 /* lwIP 网络接口 */

7 struct netif *netif;

8 /* 发送应答信号量 */

9 struct rt_semaphore tx_ack;

10

11 /* 网络状态标志 */

12 rt_uint16_t flags;

13 rt_uint8_t link_changed;

14 rt_uint8_t link_status;

15

16 /* 数据包收发接口 */

17 struct pbuf* (*eth_rx)(rt_device_t dev);

18 rt_err_t (*eth_tx)(rt_device_t dev, struct pbuf* p);

19};

实现数据包收发接口,对应了 eth_device 结构体中的 eth_rx 及 eth_tx 元素:

1rt_err_t rt_stm32_eth_tx(rt_device_t dev, struct pbuf* p);

2struct pbuf *rt_stm32_eth_rx(rt_device_t dev);

注册以太网设备,初始化以太网硬件,配置 MAC 地址:

1rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flags)

此函数由LAN8720的驱动rt_hw_stm32_eth_init()调用。

4.2.3.2 LAN8720驱动解析:

LAN8720网卡对象stm32_eth_device由rt_stm32_eth类创建,rt_stm32_eth类继承自eth_device类。

rt_stm32_eth的结构定义:

1struct rt_stm32_eth

2{

3 /* inherit from ethernet device */

4 struct eth_device parent;

5 rt_timer_t poll_link_timer;

6 /* interface address info, hw address */

7 rt_uint8_t dev_addr[MAX_ADDR_LEN];

8 /* ETH_Speed */

9 uint32_t ETH_Speed;

10 /* ETH_Duplex_Mode */

11 uint32_t ETH_Mode;

12};

实现rt_device设备的接口:

1static rt_err_t rt_stm32_eth_init(rt_device_t dev);

2static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag);

3static rt_err_t rt_stm32_eth_close(rt_device_t dev);

4static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size);

5static rt_size_t rt_stm32_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size);

6static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args);

rt_stm32_eth_init 用于初始化 DMA 和 MAC 控制器。

rt_stm32_eth_open 用于上层应用打开网络设备,目前未使用到,直接返回 RT_EOK。

rt_stm32_eth_close 用于上层应用关闭网络设备,目前未使用到,直接返回 RT_EOK。

rt_stm32_eth_read 用于上层应用向底层设备进行直接读写的情况,对于网络设备,每个报文都有固定的格式,所以这个接口目前并未使用,直接返回 0 值。

rt_stm32_eth_write 用于上层应用向底层设备进行直接读写的情况,对于网络设备,每个报文都有固定的格式,所以这个接口目前并未使用,直接返回 0 值。

rt_stm32_eth_control 用于控制以太网接口设备,目前用于获取以太网接口的 mac 地址。如果需要,也可以通过增加控制字的方式来扩展其他控制功能。

实现驱动层的数据包收发接口: