NIOS II網路驅動程序分析(1)

admin @ 2014-03-26 , reply:0

    網路是嵌入式應用的常備功能,在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)已經有1067次圍觀

http://cocdig.com/docs/show-post-43272.html