天天看点

Win32 API意外终止WinCE如何应对?

Win32 API意外终止WinCE如何应对?

上一篇 / 下一篇  2009-05-11 09:49:07 / 个人分类:微软技术

查看( 67 ) / 评论( 1 ) / 评分( 0 / 0 )

【IT168 专稿】http://tech.it168.com/a2009/0115/263/000000263128.shtml

WinCE与其它嵌入式操作系统相比优点之一,是WinCE的应用程序开发接口也是Win32 API,这与桌面Windows是基本一致的,这使许多嵌入式开发人员得以充分利用在Windows平台上的经验和工具。

  但在此过程中,需要小心应对WinCE意外终止的发生,因为意外终止处理得好坏直接关系到系统的健壮性和稳定度。近期我在一个WinCE嵌入式项目中就体验到没有处理好Win32意外终止的惨痛教训,后果是严重影响系统稳定性。因此,处理Win32意外终止并不是表面看起来的那么简单。这里与大家分享我在开发中遇到的一些问题和总结。

.b%n B?0W+m^9be2U0ITPUB个人空间h+fZ(g'@$FM&_

 1. 什么是Win32 API意外终止?ITPUB个人空间1NM X/~ zk$r

ITPUB个人空间0t z6~:p"S0i/{p

  对于世界上成千上万的Windows平台程序开发人员来说,Win32程序模式是很常见的。理所当然的,它也成了WinCE嵌入式系统理想的程序界面形式。

  (1)什么是Win32 API?

!a+sT5lIZ0  Win32 API是指基于微软32位操作系统平台的一种应用编程接口(API:Application Programming Interface)。Win32 API函数是Windows提供给应用程序与操作系统的接口,犹如积木块一样,通过这个接口可以搭建出各种界面丰富,功能灵活的应用程序,通过接口函数能大大简化内核调用的复杂性。所以,Win32 API编程指的是用Windows提供的各种API函数在Windows平台上编写应用程序。

  简单说,可以认为API函数是构筑整个Windows应用的中间联接器。在它的下面是Windows的操作系统内核,而它的上面则是应用程序。因此,Win32 API是WinCE内核与应用程序之间的界面,它将内核提供的功能进行函数包装,应用程序通过调用相关函数而获得相应的系统功能。之所以称之为Win32,是因为Windows平台使用的是最普遍的32位操作系统(现在有些Windows平台是64位了)。

  (2)什么是Win32意外终止?

qZCg*xet]A)Z*M1I0  WinCE内核除了协调应用程序的执行、分配内存、管理系统资源之外,同时也是一个很大的服务中心,它调用着各种服务(每一种服务就是一个函数)来达到帮助应用程序开启视窗、执行各种操作、使用周边设备等目的。因此,在 WinCE工作环境底下执行的应用程序,常常需要调用大量的Win32 API。

  Win32 API 在WinCE内核和应用程序的调用和服务上提供很好的方便,但有时会发生让人心烦的事情,就是这些Win32 API调用失败的时候会造成WinCE系统意外终止或者非法死机,这时系统会弹出一个让开发人员心烦的提示框,提示系统正在发生Win32 意外而被迫终止应用程序。

 2. 什么原因会导致Win32意外终止?ITPUB个人空间V$J t B X9U$F

,Y @v;f1O]0  在我所负责的项目上,由于在定制和剪裁WinCE系统时没有严谨的考虑和多方测试,结果是应用程序在运行时经常会弹出一个让我心跳的提示框,总是提示这样或那样的原因致使Win32意外终止,这也使我差点处于崩溃。

  (1)定制和剪裁内核不合理,导致API调用意外ITPUB个人空间p,k%M;Q1^&R,YG0t

  一个WinCE系统在定制和剪裁时是一个复杂的过程,不但需要对本机硬件设备合理选择,还需要针对相应的BSP板级支持包进行驱动程序开发。如果对系统主要硬件设备,像板载BSP、CPU和其它外围设备不熟悉,都有可能导致系统无法运转,特别是WinCE系统对内核的定制和检测更苛刻。

很多时候导致系统崩溃或瘫痪的原因,可能是剪裁时由于系统文件版本不兼容或者损坏了系统文件,而导致系统发生莫名其妙的致命错误;也可能是在添加外围设备时,由于硬件本身或者驱动程序不匹配或不兼容,导致系统注册表因不明原因损坏或紊乱,还可能是其它各种不明的原因导致系统发生莫名其妙的致命错误,最终造成Win32 API 调用意外终止。

CF8G1j0nK0

rUzI[.uP)z*y0  (2)设备驱动不兼容,导致API函数调用异常ITPUB个人空间z)Q4Wb7nP#z `

  许多外围设备在桌面版本Windows平台是兼容的,然而在WinCE平台下,因为组件剪裁和定制的关系,许多外围设备会产生兼容性的问题。因此,为嵌入式系统创造可靠的设备驱动接口,在WinCE程序设计的过程中是富有挑战性的部分。虽然幸运的是Win32 API 提供了一套丰富的设备接口方法,使得许多设备接口程序更容易适合于特定嵌入式系统的需要。

  但在某些特定应用与场合下,当设备驱动程序接口必须同时管理不同应用对设备的调用时,WIN32 API 就需要支持对设备的同步和异步的访问,而且适当和适时的处理异步事件,有时对于特定的嵌入式应用程序是至关紧要的。如果这时设备驱动API函数管理不当,就会导致API函数同步或异步调用异常,也会导致Win32 API意外终止。

  (3)Win32 多线程出错,导致API处理出错

}v f?0`0  WinCE系统的的特点之一,是在一个运行中的程序里支持执行多个线程。因此,WinCE是一个多任务和多线程的操作系统。对于嵌入式应用程序来说,WinCE的多线程执行能力重要的体现是在它对函数的调用。因此,Win32开发人员需要优先考虑Win32的多线程的创立与同步。

  Win32的多线程处理同其它的嵌入式操作系统是有区别的。在WinCE中多线程管理(时序安排,同步和资源管理)由内核来完成,是通过API函数装入内核来建立和管理应用程序中的多线程。对于若干个同时运行的应用程序,Win32 API已经为多线程管理和同步提供了一套的完备的处理方法。但如果设计不合理当这些多线程出现同步误差时,就会导致Win32 API调用出错,当然也就可能会导致Win32 API调用意外终止了。

  (4)中断处理出错,导致API调用出错

4Tyi/]2E7p!_ T e#b0  作为一嵌入式开发人员,最需要关心的是WinCE中断消息的处理规则会不会影响外部系统接口的时序。一般来说,在应用WinCE中断设置时是需要细心设计和准确衡量,以保证其中断时序以及其它相关的特性是与WinCE系统的需求是适应的。

  WinCE的中断消息有各种各样来源,包括操作系统、用户活动如键盘输入、鼠标、触摸屏幕以及其它运行的程序或者线程。因此,嵌入式应用程序经常有时间临界的设备接口需要,需要在最小的规定时间之内对设备和系统事件作出反应。为了支持这样的应用程序,WinCE会提供优先级的中断传送,每一个中断有一个优先级与它们相联系。一般来说,WinCE内核的中断特性是按规则来制定中断时序和优先级。但当发生的意外中断超出规则时,就会造成Win32 API调用出错,从而终止程序的运行。 

(5)内存管理不善,导致API调用问题ITPUB个人空间 cc7[?;V)Q"G'[

Win32 API为向开发人员提供了一套完备的和一致的接口。像其它的32 位Windows平台一样,Win CE操作系统也有虚拟内存的特性。在绝大部分应用程序开发时,开发人员是不需要考虑特定内存结构,WinCE内核会自动管理内存资源,和向Win32 API 提供必要的分配、使用和释放内存的接口。然而某些嵌入式应用程序,特别是那些有严格的内存资源约束或者临界时序要求的,又因为在内存管理的方法上也有许多不同的处理方式,当所选择的方式管理内存不当时,就有机会会导致内存失败,进而影响到Win32 API的调用。

n5bb&G| tD0

-FCb ~Ntl/-[5E0  3. Win32 API意外终止的处理方法

@1On*Ip/xx0ITPUB个人空间m Y5M lpr7{

  (1)利用结构化宏来处理意外发生ITPUB个人空间 D cdtEg8r9D

  Win32拥有强大的编程技术来处理意外情况的发生,它有相应一套的Win32 API函数来发现未预料到的错误状况,并且使之恢复。这种Win32意外情况处理函数,我们称为Win32 API定义的宏,这是一种结构化的方式。

  这种结构化宏的意外处理方式,允许危险的段代码可能由于硬件资源问题、设备冲突和微小编码错误而导致失败,它能使这部分可能失败的程序与其余的应用程序分开。这就保护了应用程序能继续运行,使之免于意外终止或者产生敏感的系统问题。因此,Win32结构化意外情况处理宏,是一种容易实现并且强大的保护应用程序免受未预料到的失败的方法。

  (2)定制设备的WIN32 APIITPUB个人空间qW6R4L&^ ri

  嵌入式系统在处理设备接口问题是一个挑战。当开发一个新的硬件平台时,除非只使用常规的硬件,否则就可能需要定制设备驱动程序来支持新的外围设备,这时也就可能需要配置WinCE来包含一些设备处理必要的组件,这时为满足新的设备也会需要编写相应的驱动接口代码。因此,为保证新的外围设备调用的一致性,关键就在于定制WIN32 API。

  (3)有效应用多线程编程技术ITPUB个人空间#lTy5e9G-{

  进程是一种拥有自己的内存、文件句柄和其它系统资源的运行程序, 单个进程也叫线程。为了向应用程序提供多线程功能,Win32 API函数集中提供了一些处理多线程的函数集,它包括创建线程、终止线程、建立互斥区等,Win32 API还提供一组能使线程阻塞其自身执行的等待函数。因此,在某些环境中,当某一进程通过某种形式的进程间通信要求另一进程关闭时,在应用这些API函数时就应该要求保证干净地关闭其它的Win32 应用程序,小心避免多线程冲突问题,这样就能避免Win32 API调用意外的发生。

  (4)合理配置内存,减少API调用失败ITPUB个人空间't_ q5qtB1/)CP|v)m

  WinCE的内存管理有一套完整的机制,当系统内存溢出时,它会选择一个或几个适当的进程杀掉以维持系统的稳定运行。不过虽然WinCE竭尽全力去选择那些真正是罪魁祸首的进程,但是难免会出错,到头来系统会因为误杀进程从而使内存管理失败。这个时候就需要在程序设计时人为地设定一些规则,通过按一定的规则来调整进程以实现干预控制。但需要注意的是,人为地设定某些干预规则是比较危险的,除非能100%肯定被干预的进程有问题,不然这种愚蠢的干预也会导致Win32 API意外终止。

  简而言之, WinCE与其它Windows平台兼容的Win32 API的特性消除了许多嵌入式平台的障碍,开发人员通过使用Win32 API技术节省了许多开发成本,但前提是必须保证在WinCE系统下Win32 API不会因为误用而意外的终止正常的运行。

继续阅读