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

2011-08-09 14:56:21来源: 互联网

摘要:在研究远程过程调用的原理和嵌入式系统特点的基础上,提出一种远程过程调用的设计以及在VxWorks操作系统上服务器端和在Win-dows探作系统上客户端的实现。经在项目中的应用,本设计与实现体现了良好的实用性、移植性和扩展性。
关键词:远程过程调用;嵌入式系统;网络;状态机

    远程过程调用(Renmte Procedure call,RPC)最早是在B.J.Nelson的博士论文中论述的。这里的过程等价于例程,函数的意思。RPC的思想源于大多数的程序都以过程作为最小设计单位。RPC扩展了过程调用机制,允许客户端的过程通过网络调用服务器端的过程。
    从RPC的思想出发,不同的组织和公司开发了不同的RPC协议。有SUN公司的ONC RPC,开放软件基金会的DCE RPC,微软公司的MSRPC等。这些RPC都依赖与特定操作系统,并且定义了自己的接口描述语言(IDL),对于嵌入式开发过于复杂。

1 RPC的机制
1.1 过程调用
    典型的过程调用就是过程A将参数和控制权交给过程B,过程B经过一系列运算或者下一级过程,最后把结果和控制权返回给过程A。
1.2 RPC流程
    RPC分为同步RPC和异步RPC。在同步RPC中客户端发出RPC调用的线程将被阻塞,直到从服务器端完成。异步RPC中客户端发出调用的线程不会被阻塞而是继续执行。本文以同步RPC为研究对象。
    RPC的思想就是使远程过程调用看上去就像在本地的过程调用一样。从程序运行角度来看,其流程如图1所示。客户端(MACHINE A)的进程通过网络发送远程过程调用请求给服务器(MACHINE B)。服务器收到请求后处理,调用相应的过程执行,执行完毕后服务器返回结果给客户进程。客户进程在发出远程过程调用后被阻塞,直到服务器返回结果给客户进程。

a.JPG


1.3 RPC的结构模型
    从描述的角度出发,产生不同的RPC模型如Andrew S.Tanenhum在其著作分布式操作系统中论述的模型以及B.J.Nelson论文中的RPC模型等。但这些模型的主要组件都是相同的。图2是B.J.Nelson博士的RPC结构模型。客户进程、客户存根和RPC运行库实例在客户端执行。服务进程、服务器存根和RPC运行库实例在服务器端执行。客户过程调用相应的客户存根。客户存根打包参数。客户端的RPC运行库将打包好的参数通过网络发送给服务器RPC运行库。服务器存根拆包参数,然后调用服务器过程。完成后返回结果给服务器存根。服务器存根打包结果给服务器RPC运行库。服务器RPC运行库发送打包好的参数给客户RPC运行库。客户存根拆包并将结果取出返回给客户。

b.JPG


    尽管RPC的思想比较简单,但有很多问题需要考虑。由于有很多不同的CPU,如X86、ARM、SPARC等以及各种DSP单片机,产生了参数传递问题。如X86采用最低有效字节优先,而SPARC是最高字节优先。有些大型机采用EBCDIC码,而其他处理器采用ASCII码。存根就是用来解决这些问题。还有指针问题,涉及物理地址、虚拟地址、地址空间等很多考虑。我们知道不同计算机之间无法直接访问彼此的地址。还有过程的参数如果为数据结构,这就引出数据对齐的问题。由此可以推断所有的RPC实现都在一定的范围适用。本文的RPC设计假定客户端和服务器端有相同的大小端和并且都是32位处理器。

1.4 SunRPC
    Sun RPC有时也称为ONC(Open Network Computing)RPC。Sun RPC提供了一个接口语言IDL和rpcgen用于C语言支持。这门语言可以定义constants,typedef,structure,union。rpcgen可以产生server code,client stub和头文件。server code主要是建立socket,注册端口和监听,接受连接,拆参数,调用实际的过程,打包返回值。client stub则是打包参数,发送给server,将返回值解包。Sun RPC缺点就是对Windows没有很好的支持。

2 设计
    本设计与传统的模型不同,服务器端分为:网络通讯,接收状态机和过程处理。客户端分为网络通讯,发送状态机和过程调用。
    图3是服务器端的状态机。服务器进程从初始状态进入GetHeader状态。GetHeader是读取远程过程调用的头信息。如果一次得到了所有数据,也就是nCurLen>=dwTotalSize,则进入GetComplatePacket状态,反之进入GetData状态。GetData是读取参数数据,读取数据直到得到所有的数据进入GetComplatePacket状态。期间如果超时,则回到GetHeader状态。超时的起始时间从GetHeader韵第一个字节算起,如果在定义的时间无法读取dwTotalSize个字节,则Timeout从而回到GetHeader状态。在GetHeader和GetData时,如果读取数据有错误(如客户端断开连接,recv函数返回错误)则状态机退出。GetComplatePacket是得到了完整的包。CheckCall判断当前的调用是否是有效的过程调用。如果无效则进入状态,并回复无效命令给客户端,最后进入GetHeader状态。如果有效,则处理此调用,最后发送结果给客户端。

c.JPG          d.JPG


    图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是返回结果。
    e.JPG

过程调用的类型定义如下。RPC_TYPE_SIMPLE_WRITEREAD是简单的读写,输入参数和输出参数都在头信息和过程的参数数据结构中。RPC_TYPE_READ指返回结果保存在单独的内存。RPC_TYPE_WRITE指写信息保存在单独的内存。RPC_TYPE_WRITE_READ调用是需要内存保存输入数据,返回时需要保存输出的结果。
  f.JPG
    每个过程定义自己的输入输出参数结构。例如对获取串口状态GetCommState过程,建立RPC_GETCOMMSTATE结构。
    h.JPG
    由于各个编译器对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阻塞等待请求的到来。

h.JPG


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状态机。状态机和服务器端类似,只是首先参数打包,发送给服务器,返回后拆包并拷贝返回信息到内存中。

i.JPG



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

关键字:嵌入式  设计  实现

编辑:eeleader 引用地址:http://www.eeworld.com.cn/gykz/2011/0809/article_7954.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
论坛活动 E手掌握
微信扫一扫加关注
论坛活动 E手掌握
芯片资讯 锐利解读
微信扫一扫加关注
芯片资讯 锐利解读
推荐阅读
全部
嵌入式
设计
实现

小广播

独家专题更多

富士通铁电随机存储器FRAM主题展馆
富士通铁电随机存储器FRAM主题展馆
馆内包含了 纵览FRAM、独立FRAM存储器专区、FRAM内置LSI专区三大部分内容。 
走,跟Molex一起去看《中国电子消费品趋势》!
走,跟Molex一起去看《中国电子消费品趋势》!
 
带你走进LED王国——Microchip LED应用专题
带你走进LED王国——Microchip LED应用专题
 
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2016 EEWORLD.com.cn, Inc. All rights reserved