網路是嵌入式應用的常備功能,在NIOS II中集成了UCOS II和LWIP,分析網路設備在NIOS II中的來龍去脈對學習NIOS II設備驅動程序有典型的意義。
設備的定義和系統設備聯表管理。
1. 驅動程序提供的freedev_rtl8019.h中定義一個freedev_rtl8019_if結構的全局變數dev
#define FREEDEV_RTL8019_INSTANCE(name, dev) \
freedev_rtl8019_if dev = \
{\
{\
ALT_LLIST_ENTRY,\
{\
0,\
name##_NAME,\
freedev_rtl8019_init, \
freedev_rtl8019_rx,\
},\
},\
name##_BASE,\
name##_IRQ,\
8,\
0,\
0\
}
結構freedev_rtl8019_if定義如下:
typedef struct
{
alt_lwip_dev_list lwip_dev_list;
int base_addr;
int irq;
int bus_width;
sys_sem_t semaphore;
sys_sem_t arp_semaphore;
alt_u8 tx_packet_no; /* Number of packet allocated for Tx */
}freedev_rtl8019_if;
相關結構定義如下:
typedef struct
{
alt_llist llist; /* for internal use */
alt_lwip_dev dev;
}alt_lwip_dev_list;
struct alt_lwip_dev
{
/* The netif pointer MUST be the first element in the structure */
struct netif ` *netif;
const char* name;
err_t (*init_routine)(struct netif*);
void (*rx_routine)();
};
struct netif {
/** pointer to next in linked list */
struct netif *next;
/** IP address configuration in network byte order */
struct ip_addr ip_addr;
struct ip_addr netmask;
struct ip_addr gw;
/** This function is called by the network device driver
* to pass a packet up the TCP/IP stack. */
err_t (* input)(struct pbuf *p, struct netif *inp);
/** This function is called by the IP module when it wants
* to send a packet on the interface. This function typically
* first resolves the hardware address, then sends the packet. */
err_t (* output)(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
/** This function is called by the ARP module when it wants
* to send a packet on the interface. This function outputs
* the pbuf as-is on the link medium. */
err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
/** This field can be set by the device driver and could point
* to state information for the device. */
void *state;
#if LWIP_DHCP
/** the DHCP client state information for this netif */
struct dhcp *dhcp;
#endif
/** number of bytes used in hwaddr */
unsigned char hwaddr_len;
/** link level hardware address of this interface */
unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];
/** maximum transfer unit (in bytes) */
u16_t mtu;
/** flags (see NETIF_FLAG_ above) */
u8_t flags;
/** link type */
u8_t link_type;
/** descriptive abbreviation */
char name[2];
/** number of this interface */
u8_t num;
};
由以上的結構可以分析得出:全局變數dev中包含了網路通訊的所有要素。
2. 驅動程序中freedev_rtl8019.h中還定義了FREEDEV_RTL8019_INIT(name, dev)
該宏定義最終調用alt_lwip_dev_reg(dev); 將設備全局變數註冊到系統網路設備聯表中。
#define alt_lwip_dev_reg(dev) \
alt_llist_insert(&alt_lwip_device_list, &dev.lwip_dev_list.llist)
alt_lwip_device_list是一個在alt_lwip_dev.c中定義的全局變數。第二個參數是alt_llist指針。alt_llist_insert完成雙向聯表插入操作。
以上兩個步驟在系統生成時從驅動程序.h文件中生成到alt_sys_init.c中。在系統運行時FREEDEV_RTL8019_INIT將被運行。
設備初始化
在應用程序的函數main中首先調用lwip_stack_init。函數中提供了回調函數init_done_func初始化底層網路設備。
lwip_stack_init(LWIP_TCPIP_TASK_PRIORITY, init_done_func, 0);
lwip_stack_init初始化協議棧,在TCP線程工作前調用init_done_func函數。
Init_done_func函數中對設備初始化的調用由以下函數完成,
lwip_devices_init(LWIP_RX_ETHER_TASK_PRIORITY)
在lwip_devices_init函數中調用netif_add增加網路NIC。
調用應用程序函數get_ip_addr獲取IP地址。
調用netif_set_addr設置IP地址。
注意:網路設備驅動程序的初始化在netif_add函數中被調用。
[admin via 研發互助社區 ] NIOS II網路驅動程序分析(1)已經有4268次圍觀
http://cocdig.com/docs/show-post-43272.html