因为工作的关系,有幸接触到一种不那么复杂的2G通信技术的协议栈(终端)和基带两方面的内容,经过一段较长时间的摸索和思考,再加上和终端厂商一线开发人员的的讨论深化,到现在总算对协议栈设计和架构方面有了一些比较粗浅的想法。
因为我的工作内容重点在于基带硬件(也涉及RF模块)和协议栈的(物理层+链路层,对于网络层的协议细节则不太熟悉),所以我这不多的想法也是集中在我所从事过的这些方面。
接下去的详细论述是从协议栈设计和架构方面去着眼的,从软件工程的角度来说顶多进行到概要设计那个阶段:-)
1,从协议规范的学习理解到协议栈的设计架构。
1.1 对于移动通信终端协议,首先去了解并理解协议规范的具体内容是最最基本的,这是个know what的过程,如果不做协议栈设计和实现的话,一般到这个程度也就差不多了;
1.2 知道并熟悉了协议规范的描述后,接下来就可以去考虑如何设计协议栈框架了,这是个know how的过程。
协议规范一般会以自然语言和形式化语言两种方式去描述定义:自然语言有利于理解,但是定义不严格,理解起来有时会导致歧义性,于是各种形式化语言就作为必要的成分参与其中了。从协议的整体来看,我觉得“状态机”是个非常重要的概念和思想,虽然它离实际的协议栈实现还有一点点距离。从状态机可以衍生出SDL图和MSC图等等较严格规范化的形式化定义:
〉〉SDL侧重于从系统状态的变化角度去描述和定义单个系统的行为,这里“系统”的概念比较灵活,一个协议层可视为一个系统,多个系统的集合也可视为一个更大的系统,划分和界定系统主要是为了将概念域的“系统”映射到设计域的“状态机”(设计域的“状态机”接下来将被映射到实现域的“状态机实现”,具体的实现方式有“状态—事件表”法、“Switch-Case”法等);
〉〉MSC图侧重于从多个系统间消息交互(包含消息内容和特定消息的传递顺序两方面的内容)的角度去描述和定义系统间的行为,这里的系统可能是一个物理通信实体(如终端或基站)内部的某个协议逻辑层系统,也可能是整个物理通信实体本身,当然准确地说在通信协议栈的规范和实现中,物理通信实体一般都会被划分为多个逻辑通信实体去分别对待的,而不会像在通常口头所说的终端和基站通信这么简单、笼统。
关于“状态机”概念,稍微深入下去讨论的话,我个人的理解是:状态机是状态和事件以及事件对状态的驱动规则的集合,前两个元素基本上可看作是静态的,而事件对状态的驱动规则可看作是动态的,这样的话“状态机”就可以理解为静、动结合的一个逻辑实体,当然用面向对象的思想去看待“状态机”这样一个逻辑实体的话,很容易地就会把它理解成一个对象,——在协议栈设计和实现的过程中,确实可以借用面向对象的方法(思想层面上)或手段(实现层面上),这样的话协议栈的结构和逻辑会更清晰。
通常我们所讨论和理解的“状态机”多是单层、扁平的状态机模型,此外对状态机概念的一个发展是“层次状态机”的概念:单层状态机概念是在将系统划分为一个个相对孤立的系统的前提下、将系统从概念域映射到设计域后得到的,而客观上,各个系统间并非都是完全孤立的,有的系统间存在逻辑上的包含与被包含关系,因而考虑到概念域的这种联系,在设计域也有必要将状态机在逻辑上进行层次划分,这种想法和面向对象思想中的继承是非常相像的,甚至多态的概念也可以加入到此中来。关于层次状态机的详细论述,可参考《嵌入式系统的微模块化程序设计——实用状态图C/C++实现》一书,作者是美国的一个资深工程师,书里面的内容我个人理解应该是经验之谈,不过我只吸收了其中的“层次状态机”这个核心思想,至于具体的代码实现细节,我没仔细去看了^&^。
在对协议栈的设计和架构有了总体的认识后,尝试着慢慢去把这些认识具体化就是件水到渠成的事情了。就个人体验而言,Visio用在这方面真是很不错,我尝试过用WORD画状态机图和SDL图、用Excel画MSC图,但是因为数据格式不统一而导致的内容分散,所以很难把自己的理解和想法在一种单一类型的文档中集中体现出来,而Visio的多页编辑功能和丰富灵活的编辑方式恰好满足了我的这种需求(Tips:平时有什么想法的话也可以在Visio里涂涂画画,想法变了可以再改,Visio给你提供足够的自由度:-)。
1.3 经过上面的两步工作,一个基本的协议栈架构和模型差不多就能出来了,不过在具体实现前,为了尽可能的避免一些理解的偏差或提高系统设计的质量,花些心思去理解或猜测协议规范为什么设计成现在的这个样子是很有意义的,这是个know why的过程,虽然都是去了解和理解协议,但是能达到know why的高度则非常厉害了,不过这个过程是个周而复始、循环上升的过程,需要长期不断地积累:在具体实现和运行之前,可以依托广泛的知识背景和高超的个人理解力去理解或猜测协议设计背后的思想或考虑,但是很多这方面的知识和经验是要等到协议真正实现运行了后,在调试和实测中发现问题、总结经验后才能逐步深化的,这些深化了的理解反过来可以指导前期的设计以提高系统设计的质量。所以要自行开发协议栈的话,我觉得在设计—〉实现这条路上不宜坚持一步走到底的“美好”想法,反过来若是以原型化的方法先开发一个简易的Demo,然后通过调试和测试不断地去细化和完善,这样协议栈开发成功的可能性会增大、总的开发周期也有可能会缩短。形象地说,是先搭骨架,再添器官,最后加肌肉和血管,这样一个有血有肉、鲜活的生命体就诞生了:-)
2,从协议栈的设计架构到协议栈的实现调试
这里的“实现”是指在软件级的实现,包括RTOS的选择、系统任务的划分和通讯机制的选择安排、以及最后的编码调试。
如前所述,一个完整的通信过程中会牵涉到不同逻辑通信实体间的信息交互(从终端用户的角度看,看到的是不同物理通信实体间的信息交互),各个不同的逻辑通信实体在整个的通信系统中既保持一定的独立性(这是状态机赖以存在的基石),又和其他逻辑通信实体存在一定的联系(这是整个系统得以实现通信功能的所在),因而在实际实现和运行中需要考虑怎样去协调这些逻辑通信实体间的行为(广义地说,逻辑通信实体间的通信也是为了协调逻辑通信实体间的执行顺序,如:物理层给链路层发送1个slot的接收数据,链路层收到此数据后触发其下一步的动作,否则链路层在接收数据方面的操作会被挂起暂停,因而可以理解功能上的消息通信实则影响了时间上的执行状态)。从逻辑设计到实际实现的过程中,每个逻辑通信实体所对应的状态机很自然地会被考虑映射到RTOS的任务上去,这中间不一定是一对一的关系,某些情况下,出于任务粒度划分的考虑,有可能是一对多的。
由于每个RTOS提供的任务同步和任务间通讯方式差异较大,所以在这里讨论以何种具体的任务同步和任务间通讯方式去实现两个特定逻辑通信实体间的同步和通信意义不大,据我所知道的日本比较流行的iTRON规范中,常见的有信号量(Mutex、Semphore)、事件标志、邮箱(适合大信息量的任务间通讯)、消息缓冲(适合中、小信息量的任务间通讯)这几种,至于会合,有些符合iTRON规范的RTOS中并未实现。
协议栈的调试是件烦人的事情,有时会因为一个小小的错误折腾很多天而不得其解,有时甚至会被逼得考虑重新设计状态机,这个过程很折磨人,也很锻炼人,协议栈实现能力和调试水平的提高,在这个过程中可以得到深化和升华,这可能也是TTPCOM这样的专业协议栈软件公司的经验和长处所在了:-)
后记:
写了这么多,虽然文字量不太大,但是涉及的内容面挺广,因而写完后还是感觉有点累!
我这人比较懒,有想法一般都在脑子里打转或在嘴上和人家说,不太习惯用文字的形式把它固化下来(敲字太累!图表倒是经常用,因为我把那个看作是思维的延伸:-)
因为我也是第一次接触无线通信终端协议栈和基带方面的内容,所以在无线通信协议上的经验和理解有限,2G里面我只碰过这个,不知道将来在3G领域有没有机会再碰碰。
协议栈的设计和实现与一般的软件系统开发不太一样,不过它有一套自身特有的模式,一旦接触过并掌握了这个模式后,以后再开发其他无线通信协议栈的话,难度应该会降低很多。而且协议栈开发中某些过程确实是可以模式化且能以CAD的形式实现出来的,如Telelogic的Tao据说就能根据SDL图自动生成C代码,其实这种转化并不难。
谈到CAD这块,有必要提提ITU在通信协议规范方面所做的形式化语言定义工作:从ASN.1对PDU(Protocol Data Unit)的定义,到SDL对状态机的定义,再到MSC对消息交互流程的定义,直到TTCN等对协议测试的定义等等。对这些形式化语言,我只是很粗略地看了看,有兴趣学习研究的朋友可以去ITU的网站上下载。
“话不说不明,理不辩不清”,欢迎其他对协议栈感兴趣的朋友积极讨论,以加深或纠正各自对这方面的理解。以后如有时间的话,可以再开个话题讨论协议栈开发和应用过程中的Troubleshooting,这个不属于纯技术的范畴了,可能很多人对此也没多大兴趣了^&^。
---------------------
Cache, 2006-11-23
<P align=right><FONT color=red>+9 RD币</FONT></P>
[此贴子已经被作者于2006-11-23 18:37:40编辑过]
[br]<p align=right><font color=red>+1 RD币</font></p> |