目前用的是NIOS II+LAN91C111 通过几天的学习,基本上弄清楚了LWIP底层网络芯片的初始化,初始化的主要代码在netif_add函数中, netif_add起到了一个衔接顶层协议和底层驱动的作用 netif_add调用low_level_init初始化硬件,前几天主要是phy_config失败,然后找到了在AUTO NEGOTIATION时老是TIME OUT ,开始怀疑是硬件的问题,找了很多个版本的原理图,得出的结论是引脚的配置是正确的。在AUTO NEGOTIATION用示波器量tpi tpo 各个引脚也没有波形。最后只能怀疑是连接LAN91C111和交换机的网线有问题,于是去查关于网线的定义,得知RJ45接口的1、2、3、6脚O+ O- I+ I-,究竟那一个是RJ45的一脚,对于RJ45的插座口,将引脚向上放置,从左往右,依次是1-8。再去查网线,果真是接错了。于是更改,最后虽然初始化OK了,但是PC机PINGLAN91C111却始终PING不通。
TO BE CONTINUE
今天发现为什么一直以来PING不通了,我的set_ip_addr是在main函数所在的文件中定义的,所以在//C:\altera\71\nios2eds\components\altera_lwip\UCOSII\src\alt_lwip_dev.c
文件中调用get_ip_addr编译时找不到这个函数,但是NIOSII IDE从来没有报过错。同样
//C:\altera\71\ip\sopc_builder_ip\altera_avalon_lan91c111\UCOSII\src、altera_avalon_lan91c111.c调用get_mac_addr连接器也找不到这个函数。发现NIOSII IDE做的实在是太差了。解决的办法是在/C:\altera\71\nios2eds\components\altera_lwip\UCOSII\src\alt_lwip_dev.c文件中加入get_ip_add,建立好工程后,在工程树状视图的Device Drivers [Sopc Builder]-〉altera_avalon_lan91c111-〉UCOSII-〉src-〉altera_avalon_lan91c111.c中加入get_mac_addr函数。
现在将NIOS对LAN91C111的初始化过程分析如下:
在MAIN程序中,应用程序首先调用lwip_stack_init函数对IP协议栈进行初始化
对lwip_stack_init的定义在
C:\altera\71\nios2eds\components\altera_lwip\UCOSII\src\alt_lwip_dev.C中
如下所示:
void lwip_stack_init(int thread_prio, void (* initfunc)(void *), void *arg)
{
sys_init();
#ifdef STATS
stats_init();
#endif /* STATS */
mem_init();
memp_init();
pbuf_init();
netif_init();
tcpip_init(thread_prio, NULL, NULL);
return;
}
该函数的第二个参数为指向函数initfunc的指针,initfunc在tcpip_init(thread_prio, NULL, NULL)执行后执行,initfunc由用户定义,在initfunc中调用lwip_devices_init(C:\altera\71\nios2eds\components\altera_lwip\UCOSII\src\alt_lwip_dev.C)
对底层硬件进行初始化,lwip_devices_init主要完成两个工作,一是对网络接口进行初始化netif_add,二是设置IP地址netif_set_addr。网络接口的初始化函数是netif_add是一个相当重要的函数,该函数是一个联系底层硬件和上层IP协议栈的桥梁。硬件设备驱动程序中,lwIP用一个类似于BSD的网络接口结构来描述物理硬件。 网络接口被连成一个全局链表(global linked list)。 该函数就是将我们要操作的网络接口加入到这个链表中。结构体netif在netif.h中定义如下:
struct netif {
struct netif *next;
struct ip_addr ip_addr;
struct ip_addr netmask;
struct ip_addr gw;
err_t (* input)(struct pbuf *p, struct netif *inp);
err_t (* output)(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
void *state;
#if LWIP_DHCP
struct dhcp *dhcp;
#endif
unsigned char hwaddr_len;
unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];
u16_t mtu;
u8_t flags;
u8_t link_type;
char name[2];
u8_t num;
};
对netif结构体的说明可以参考LWIP的手册。
netif_add的声明如下所示
struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
struct ip_addr *gw,
void *state,
err_t (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif));
在netif_add中主要又调用了err_t (* init)(struct netif *netif)函数,在NIOS中这个函数为err_t alt_avalon_lan91c111_init(struct netif *netif)
(C:\altera\71\ip\sopc_builder_ip\altera_avalon_lan91c111\UCOSII\src\ altera_avalon_lan91c111.c)在该函数中调用了low_level_init(终于接触硬件了,在这个函数中完成了硬件的初始化)
对硬件的初始化分为如下几步:
1. reset_device
2. set_mac_address
3. configure_phy
4. allocate_tx_packet
reset_device就是对LAN91C111的复位寄存器进行操作,完成软件复位,读取chip_id,,向
configure_phy对PHY MII寄存器操作,根据Datasheet中的 MI Serial Port Frame Timing Diagram对PHY MII寄存器进行操作。
TO BE CONTINUE
发表于 @ 2007年08月23日 22:02:00|评论(loading...)|编辑