嵌入式系统通讯协议设计与应用
1.概述
本通讯协议主要参考TCP/IP协议的分层结构进行建模,主要为了解决嵌入式系统中通讯设备种类较多,网络结构多变使上层应用程序设计与硬件相关,没有统一的编程接口,不便于调试,不便于模块化的问题。
2.协议模型
本通讯协议被分为如图1-1所示的五层。各层的定义见表1-1
图1-1
层次名称 层次作用 对应类(基类) 物理层 提供物理层次的器件连接 无
数据链路层 通过对物理层寄存器的操作,按照传输
要求对数据进行编码解码,实现点对点
的数据流的传输及流量控制。
CDLL_BASE
网络层 通过统一接口访问“数据链路层”的数
据缓冲,将含有网络层协议头的网络层
包装入或取出数据缓冲,进行路由分析,
最后转发或向上一层传输。
CNWK
CNWK_MASTER (主板或单机使用)CNWK_SLAVE
(子板使用)
传输层 对数据进行分包处理,将数据切割成较
小的数据包,按照次序发送,对接收的
数据包按照包头的信息重组数据包。并
且提供发送数据的校验及重发超时任
务。
CTPL_TASK
路由管理协议层 针对不同的应用配置管理设备的网络结
构,映射硬件物理结构并查询、存储路
由信息的服务。
CLINK
应用程序层 应用程序使用固定接口向“传输层”提
交发送任务,并在数据到达以后进行处
理及响应。
CAPP_BASE
表1-1
3.通讯程序的应用
3.1通过CLINK类的使用及配置协议
除了以上提到的五层网络模型以外,为了程序设计者能够方便的使用配置程序在协议开发包中还包含一个CLINK类,它继承于CTPL_TASK类(类图见注),通过继承这个类,调用它的接口开发者能够将程序员自己编写的“数据链路层“,和“应用程序层”动态配置到网络中,产生编程者所需要的网络配置。
本协议使用“网络层协议”,“传输层协议”作为实现网络功能的下层协议。在使用中应按照以下的步骤配置协议。
① 新建一个类继承类CLINK。
② 实例化数据链路层协议。(需自CDLL_BASE中派生)
③ 实例化应用程序层程序。(需自CAPP_BASE中派生)
④ 重载以下四个函数。
virtual
BOOL OnAddDll();在此函数中使用
BOOL AddDll(CDLL_BASE *pcDllUnit, BYTE
&uDllIndex);
函数添加用户编写的“数据链路层”协议
virtual
BOOL OnMapUnit();在此函数中使用
BOOL MapModule(const
BYTE uModule, const
DLL_STRU sDllStru);
适用于主板或单机
BOOL MapPort(const
BYTE uModule, const
DLL_STRU sDllStru);
BOOL
SetDefaultPort(const
BYTE uDefaultPort);
BOOL
SetMasterPort(const
BYTE uMasterPort,
BOOL bMaster);
适用于子板
virtual
BOOL OnAddApp(); 在此中加入应用层程序
BOOL AddNetApp(CAPP_BASE *pcNetApp);
virtual
BOOL OnInitFinish()
通讯协议初始化完毕。
⑤ 在程序运行时可以使用如下接口改变路由及配置。
路由信息类:
函数体 函数定义 DWORD GetMyId();获得设备地址
void SetMyId(DWORD dwMyId);设置设备地址 BOOL AddGroupRoute(const BYTE
uGroup, const BYTE uModule, const
BYTE uPort);
增加组路由(暂不支持)
BOOL DelGroupRoute(const BYTE
uGroup);
删除组路由(暂不支持)
BOOL AddRoute(const DWORD
dwNodeId, const BYTE uModule,
const BYTE uPort = 0);
增加路由
BOOL DelRoute(const DWORD
dwNodeId);
删除路由
void ClsRoute(); 删除所有路由 BOOL SaveRoute();存储路由
BOOL
GetRouteInf(DWORD dwNodeId,
BYTE &uModule, BYTE &uPort);
查询路由
DWORD GetRouteCount();获取路由数 DWORD GetRouteList(sNodeStru
*psNodeStru);
获取整个路由表
3.2通讯程序的扩展编程
本通讯协议可以在任何层次上使用,以便各层的调试,及以后通讯设计的复用,以下将介绍使用的方法和一些接口。
3.2.1数据链路层
对发送缓冲
WORD Dll_GetOutputCount(const BYTE
uBuffUnit);
发送缓冲中数据数
BOOL Dll_GetChar(const BYTE uBuffUnit,
BYTE &uChar);
从发送缓冲中读出一个数据
BOOL Dll_GetChar(const BYTE uBuffUnitm,
BYTE *puChar, WORD wCount);
从发送缓冲中读出多个数据
BOOL Dll_DelChar(const BYTE uBuffUnit,
const WORD wCount = 1);
从发送缓冲删除数据
对接收缓冲
virtual void Dll_InputUpdate(const BYTE
uBuffUnit) = 0;
WORD Dll_GetInputRemainBuffCount(const
BYTE uBuffUnit);
获得剩余的输入缓冲空间数
BOOL Dll_PutChar(const BYTE
uBuffUnit ,const BYTE uChar);
送入一个字节
BOOL Dll_PutChar(const BYTE
uBuffUnit ,BYTE *puChar, const WORD
wCount = 1);
送入多个字节
void Dll_ValidInput(const BYTE uBuffUnit); 输入允许
与系统的接口
BOOL GetEnable
(const BYTE uUnitCount);
获得端口是否被系统禁止
void SetEnable
(const BYTE uUnitCount, const BOOL
bEnable);
系统设置端口状态
BOOL GetActive
(const BYTE uUnitCount);
获得端口是否可用
BYTE GetUnitCount();获得协议所分配的端口数
BOOL Init();手动初始化协议
3.2. 2网络层
结构体定义
typedef struct
{
BYTE uDllIndex; uDllIndex;
“数据链路层”索引 uDllUnit;