引言

在VxWorks下,使用系统本身提供的接口函数ExcConnect()来进行异常处理只对PowerPC系列处理器有效,对目前使用同样广泛的Intel 80x86系列处理器和ARM系列处理器无法提供有效支持。本文主要针对目前VxWorks异常机制可移植性差的问题,提出一种及时准确并且与具体处理器类型无关的捕捉异常的方法。

1 VxWorks 下异常分析与处理

在VxWorks下如果使用默认的异常处理机制,处理结束后:产生异常的任务将被悬挂,且该消息将被传送到控制台。可以看出,如果不对异常进行处理,使用默认的异常处理方法,对于一个系统来说往往是致命的。所以我们必须对系统默认的异常处理方法进行修改和完善。

可以将异常处理流程分为以下5个阶段:

  1. 一个软件错误发生
  2. 错误的原因和性质被一个异常对象携带
  3. 程序检测这个异常对象,或者允许它的存在,或者由其主动上报
  4. 检测代码决定如何处理异常
  5. 异常处理完毕,恢复程序并继续执行

2 跨平台异常处理模块的实现

2.1 整体实现方案

本文设计的异常处理模块采用钩子函数的方式接收操作系统传入的异常现场;在内存的保留区保存传入参数,并释放信号量以激活守护任务;守护任务保存未解析的现场信息;采用堆栈回溯和匹配函数序言的方式进行函数调用链分析,将结果保存到内存保留区;若存在外部存储介质,则将解析后的现场和函数调用链分析结果写入文件;对应用层提供钩子函数以实现恢复策略支持。

异常处理模块的整个流程主要由两部分组成:异常处理初始化流程和异常钩子函数流程。初始化流程主要包括初始化全局变量和挂接异常处理钩子函数。异常处理的处理过程设计如图所示:

VxWorks Exception Process

2.2 “堆栈分析”

异常处理过程中的关键是“堆栈分析”,即使用堆栈回溯的方法实现现场分析,该功能的实现也是异常处理的难点。现场分析与处理器类型密切相关,需针对不同系列处理器分别分析异常类型、现场信息、运行栈结构、函数的序言和尾声等内容。下面以x86 处理器为例进行说明。

2.2.1 运行时堆栈结构

在VxWorks Image的编译工程的Kernel Configuration中添加下列组件,如图所示

VxWorks Telnet Server

(注:上述的LOGIN_PASSWORD的内容为"RQcRcRSS9e",输入时需要带上双引号,一个符号都不要错,它对应的明码是"123456789")

然后,重新编译生成VxWorks镜像工程文件,引导启动;

在Windows端使用PieTTY或者Putty等telnet客户端登陆,用户名:target;密码:123456789。且Port为23,是Telnet(BBS),不是SSH类型:

Pie TTY

上述的“RQcRcRSS9e”计算过程:可使用工具:WindRiver3.8\vxworks-6.8\host\x86-win32\bin>vxencrypt.exe 123456789 后得到。

Synopsis

This article will discuss the key points of the UDP communication between vxworks 6.8 and windows.

Code description

On Windows, we run a UDP Server whose name is win_udpServer.exe, which is designed by www.vxbus.com.

On VxWorks6.8, we designed a UDP Client procedure whose name is mkvxUdpClient.c

Please check out the attached file for the source code of them.

Steps to Test

On windows

Open a command terminal console, and then change into the directory where win_udpServer.exe resides, type the name of the application win_udpServer.exe, see picture below:

windows udp server

It will show you how to launch the application correctly, here we can type win_udpServer.exe 5002, see picture above.

After launching the application, we can see the picture below:

VxWorks系统提供灵活多样的定时器机制,有多种接口可以方便地实现延时,文章列举几种常用的延时方法,并对这几种延时方式的适用条件和注意事项作了说明。

嵌入式系统中,一个任务往往需要在特定的延时之后去执行一个指定的动作,比如等待外设以确保数据可靠,控制扬声器发声时间,串口通信超时重发等等。这就需要利用定时器机制来计量特定长度的时间段。VxWorks作为实时嵌入式系统,提供多样的定时接口函数。以下列举一些常用的定时方式及其注意事项。

taskDelay

taskDelay(n) 使调用该函数的任务延时n个tick(内核时钟周期),该任务在指定的时间内主动放弃CPU,除了taskDelay(0) 专用于任务调度(将CPU交给同一优先级的其他任务)外,任务延时经常也用于等待某一外部事件,作为一种定时/延时机制。在没有中断触发的时候,taskDelay能很方便实现又不影响系统整体性能。比如需要写数据至EEPROM,EEPROM需要一个内部擦除时间(最大擦除时间为10ms)。以下文章所提及的一个tick都假设为16.67ms(1/60s),我们可以简单地调用taskDelay(2)以保证数据擦写完成,按理说taskDelay(1)就足以保证,为什么需要taskDelay(2)呢?

VxWorks Timer taskDelay

这也是taskDelay使用的一个缺陷,使用时需要注意。taskDelay(n)表示任务延时至第n个系统时钟到来的时刻,如图1所示:如果在A时刻调用taskDelay(1)仅仅延时5ms,而在B时刻taskDelay(1)就是刚好一个tick周期。可见要10ms的延时就必须taskDelay(2)才能保证。taskDelay有接近-1个tick的误差存在,taskDelay(n)实际上是延时(n-1)tick ~ n tick 之间的时间。延时精度为1/n,延时1s就是taskDelay(60)的误差极限为1.6%,而taskDelay(1)的误差极限将是100%。

使用taskDelay需注意的另外一点是:即使经过n个tick,调用延时的任务也不保证返回执行状态,可能有更高或相同优先级的任务占用了CPU。

watchDog

VxWorks提供了一个通用的看门狗定时器机制,利用提供的函数,任何任务都可以创建一个看门狗定时器,经过指定的延时后,实现在系统时钟ISR的上下文中运行指定的程序。需要注意的是,看门狗定时触发的程序是在中断级别上执行,而不是在任务的上下文。因此,看门狗定时挂接的程序编写有一定的限制,这个限制条件与中断服务程序的约束是一样的。比如,不能使用获取信号量的语句,不能使用像printf()这样的I/O 系统函数。

一、前言

ICE1.3.0中间件当前版本并没有直接支持VxWorks,我们可能在百度搜索上也找不到相关移植资料。在Windows,unix,linux等相关操作系统下,也许你可以轻松地搞定。或许估计你曾经尝试把它移植到VxWorks实时操作系统,其过程估计没有想象那么容易,只有身临其中才能有所体验了。

在Ice移植VxWorks过程中,我们需要定义宏“VXWORKS”开关。VxWorks底层网络遵循POSIX标准,但不同的操作系统中POSIX还是有一点差异,代码修改过程中使用VXWORKS标志区别出来。

本文基于VxWorks本身的仿真器实现,完成ice的动态库创建,并使用最简单的例子“Hello World!”实现客服与服务器之间的通信。

二、了解POISX标准

POSIX具有多重含义,通常指POSIX标准,该标准是一个可移植操作系统接口(Portable OperatingSystem Interface),由IEEE提出,ANSI和ISO将其标准化。POSIX的目的是使应用程序源代码可以在兼容POSIX的操作系统上移植。理想的目标是应用程序移植到另一个操作系统只需要重新编译就可以运行。POSIX最后一个字母“X”表达了这种超乎操作系统差异的理想。目前并没有实现这种理想:从操作系统看,由于目标、要求、理念、条件的差异,并不是所有的操作系统都实现100%POSIX兼容;从应用程序看,很多代码编写使用了特定操作系统支持的调用,并没有很好地使用POSIX接口。但是,很显然,使用POSIX接口的应用程序在兼容POSIX的操作系统间移植将是很轻松的事情。

POSIX标准是一个处于不断发展之中的庞大体系,包括:

  • 1003.1 系统API
  • 1003.2 SHELL及工具
  • 1003.3 POSIX符合性测试方法
  • 1003.5 ADA语言接口
  • 1003.13 标准化可移植实时应用环境AEP

其中,POSIX 1003.1系列标准是POSIX最主体内容,也是我们最关心的部分。该系列内容由如下主体定义以及一些扩展和增补组成:

  • 1003.1 1988年通过,基本OS接口
  • 1003.1b 1993年通过,实时扩展
  • 1003.1c 1995年通过,线程扩展
  • 1003.1d 1999年通过,实时扩展
  • 1003.1j 2000年通过,高级实时扩展
  • 1003.1q 2000年通过,事件数据流跟踪

三、测试POISX线程相关的函数

VxWorks Test Posix

图3.1 创建RTP工程

build spec

图3.2 选择编译器