《VxWorks7编程指南》笔记(二)——多任务

目录

 

1.任务与多任务

2.VxWorks系统任务

3.任务拥有权与继承属性

4.任务状态和转换

5.任务调度

6.任务创建与激活

7.任务名称与ID

8.任务选项

9.任务栈

10.任务信息

11.任务执行控制

12.任务调度控制

13.任务删除及删除保护

14.任务扩展:使用钩子函数

15.任务错误状态:errno

16.任务异常处理

17.共享代码与重入

18.内核任务环境变量


1.任务与多任务

多任务环境允许实时应用程序由一系列独立的任务构成,这些任务拥有自己的执行与系统资源。

2.VxWorks系统任务

根据具体的配置,VxWorks在启动时将运行各种系统任务,其中有些任务会一直运行。

VxWorks基础任务如下:

 

可选组件任务如下:

3.任务拥有权与继承属性

根用户是所有任务和RTP的默认拥有者。可以使用如下函数了解任务拥有权与继承属性:

  • getuid()
  • getgid()
  • setuid()
  • setgid()
  • taskShow()
  • ps -l (用于RTP)

4.任务状态和转换

下表描述了在开发工具中课件的任务状态和状态符号。需要注意的是,任务状态是可以累加的,同一时刻一个任务可能处于多个状态下。

 

Shell命令行中的任务状态示例

 

基本的任务状态转换图示

下图展示了基本的任务状态转换关系。为了简化关系,图中没有展示上述的叠加状态,也没有展示STOP状态。

注意:taskSpawn()函数将创建一个任务,并使之进入Ready状态;taskCreate()函数将创建一个任务,并使之进入suspend状态。

 

5.任务调度

多任务环境需要任务调度器将CPU分配给处于ready状态的任务。VxWorks提供了多种调度器选项:

  • 传统VxWorks调度器,提供基于优先级的抢占调度,具备round-robin扩展;
  • VxWorks POSIX线程调度器,用于运行进程中的线程(RTP)
  • RTP分时调度器,允许按照时间片调度RTP;
  • 自定义调度器框架,允许自定义开发调度器;

任务优先级

任务优先级在创建时指定,任务调度器依赖于优先级进行调度。VxWorks内核提供了256个优先级,最高优先级为0,最低优先级为255。

 

内核应用程序优先级

所有应用程序应该运行在优先级100~255。

注意:网络应用程序任务的优先级可能需要运行在低于100的优先级下。

 

驱动程序的任务优先级

驱动任务优先级范围为51~99。

 

任务倒置:将一个内核任务移动到优先级队列的队尾

可使用函数taskRotate()实现该功能,结合该函数可以间接实现round-robin机制。

6.任务创建与激活

taskLib库中提供了创建、控制任务的函数,也提供了获取任务信息的函数。如下所示:

7.任务名称与ID

taskLib中提供的任务名称和ID函数如下所示:

8.任务选项

9.任务栈

任务的栈空间是在任务创建时定义的。可以使用guard zone使任务栈不可执行,从而对任务栈进行保护。

想要确切知道一个任务需要多大栈空间是很困难的。为了避免栈溢出与崩溃,可以在分配任务栈时分配一个比预期大小更大的空间。之后可以使用checkStack()函数或ti()函数周期性地检查任务栈。当确认了具体的使用情况后,可以调整栈大小以适应测试或系统部署的要求。

 

任务栈保护

可以使用guard zone通过将任务栈设置为不可执行,来实现任务栈保护。

 

任务栈guard zone

通过配置INCLUDE_PROTECT_TASK_STACK组件,可以为任务使能guard zone保护功能。如果对系统内存要求比较严格,后续在进行最终测试或系统部署时可以移除该组件。

在任务执行时,一个对上的guard zone可以确保任务栈不超过其预定义的大小上限,以免搞崩其他数据或任务栈;一个对下的guard zone可以确保对任务栈的访问不低于其栈底空间,以免于由缓冲区移除导致的内存崩溃。

10.任务信息

任务信息是动态的,除非任务挂起,否则任务信息所反馈的信息可能不是最新的。可以使用如下函数获取任务信息。

11.任务执行控制

以下函数可用于控制任务的执行状态:

如果需要将任务延迟半秒,可以使用如下方式:

taskDelay(sysClkRateGet()/2)

其中,sysClkRateGet()函数返回了每秒的系统时钟数。使用taskDelay(0),可以直接将CPU使用权让给其他任务,使自己挂起并让同优先级 的其他任务继续执行。

12.任务调度控制

可使用如下函数实现任务调度控制。

13.任务删除及删除保护

任务可以被动态地删除,也可以通过保护措施避免被其他任务删除。具体函数如下:

 

删除保护

任务在执行关键代码时,为了避免被删除,可以通过增加其删除保护计数器来实现任务保护。具体方法包括:

  • 调用taskSafe();
  • 获取使用了SEM_DELETE_SAFE选项的互斥信号量。

对于使用SEM_DELETE_SAFE选项的信号量,在使用semTake()获取它时,效果类似于调用taskSafe();在使用semGive()释放它时,效果类似于调用taskUnsafe()。

当任务执行完关键代码后,为了允许被其他函数删除,需要减少其删除保护计数器。具体方法包括:

  • 调用taskUnsafe();
  • 释放具有删除保护属性的互斥信号量。

14.任务扩展:使用钩子函数

VxWorks提供钩子函数管理API,用于注册在创建、删除或任务切换时所需触发的钩子函数。具体函数接口如下:

 

15.任务错误状态:errno

C函数库中使用了一个全局整型变量errno,用于反馈函数执行错误时的具体错误码。此由ANSI C标准中所规定。

注意:当前描述的内容主要针对VxWorks,对于SMP需要另外考虑。

 

errno的分层定义

在VxWorks内核中,同时使用了两种方法定义errno:

  • ANSI C全局变量errno;
  • errno.h中定义的一个宏errno,该宏定义调用一个函数__errno()。该函数返回全局变量errno的地址。使用该方法的好处是:因为__errno()是一个函数,所以可以在调试时为其添加断点,从而确定是否有错误发生。

 

每个任务具有独立的errno值

为了在多任务环境下使用errno,VxWorks为每个任务保留了相应的errno。因此,在每次进行任务切换时,内核将errno作为任务栈的一部分保存在任务栈中。

16.任务异常处理

信号(signal)可以用于标识软件或硬件异常。

17.共享代码与重入

供多个任务执行的一份代码被称为共享代码,共享代码必须是可重入的。

18.内核任务环境变量

默认情况下,内核任务共享相同的环境变量。但是如果一个任务在创建时使用了VX_PRIVATE_ENV选项,那么它就可以拥有私有的环境变量。

envLib环境变量API

envLib库提供了兼容Unix的环境变量功能。具体函数结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weekman93

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值