基于ARM的W5100底层驱动设计
OutInt_2138 NetOutInt; //外部中断类实设备对象
NetWork_W5100
Net5100;//W5100实设备对象
Spi0_Driver_Lpc Spi0;//SPI实设备对象
Pin_LPC2138 PIN023;
//引脚实设备对象
Pin_LPC2138 PIN031;
//引脚实设备对象
接着在main.cpp采用如下代码完成Net5100和简单设备NetOutInt、Spi0、PIN023、PIN031等的关联:
NetOutInt.WorkModel=Fall_Eage;//表示下降沿触发
NetOutInt.SubDeviceName=Eint1;//表示使用外部中断1
NetOutInt.Ini();
NetOutInt.Father=&Net5100;
Net5100.SpiPort=&Spi0;//设置Spi0和SpiPort指针关联
Net5100.W5100_Cs=&
PIN023; //设置片选引脚关联
Net5100.W5100_RESET=& PIN031;
//设置复位引脚关联
在“Net5100.SpiPort=&Spi0”中SpiPort是指向某基类对象的指针,Spi0是该基类的派生类对象,该语句实现把该指针指向其派生类对象。因此就可以利用该指针直接访问该公有派生类从基类继承来的成员。同样,可以利用W5100_Cs和W5100_RESET等基类对象指针直接访问该基类的派生类——Pin_LPC2138类从基类继承下来的成员,即引脚的操作函数等。
在NetWork_W5100中有W5100_Send_Receive_Data函数就是利用这个技术,该函数如下:
char
NetWork_W5100::W5100_Send_Receive_Data(char dat){
char
i;
W5100_Cs->Clear();
i=SpiPort->SPI_Send_Receive_Data(dat);
W5100_Cs->Set();
return
i;
}
NetWork_W5100类对象能实现SPI读写操作,是因为其拥有一个SPI虚设备的指针。同理,能实现对引脚操作是因为其拥有一个引脚虚设备的指针。
3.4.2
外部中断实设备和W5100实设备关联
NetOutInt是一个外部中断类对象,使用前首先对该对象进行初始化,其中代码“NetOutInt.SubDeviceName=Eint1”表示该类对象和外部中断1产生了绑定。
在本项目测试中,W5100从网络接收到一个数据包后触发了一个外部中断1中断。该W5100实设备类对象Net5100感知该事件,从而对该事件进行处理,接着把该消息发布给其所支撑的控件。
main.cpp中有“NetOutInt.Father=&Net5100;”,其中Father是一个指针,该指针来源如下:
class
Object{
public:
……
Object
*Father;
……
};
由于所有设备类都是从该类间接继承下来,所以都拥有这个Father指针。
“NetOutInt.Father=&Net5100;”的目的是把Net5100对象地址赋给该指针,因此该指针就指向Net5100,说明NetOutInt拥有一个指向Net5100的指针。main.cpp中,外部中断1的服务程序代码如下:
void
__irq
IRQ_Eint1(){
NetOutInt.HardInt(Null);
VICVectAddr=0×00;
NetOutInt.ClearInt();
}
“NetOutInt.HardInt(Null);”其本质就是调用到HardInt函数,如下:
void
OutInt_2138::HardInt(Device*
IntDevice){
……
this->Msg.MsgID=Sys_Msg_OutInt;
this->Msg.Parm1=this->SubDeviceName;
this->Father->Message(Msg);
……
}
“this->Father->Message(Msg);”即中断服务最后把该工作交给Father指针指向的Net5100,接着该对象调用了其Message函数。NetWork_W5100类的Message函数伪代码如下:
void
NetWork_W5100::Message(MessageBody SystemMsg){
if
Socket3
SelectSocket(3);
if Socket2
SelectSocket(2);
if
Socket1
SelectSocket(1);
else
SelectSocket(0);
};
其中NetWork_W5100类的SelectSocket函数如下:
void
NetWork_W5100::SelectSocket(char socket){
uint16
address,inttype;
address=COMMON_BASE+0×100*socket+0×0402;
inttype=NetWork_Read(address);
if((inttype&0×04)==0×04){
//接收数据引起中断
S_UDP_RX_Process(socket,&ReceiveBuffer[0],&ReceiveBuffer[8]);
//从对应的Socket接收数据
Msg.MsgID=Sys_Msg_UdpGetData;
Msg.Msg=&ReceiveBuffer[0];
VclPointer[socket]->Message(Msg);
//向支撑控件发送消息
}
NetWork_Write(address,0xFF);//清除所有的中断
}
可见,W5100驱动最后把网络接收到数据包作为一个消息发给其所支撑的上层控件。
4
W5100驱动测试
4.1 测试方案
在PC机上,利用网络测试工具TCP/UDP
Socke调试工具V2.2,通过网络向W5100的终端发送一个数据包。当该终端接收到该数据包后,把该包往PC机终端发送。如果发送和接收的数据包一致,说明通信测试成功。
4.2
测试过程
PC机端的IP地址为192.168.1.103,某端口号为9000。W5100本身地址设置为192.168.1.101,某端口号为9000。PC机往W5100终端发送数据包,在如图2所示操作界面的数据发送窗口输入“Hello,
This is a happy word!”字符串后,点击“发送数据”,在操作界面的数据接收窗口接收到“Hello, This is a happy
word!”,并且在操作界面上方显示“对方IP:192.168.1.101,对方端口:9000”,这跟W5100终端设置是一致的,说明双方的通信成功。
ARM的W5100底层驱 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)