2010年(49)
分类: 嵌入式
2010-09-07 11:58:26
在系统启动后,VxWorks产生tUsrRoot任务初始化网络。usrRoot()调用usrNetInit(); 在usrNetInit()中调用sockLibAdd(),sockLibAdd()再调用bsdSockLibInit来添加BSD socket 库接口。在usrNetInit()中还调用usrNetProtoInit()来初始化各种协议。usrNetInit()还调用muxDevLoad()和ipAttach()。muxDevLoad()然后调用驱动中的endLoad()函数。
在muxDevLoad()加载驱动之后,调用muxDeStart()函数,它调用驱动中的endStart()函数。endStart()函数应该激活驱动并且用相应的中断连接程序把中断服务程序连接到相应的结构和BSP中。
系统调用ipAttach()函数,而该函数调用muxBinds()函数,绑定协议栈到MUX上的一个指定的网络接口。当一个网络接口被关闭时,ipDetach()函数将释放网络接口所关联的TCP/IP堆栈模块。
Vxworks将根据下面的数据来加载网络接口,特别是END_TBL_ENTRY
endDevTbl []数组中每一项代表着一个网络接口。
在configNet.h中,将网口信息写入endDevTbl数组,数组的类型为END_TBL_ENTRY,END_TBL_ENTRY结构定义如下:
Typedef struct end_tbl_entry
{
Int unit;代表设备号,从0起始……
END_OBJ*(*endloadFunc)(char*,void*);指向设备的xxxendload()函数
Char* endLoadString;对该设备的初始化数据,实际被调用时,unit是被合并到前端的。
BOOL endLoan;是否借出缓存
Void* pBSP;bsp私有信息
BOOL processed;此设备单元是否已经被处理
}END_TBL_ENTRY;
在giga中定义了如下结构数组:
END_TBL_ENTRY endDevTbl [] =
{
{ 0, FEC_LOAD_FUNC,
FEC_LOAD_STRING, 1, NULL, FALSE},
{ 0, END_TBL_END, NULL, 0, NULL, FALSE},
};
第一个数组元素即为我们的网络设备motfec
0
第二个数组元素是vxworks自带的设备结束标志,在加载设备时发现END_TBL_END则停止加载。
在END_TBL_ENTRY结构中,最重要的两个变量是END_OBJ*(*endloadFunc)(char*,void*)和Char* endLoadString ,下面首先解释endLoadString,而endloadFunc将在下一节进行解释。
注意IP_MAX_UNITS这个宏的定义,它表示最多可以向网络栈绑定多少个网络接口。当然绑定网络接口到网络栈是使用ipAttach来完成的。在ipAttach的源码中,会有判定limit值,该值用ipMaxUnits来赋值,而ipMaxUnits的值来源于IP_MAX_UNITS这个宏。
endLoadString是一个由“:”分隔的字符串,它的意义如下:
:
(1)motFecAddr:即IMMR的值。Fec的寄存器集相对于IMMR的偏移量为0x0E00~0x1FFF。
(2)ivec:fec的中断向量
(3)bufBase:fec使用外部存储器的空间作为缓存,这是缓存基址。-1(NONE)代表系统默认。
(4)fifoTxBase:指明发送队列在内部存储器中的基址。-1(NONE)代表系统默认。
(5)fifoRxBase:指明接收队列在内部存储器中的基址。-1(NONE)代表系统默认。
(6)tbdNum:指定txbd的数目。系统默认至少为0x40。
(7)rbdNum:指定rxbd的数目。系统默认至少为0x30。
(8)phyAddr: This parameter specifies the logical address of a
MII-compliant physical device (PHY) that is to be used as a physical media on
the network。这是注释原文,经过斟酌,phyAddr可以认为它特指网卡芯片中配置为mac phy模式的物理地址。但是,vxworks提供的motfecend.c文件模板并不能兼容所有的网卡芯片,比如我们用的88e6095,当0x10口配置为mac phy模式时根本不存在phy寄存器,此时必须通过自己编程使的0x10口的mac和mii phy匹配(包括speed,fulldplux/halfdplux,flow contrl,link up or down)。
(9)isoPhyAddr:This parameter specifies the logical address of a
MII-compliant physical device (PHY) that is to be electrically isolated by the
management interface. 如果设定为0xff,那么表示当前没有isolated phy;如果不为oxff,那么如果能探测到该phy的存在,就使其isolated(端口隔离)。注意:88e6095芯片的物理地址0x07~0x00的范围内的isolated位是只读的,所以对其进行写操作会返回错误。
(10)phyDefMode:This parameter specifies the operating mode that will be
set up by the default physical layer initialization routine in case all the
attempts made to establish a valid link failed.如果auto- negotiation结束后仍然没能协商好phy的工作模式,那么就使用phyDefMode指定的模式。
(11)userFlags:用户通过设置该值可以控制DRV_CTRL *pDrvCtrl中的初始值,很重要。
#define MOT_FEC_USR_PHY_NO_AN 0x00000001 /*
do not auto-negotiate */
#define MOT_FEC_USR_PHY_TBL 0x00000002 /*
use negotiation table */
#define MOT_FEC_USR_PHY_NO_FD 0x00000004 /*
do not use full duplex */
#define MOT_FEC_USR_PHY_NO_100 0x00000008 /*
do not use 100Mbit speed */
#define MOT_FEC_USR_PHY_NO_HD 0x00000010 /*
do not use half duplex */
#define MOT_FEC_USR_PHY_NO_10 0x00000020 /*
do not use 10Mbit speed */
#define MOT_FEC_USR_PHY_ISO 0x00000100 /*
isolate a PHY */
#define MOT_FEC_USR_SER 0x00000200 /*
7-wire serial interface */
#define MOT_FEC_USR_LOOP 0x00000400 /*
loopback mode */
/* only use it for testing */
#define MOT_FEC_USR_HBC 0x00000080 /*
perform heartbeat control */
(12)clockSpeed:
注:endLoadString详见Tornado Online Manuals中的《vxworks_drivers_api_reference_5.5》或motFecEnd.c文件起始处的注释部分。
MuxDevLoad()=>End_load()
MUX接口是网络协议层和驱动程序之间的转接程序。在usrRoot()函数中通过调用函数muxDevLoad()来加载网络设备的驱动程序,而muxDevLoad()的主要动作会调用函数end_load()函数。End_load()函数属于驱动程序的加载函数,它主要的任务是初始化数据结构END_OBJ,END_OBJ是该函数的返回值。此时,注意END_OBJ结构中的数据结构net_funcs,它里面保存了指向各个驱动程序的指针。
这样,在初始化完成后当使用该网络设备时,就能调用正确的驱动函数。
EndLoad函数实际上被系统调用两次,第一次调用时入口参数并不是上述的endloadstirng,而是一个内容为空的字符指针用于获取设备名;第二次调用则会把END_TBL_ENTRY中的unit和endloadstring合并成一个string(当然uint放在最前端,并用:和endloadstring连接)。
(1)pDrvCtrl = (DRV_CTRL *) calloc (sizeof (DRV_CTRL), 1);
新建pDrvCtrl结构变量,类型为DRV_CTRL
补充:
初始化改结构,需要注意这个结构里面的有些指向scc的寄存器及param ram的地址。
(2)motFecInitParse (pDrvCtrl, initString)
对网口FEC的初始化字符串进行分解并赋值给pDrvCtrl结构内部相应的变量。
(3)motFecInitMem (pDrvCtrl)
初始化FEC需要使用的内存空间initialize memory,本质是对pDrvCtrl结构中与内存有关的变量初始化。
(4)SYS_FEC_ENET_ADDR_GET (enetAddr);
获得MAC地址。
(5)MOT_FEC_MII_SEM_CREATE;
MOT_FEC_GRA_SEM_CREATE;
产生信号量,用于设备的同步与互斥。
(6)END_OBJ_INIT
初始化END_OBJ。
muxDevStart()=>EndStart()
(1)FEC硬件初始化
(2)配置设备结构DRV_CTRL *pDrvCtrl
(3)mii phy物理层芯片的初始化
(1)MOT_FEC_ETH_SET
设置ECNTRL 寄存器pinmux位,使能FEC。
(2)motFecReset()
设置ECNTRL 寄存器reset位,reset FEC设备,并再次使能FEC。
(3)motFecTbdInit()
初始化发送缓冲环。
(4)motFecRbdInit()
初始化接收缓冲环。
(5)SYS_FEC_INT_CONNECT
连接FEC中断到指定的中断入口函数motFecInt()
(6)SYS_FEC_INT_ENABLE
FEC中断使能。
(7)SYS_FEC_ENET_ENABLE->sysFecEnetEnable()
选择使用PortD口作为MII接口。
包括管脚初始化:数据管脚,时钟管脚及时钟选择。
(8)motFecPrePhyConfig()
对FEC中与物理层芯片无关的寄存器进行配置,与motFecPostPhyConfig()相对。
(9)motFecPhyPreInit()
对物理层芯片初始化做准备,为下一个函数motFecPhyInit()的执行做准备。
(10)_func_motFecPhyInit ->motFecPhyInit()
初始化物理层芯片(88e6095中与FEC的mii通信的接口的物理层)。
(11)motFecPostPhyConfig()
对FEC中与物理层芯片有关的寄存器进行配置,与motFecPrePhyConfig()相对。
(12)MOT_FEC_ETH_ENABLE
设置ECNTRL 寄存器ETH位,使能ETH。
(13)MOT_FEC_RX_ACTIVATE
通过设置R_DES_ACTIVE使能接收。
第(10)步所涉及到的函数motFecPhyInit()的主要作用是初始化88e6095中与FEC的mii接口对接的那个接口即第11个口。对于该口的配置是一个非常重要的工作。