具体设计思路如下:
硬件为使用串口转eib总线的电平转换设备。
eibStackCore模块(封装了从用户层到网络层的协议包)。
要开发的eibTP1Rs232Comm模块,是完成eib协议中媒体介质为TP1类型的数据链路层数据帧的编码,
和解码的功能。并操作物理层硬件。完成数据包的发送和接收功能。
eibTP1Rs232Comm模块的硬件操作接口设计思路,如下:eibTP1Rs232Comm模块主要是使用硬件设
备驱动提供的两个操作来完成数据的收发的,一个write写数据方法,个read读数据方法。模块功能
设计图如下:(图1)
_____________________________________
| |
| eibStackCore模块 |
| ---------------------------- |
| | class Layer2Interface接口 | |
---------------------------------------
通过下方法: | ^
SetDlinkLayer_Data_Req()| | DataServer.Primitive_Ind()
Set_SystemBroadcast_Req()| | SystemBroadcastServer->Primitive_Ind()
等接口方法来调用| | 等方法来调用eibStackCore模块
eibTP1Rs232模块| |
| |
V |
|-----------------------------------|
| eibTP1Rs232Comm操作串口驱动模块 |
| |--------| |--------| |
| |write() | | read() | |
|-----------------------------------|
| 写入数据到串口 ^
V |从串接收数据
|-------------------------------------|
| | 串口设备驱动 | |
| |------------------------| |
| 串口设备硬件设备模块 |
|-------------------------------------|
这里主要设计eibTP1Rs232Comm模块到串口设备之间的接口。这个接口我们定义他为eibDeviceInterface类,这个类的C++定义如下:
class eibDLAutoMachineState
{
public:
static const int eibDLAutMacState_STOP = 0;
static const int eibDLAutMacState_NONMODEIDLE = 1;
static const int eibDLAutMacState_BUSY = 2;
static const int eibDLAutMacState_WAITRESET = 4;
static const int eibDLAutMacState_BUSMONITORTIDLE = 5;
static const int eibDLAutMacState_TRANSERROR = 7;
};
class eibDeviceInterface
{
private:
Layer2Interface *m_DLsObj;
int m_AutMacState;
protected:
public:
eibDeviceInterface(void){}
~eibDeviceInterface(void){}
public:
void read(CArray c_eibdata)
{ DLsObj->OnReceive(c_eibdata); }
void regDLinkLayerSysInstance(Layer2Interface *func_dlsys)
{ DLsObj = func_dlsys; }
void SetDLinkAutoMachineState(int mac_state)
{ m_AutMacState = mac_state; }
int GetDLinkAutoMachineState(void)
{ return m_AutMacState; }
public:
virtual void write(CArray c_eibdata){}
};
定义eib具体的设备类以串口设备为例:
class eibRs232Device :public eibDeviceInterface
{
public:
void write(CArray c_eibdata)
{ WriteFile(c_eibdata);//标准的串口写数据函数 }
void callback read(void) //系统读串口数据回调函数。由系统发生读数据后自动调用
{ read(r_commdata); }
void callback DeviceWorkTask(void)//设备的工作任务函数,由系统内核调用管理。
{
for(;;)
{
//判断设备的工作状态,设备的系统资源是否冲突,设备的工作信息。
//通过判断以上信息,设置数据链路层自动机状态。
SetDLinkAutoMachineState(mac_state);
}//end for(;;)
}
};
eibTP1Rs232Comm模块的定义修改增强如下:
class Layer2Interface
{
protocol:
eibDeviceInterface *m_eibDeviceInstance; //增加属性
};
class RS232DLinkLayer_Sys :public Layer2Interface
{
public:
RS232DLinkLayer_Sys(eibDeviceInterface *phy_eibDevice)
{
m_eibDeviceInstance = phy_eibDevice;
//注册数据链路层实例
m_eibDeviceInstance->regDLinkLayerSysInstance(this);
}
SetDlinkLayer_Data_Req()
{
//在该方法原来的过程中添加以过程
//在执行调用设备的写数据之后增加对设备的数据连路层状态机的功能支持和判断。
int n_dautstate;
n_dautstate = m_eibDeviceInstance->GetDLinkAutoMachineState();
//进入状态机处理过程
if(n_dautstate==eibDLAutoMachineState::eibDLAutMacState_STOP)
{
//进入错误处理,通知通信系统设备停止
}
else if(n_dautstate==eibDLAutoMachineState::xxx)//传输出错,设备忙
{
//进入理该事件的动作 其中关闭设备
}
else if(n_dautstate==eibDLAutoMachineState::xxx)//空闭
{
//传输数据,并调用Con原语通知上层
m_eibDeviceInstance->Write(c_eibdata);
L_DataServer->Primitive_Con(State_OK&State_NOK);
}
else if(n_dautstate==eibDLAutoMachineState::xxx)//等等其他处理
{
//...............
}
else if(n_dautstate==eibDLAutoMachineState::xxx)//等等其他处理
{
//.........
}//end if(n_dautstate)
}
};
以上设计方案有几个好处:
其一: 使用Layer2Interface作为不同媒质的数据链路层接口使的eib这种支持多媒介的协议
的不同数据连路层开发起来更方便。更模块化一些。
其二: 使用eibDeviceInterface做硬件设备的接口使的不同煤介的设备驱动方便操作和使用。
其三: 以上设计使发开更具有高效性。和更能体现不同硬件的优势。
以上就是我想了一下的设计方案。哈哈。 写的不是很好。但是还是写了有几个小时。
楚来 2010/4/2 早上 4:29
阅读(857) | 评论(0) | 转发(0) |