当前位置:首页 > 嵌入式 > 嵌入式软件

在任务运行过程中,会出现一些异常的情况,导致任务不能正常运行或者对操作系统造成影响。一般来说,这些异常是由程序的逻辑错误造成的,防止这些异常情况的出现和出现后进行补救就有格外重要的意义。

  CPU异常

  在VxWorks中,当任务的指令执行中出现了指令非法、地址寻址错误、总线错、除数为0等情况时,就会出现CPU异常。比较常见的情况是,指针地址非法或者数组下标越界就有可能存取有效地址空间以外的地址而造成CPU异常。VxWorks提供一个异常处理句柄(handler)和一个名为tExcTask的任务来处理异常。异常出现后任务成为挂起状态(suspend),并且不能转变为其它状态。在VxWorks中,有一个异常向量表来对应各种异常,外部中断也作为一种特殊的异常。VxWorks的做法是把多种异常的处理映射到同一个异常处理函数进行处理,并且VxWorks提供了向这个异常处理函数中钩挂用户的异常处理函数的接口excHookAdd(),也可以将某一个异常向量映射到指定的处理函数。

  代码重入与共享

  在应用中,可能会出现多个任务调用同一段代码的情况,由于任务占用CPU是串行的,不会出码资源使用冲突。但是,不同优先级的任务同时调用同一段代码,则可能出现低优先级任务执行某一函数时被执行该函数的高优先级任务打断的情况,如果函数中要改写全局变量而没有使用互斥,就有可能导致错误的存取。例如在中断中调用内存分配或者释放函数,如果某个任务正在调用内存分配函数或者是内存释放函数,打断该任务时会造成异常,可能导致内存泄漏,甚至有可能会因在中断中异常而reboot。另外,如果多个任务共用的代码中有全局变量且使用目的不同,或者多个任务的代码中有全局变量同名的情况,则有可能造成变量使用中的错误。VxWorks提供了任务变量(taskVar)的方法来解决这个问题,任务可以将使用的全局变量作为任务变量独立使用,添加的任务变量保存在任务的上下文中,任务切换时保存当前内容。

  符号表的使用

  VxWorks中有模块()的概念。装载模块完成目标代码文件在内存中的链接,并可以将目标代码文件中的函数与全局变量加入符号表。符号表中的符号对C语言编写的函数以原来名字命名,对于C++语言的函数则是在后面加上形参的数据类型作为符号名。如f1( )的符号名为f1__Fv,最后的v表示void类型;f2(int)符号名为f2__Fi,f3(int,int)为f3__Fii,依此类推。代码的编译过程中并不对要使用的函数和变量进行检查。例如调用一个并不存在的函数编译并不报错,编译器认为此函数可能在操作系统内核中或者已经下载的目标文件中,但在目标文件下载时会找不到要调用的函数。如果符号表中的符号出现了重名,譬如两次下载的目标文件中有函数重名,则要作散列处理,之后对该函数的调用是最后加入符号表的函数,而之前已经装载的模块则不会受到影响。如果应用程序中使用了与操作系统内核同名的符号,则对操作系统某些API函数的调用将会失败。

  特殊的任务保护

  在VxWorks中,当一个任务被删除,其它任务不会得到通知,而且由于任务间的独立性,每一个任务可以无限制地删除其它任务。在应用中,我们可能会把需要保护任务误删除。VxWorks 提供的两个函数taskSafe( )和taskUn( )将通知意外删除任务而引起的问题。当任务调用taskSafe( )时,从调用的那一刻起,该任务就被保护起来而不会被其它任务删除。如果任务1试图删除已经调用taskSafe( )的任务2,则任务1将被阻塞,直到任务2调用taskUn( )。保护只能由任务自己实现,一个任务不能或unsafe另外一个任务。taskSafe( )和taskUnsafe( )支持嵌套模式。如果有嵌套发生,一个计数器将开始工作,每有一个taskSafe( )被调用,则计数器加1;调用1个taskUnsafe( ),则计数器减1。只有当计数器为0时,才能删除该任务。

  有时为了执行效率等原因,任务的运行需要禁止基于优先级的抢占,这可以通过调用taskLock( )实现。如果任务1调用taskLock( )禁止了高优先级任务对它的抢占,当任务1被阻塞或被暂停,核心将调度下一个具有最高优先级的就绪任务运行。如果这时任务1又就绪且被调度运行,抢占又被禁止。但是,禁止基于优先级的抢占可以阻止任务切换,却并不会屏蔽中断。调用taskUnLock( )可以解除优先级抢占的禁止,通过调用taskLock( )和taskUnLock( )可以实现对临界资源的互斥访问。

  任务调度中CPU的占用

  如前所述,不同优先级的任务是通过抢占获得CPU使用权的,如果不选时间片轮转,相同优先级的任务之间也是抢占CPU的。任务就绪队列中正在运行的任务如果不主动放弃CPU,则其它同优先级的任务不会得到运行,这样就有可能看到几个同优先级的任务状态同为READY,但实际上只有一个任务在运行的现象。比如在一个任务中用taskSpawn()函数创建一个同优先级或低优先级的任务,如果原任务一直占用CPU,新任务就不会开始运行。调用函数taskDelay()可以使任务放弃CPU一定的时间,从而实现任务间时间上的同步;也可以放弃CPU零时间,将任务移至同优先级就绪队列的末尾,这样就可以实现多个同优先级的任务并发运行。另外,由于中断能够打断任务的运行,中断处理函数中执行的代码就要尽可能少地占用CPU,并且中断中不能有获取信号量的操作。一旦处于等待之中,所有的任务均得不到运行,用户可能会有CPU不响应的错觉。

  堆栈越界

  如前所述,每一个任务都有自己的堆栈,任务创建时进行初始化。每个堆栈的大小是固定,但是任务运行过程中并不对堆栈的使用进行限制。由于VxWorks不对内存访问作限制,栈顶超越了原定的值后出现越界,这样操作系统中该任务堆栈以外的内存区域就可能被改写,会造成难以预料的结果,甚至可能造成任务的上下文区域被改写而任务消失。造成越界的原因主要是在函数中定义了比较大的数组,以致进栈时越界。这样在编写程序时,就要求在堆栈许可的范围内定义数组。如果确实需要比较大的内存空间,可以使用操作系统的内存分配函数来获得内存。由于堆栈越界后有可能使任务的控制信息被破坏,使得对堆栈越界的检测比较困难,例如可以在栈底写入一串特殊字符,用另外一个任务或者中断服务程序经常来检查是否被改写来判断越界。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

VxWorks是一款广泛应用于嵌入式系统的实时操作系统(RTOS)。作为实时操作系统领域的领导者,VxWorks以其强大的功能和可靠性,在多个行业领域得到了广泛应用。本文将向读者简要介绍VxWorks系统,包括其定义、特...

关键字: VxWorks 操作系统 嵌入式

自己目前开发的嵌入式开发所用的操作系统是VxWorks,以前读大学的时候用的最多的是linux操作系统,但是,对于这两种操作系统之间到底有什么区别,还真没有真正去细心的总结过,被别人问起时,难免有些尴尬的感觉,毕竟自己是...

关键字: VxWorks Linux

调试指令,dbgHelp显示所有的调试命令

关键字: VxWorks 调试命令

Amazon Lookout for Vision在图像和视频流上使用亚马逊云科技训练的计算机视觉模型,以发现产品或生产过程中的异常和缺陷,目前使用Lookout for Vision的用户和合作伙伴包括GE医疗、亚马逊...

关键字: 亚马逊 视觉模型 异常

有许多朋友在学习,或者开发STM32时都遇到过HardFault_Handler的情况。

关键字: CortexM3 Faults 异常

在嵌入式软件开发中,因为代码质量不佳、线程冲突、栈溢出等问题,会造成Arm的HardFault。

关键字: 嵌入式 HardFault 异常

  目前,触摸面板在全球已开始自成一项产业,作为一项先进的计算机输入设备,它是目前最简单、方便、自然的而且又适用于多媒体信息查询装备。触摸面板具有坚固耐用、反应速度快、节省空间、易于交流等许多优

关键字: VxWorks 通信模型

  • 新一代实时操作系统的 Security Profile 在各个层面为互联设备提供全程保护。   • 从Wibu-Systems中无缝集成基于硬件和基于软件的安

关键字: profile security VxWorks 物联网 风河公司

  • Wind River 的COTS (商用现货) 平台为空客集团ATLANTE无人机项目提供核心安全性相关的综合模块化航电应用软件。   • VxWorks 6

关键字: 653 platform VxWorks 风河公司

2020年,StackOverflow对全球开发人员进行了关于最受欢迎的编程语言的调查。 在排名中,Python语言超过Java,排名第二(紧随Rust之后)。 与去年的排名相比,Python已成为增长最快的编程语言,并...

关键字: python VxWorks 嵌入式
关闭
关闭