诊断之美-平台和构架

       平台

  之前曾经提到过,诊断的平台有两种,一种类似boot loader,一种基于高级操作系统。这两种的优缺点也都已经分析。   
  这里,我各举一个例子来详细说明。
  首先拿boot loader的代表,u-boot来举例。u-boot的特点是对于arm系列的支持很好,包括了很多arm的开发板及其设备的驱动支持。 在进行适当的交叉编译后,我们可以得到一个文件。这个文件可以烧录在系统上电代码所存在的只读存储器上。当u-boot运行后,我们可以看到一个命令行界面,甚至可以运行自己预先添加的命令。还有,u-boot自带了开机自检代码,可以进行最简单的诊断。利用这个框架,我们可以在他的基础上定制自己的诊断系统。在这种情况下,我们的诊断系统就成了boot loader的一部分,没有自己的进程空间和可执行文件。当然,这个缺点在很多情况下可以忽视,只要诊断代码稳定运行就行。此外,u-boot集成了C语言标准函数库,为我们的开发提供极大便利。
  
  另一个选择就是现成的linux等多线程操作系统。单进程的操作系统当然也可以,比如dos。但是这样一来可利用的系统调用还是太少,还不如在boot loader基础上开发。我们可以选择的有linux,windows,vxworks,qnx等。前两个的通用版本可能太大,我们需要使用其精简的版本,比如real time linux和wince。当然,如果硬件系统足够强大,那么直接运行通用版本也可以。vxworks和qnx需要花钱买,优点就是可以编译出很小的核心模块,把不必要的模块,比如文件系统省略掉。我所知道的qnx精简后只有几百K。
  
  使用现成的操作系统还有一个好处,就是可以利用程序除错工具。在linux下,我们有GDB和KGDB。


       构架
  无论诊断系统基于boot loader 还是操作系统,他的结构都是通用的。应该包含以下几个部分:
  
  1.测试管理模块
  一个测试可以分为六个函数,初始化,正体,迭代,状态,错误处理,清理。有时还可以饱含中断处理函数。迭代函数可以看作一个状态机,控制正体函数的运行次数。
  为了维护一个测试列表,我们可以引入设备的概念。设备可以指一个芯片,也可以是一个总线,更可以是一个主板,一个系统。每个设备包含了若干测试。一个测试又可以包含几个参数。此外测试的六个函数可以通过函数指针矩阵连接到单个测试的数据结构中。对于那些跨芯片的测试,我们可以定义一个虚拟的设备,然后把该测试挂到上面。至于对于虚拟设备的访问方式,我们可以使用现存的设备驱动,也可以写一个虚拟的驱动。举个例子,对于数据通路测试,可能需要涉及到5个芯片,那我们可以建立一个包含5个设备的虚拟设备,然后把数据通路测试挂在下面。这个测试的读写总是针对某个芯片的,我们可以调用那个芯片的驱动来访问。此外,单个测试还可以包含一个属性,叫做默认测试。如果为真,那么在运行测试列表时可以运行它,否则跳过。还有,运行结果也可以记录在设备的数据结构中。
  此外,在编写测试函数的时候,我们应该尽量做到平台无关。比如访问一个相同的芯片,这个芯片在不同的系统中使用不同的驱动方式访问,那么我们可以编一个相同的访问函数接口,在函数里分类处理。那么,顶层的测试函数就可以使用统一代码了,这样便于代码复用。
  
  2.命令处理模块
  命令处理模块是人机交互的通道。通常所需的命令有,列出全部或者隶属于某一设备的测试,选择当前测试或者设备的子测试,运行默认测试列表或者单个测试,强制关闭测试,设定或者取消默认测试列表,设置输出打印级别等。他应该是一个无限循环,不断读取用户输入。
  
  3.测试结果统计模块
  测试结果统计模块应当把前几次的运行结果和详细信息储存在一个表中,以备查询。
  
  4.测试执行模块
  测试执行模块分两种情况,一种是运行当前的单个测试,一个是运行默认测试列表。运行多个测试列表时不应该多线程并行执行,因为这样会破坏测试结果,会难以定位错误到底是软件还是硬件问题。单个测试里可以允许并行运行,但是这取决于测试开发者本身,而不是诊断系统。此外,测试列表的顺序应该是与测试无关的,也就是顺序不影响测试结果。如果影响,那应该在被影响的测试初始化函数里初始化到一个统一状态。还有,测试结束时要记录运行结果,以供统计模块使用。此外,还可以指定是否单个测试发生错误继续执行别的测试,以及最大错误数量。
  
  5.子系统通讯模块
  子系统之间有时候需要通讯。比如我们连接到一个有串行接口的母系统,想访问子诊断系统的话,就需要通过网卡驱动和上层OSI协议,自己定义一些命令,发送过去。接收端解析命令以后,返回字符串到母系统,再由母系统显示。对于那些需要几个子系统协同的测试,也需要调用相应的命令,解析后再调用,最后返回结果。
  
  6.标准测试算法模块
  标准测试算法模块包含了寄存器,内存等标准算法,要做到和硬件无关。算法只接受标准的输入参数,比如,地址,长度,读写函数指针等。
  
  7.设备驱动模块
  设备驱动模块可以是操作系统的标准驱动模型,也可以是直接访问硬件。基于操作系统的,最好能处理多个线程并发访问同一硬件的情况。
  
  8.除错和打印信息模块
  我们的打印信息应该仿照linux中的printk一样分级别,这样就可以在运行时不同的时刻打开不同的级别,看到期望的信息,不会被别的信息所干扰。
  
  9.装载模块
  有时候母系统和子系统的映像编译在一起,当装载的时候,母系统会和子系统上的启动代码通讯(可以基于TFTP),然后把子系统所需的映像传送过去。这就需要额外的代码来决定如何传送。这部分我需要做进一步研究。
  
  10.硬件初始化模块。
  这包含了系统初始化,板卡初始化,芯片初始化,测试初始化等。我们可以使用函数指针,在初始化的时候指定好。还可以在这个模块内做一些针对某个设备的特殊处理。
  
  定好了代码模块,我们还需要规定代码存放的目录结构。一般是诊断系统的平台无关代码放一个地方,平台相关代码独立存放。当然,定义更细致的子目录也是合理的。平台相关部分包括了芯片,板卡,系统等。我们可以把这三个层次的硬件都看作是设备,设备包含驱动与测试两个部分。每个设备针对不同硬件系统包含不同的驱动,但是对外统一函数接口。高层次的设备可以使用低层次设备的驱动接口,形成高层次的测试。

 

  集成开发环境


  我一直在想,诊断开发到底需不需要一个集成环境?做到怎么样的程度才有商业价值呢?
  
  最理想的情况,就是自动分析硬件布线图和硬件功能文档,把所有基本的测试全都自动生成。不过这样需要特殊格式的文档,不太现实。
  
  次理想的情况,利用集成环境的工具画出硬件系统的结构框图。对于框图内每一个设备,手工定义需要测试的寄存器列表,定义每一个内部模块的类型,比如内存等。然后给出访问所需的驱动,如果是标准访问方式则给出类型,比如I2C协议。最好每一个设备的定义都能够被共享,做类似开源的项目。这样就可以大大节约开发时间。不过开源的东西谁有精力去维护呢?或者说怎么盈利呢?要做到微软那样厂商自己写驱动然后出钱注册那也不太现实。
  
  再次的情况,只给出最基本的一些总线,接口和算法,但是做到和Visual C++那样的标准封装,用户需要自定义新的设备诊断程序。这个似乎可行,甚至可以利用elipse的平台,用插件的形式实现诊断集成环境,可以省事很多。这似乎是最可行的方法了。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值