微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 一种嵌入式RPC的设计与实现

一种嵌入式RPC的设计与实现

时间:06-10 来源:互联网 点击:

图4为客户端状态机。首先是打包参数,发送到服务器端,等待服务器端的回复,进入GetHeader状态。GetHeader,GetData和Get Com-plate Packet与服务器相应的状态意义相同。如果timeout则返回timeout错误。如果得到了整个packet则拆分最后返回。
DCE—RPC和ONC—RPC允许选择UDP或TCP协议。TCP协议传输控制协议,提供的是面向连接、可靠的字节流服务。UDP协议不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。基于TCP协议的可靠性,选择TCP作为通讯协议。
3 实现
3.1 数据结构
服务器和客户用共用包头信息和每个过程的参数结构。头信息定义如下。dwCallID是过程的标识号。每个过程都有一个唯一的号码。bCallType是调用的类型。dwTotalSize是整包的字节数。dwReturn是返回结果。

过程调用的类型定义如下。RPC_TYPE_SIMPLE_WRITEREAD是简单的读写,输入参数和输出参数都在头信息和过程的参数数据结构中。RPC_TYPE_READ指返回结果保存在单独的内存。RPC_TYPE_WRITE指写信息保存在单独的内存。RPC_TYPE_WRITE_READ调用是需要内存保存输入数据,返回时需要保存输出的结果。

每个过程定义自己的输入输出参数结构。例如对获取串口状态GetCommState过程,建立RPC_GETCOMMSTATE结构。

由于各个编译器对struct数据结构的成员的对齐实现不同。这样同样的struct在客户端和服务器端的大小可能不同,同样的成员在结构中的位置不同。为了确保客户端和服务器端有相同的对齐,我们采用字节对齐用#pragma pack(1)。
3.2 Packet内存布局
开始依次是头信息和参数,其余部分根据特定的过程而不同。以RPC_TYPE_WRITE_READ类型的布局为例:头信息,参数,输入内存块[1…N],输出内存块[1…N]。其他的过程类型布局类似。
3.3 服务器端实现
3.3.1 网络模块实现
RPC在单独的任务中执行。图5为RPC任务流程图。调用VxWorks的系统函数taskSpawn建立RPC任务。调用socket( )建立面向连接的SOCK_ STREAM套接字,bind将套接字与本地网络地址和端口号捆绑,listen申明要在该端口侦听客户连接请求,accept阻塞等待请求的到来。

3.3.2 状态机实现
当accept后,进入服务器端状态机。设置accept返回的socket为非阻塞状态。在阻塞的socket上调用send时,如果没有足够的输出缓冲区,该调用将被阻塞。Recv也是一样,要读的数据没有就绪时,调用者阻塞。服务器不知道每次要读取的字节数,所以阻塞的socket无法工作。
分配2块内存:A和B。内存A用来保存recv的内容,内存B用来保存客户端发送的Packet内容。因为服务器不知道客户会发送多大的内容过来,每次从内存A拷贝到内存B之前检查内存B的大小,如果内存B剩余大小不够则重新分配。
在得到了整个Packet后,即GetComplatePacket后,根据dwCallID调用服务器的本地过程,待返回后将返回值和内存打包发送给客户端。
3.4 客户端实现
客户端的流程如图6所示。在Windows下运行,首先调用WSAStartup,Windows根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。然后初始化socket,连接到服务器,接着过程调用。比如过程调用1会进入图4状态机。状态机和服务器端类似,只是首先参数打包,发送给服务器,返回后拆包并拷贝返回信息到内存中。

4 结束语
本文设计和实现的RPC可应用于白盒测试、跨平台开发环境和开发客户端软件等。商用的嵌入式IDE软件都很昂贵,通过本RPC,测试人员就可用开源的环境如cygwin等开发白盒测试代码。另外对于有大量操作界面的嵌入式开发,需要频繁下载到开发板上验证,本文RPC可应用于构建跨平台的开发环境,直接在Windows上开发界面部分,最后下载到开发板上,从而大大提高开发效率。大多数的嵌入式软件都有相应的PC客户端软件,本文的实现也适用于开发PC客户端软件。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top