VxWorks版本的MSDN(1):任务管理API开发手册
文档概述
本手册详细介绍了VxWorks实时操作系统中任务管理相关的API函数。VxWorks采用基于优先级的抢占式调度机制,支持256个优先级(0-255,0为最高优先级)。任务管理API提供了创建、控制、查询和删除任务的全套功能,是VxWorks多任务编程的基础。
包含头文件
#include <vxWorks.h>
#include <taskLib.h>
任务状态说明
VxWorks中的任务可以处于以下状态:
- DORMANT:已创建但未激活
- READY:已准备好运行,等待CPU资源
- RUNNING:当前正在执行
- PENDED:因等待资源(如信号量、消息队列)而阻塞
-
DELAYED:执行了
taskDelay()而延迟 -
SUSPENDED:被
taskSuspend()挂起
1. taskSpawn – 创建并激活任务
函数原型
TASK_ID taskSpawn(
char *name, /* 任务名称 */
int priority, /* 任务优先级 */
int options, /* 任务选项 */
int stackSize, /* 堆栈大小(字节) */
FUNCPTR entryPt, /* 入口函数指针 */
int arg1, /* 参数1 */
int arg2, /* 参数2 */
int arg3, /* 参数3 */
int arg4, /* 参数4 */
int arg5, /* 参数5 */
int arg6, /* 参数6 */
int arg7, /* 参数7 */
int arg8, /* 参数8 */
int arg9, /* 参数9 */
int arg10 /* 参数10 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
name |
char * |
任务名称字符串。可以为NULL,系统会自动生成默认名称(如"t1"、"t2"等)。 |
priority |
int |
任务优先级,范围0-255。0为最高优先级,255为最低优先级。 |
options |
int |
任务选项标志位,可以是以下值的组合: • VX_FP_TASK (0x0008):启用浮点运算支持• VX_NO_STACK_FILL (0x0100):不填充堆栈• VX_PRIVATE_ENV (0x0080):使用私有环境变量• VX_UNBREAKABLE (0x0002):禁止断点调试 |
stackSize |
int |
任务堆栈大小(字节)。必须足够大以容纳函数调用和局部变量。 |
entryPt |
FUNCPTR |
任务入口函数指针。函数原型应为void func(int arg1, int arg2, ...)。 |
arg1–arg10
|
int |
传递给入口函数的参数,最多10个。 |
返回值
-
成功:返回新创建任务的ID(
TASK_ID类型) -
失败:返回
ERROR(-1)
描述
taskSpawn()是VxWorks中最常用的任务创建函数。它一次性完成以下操作:
- 分配内存用于任务控制块(TCB)和堆栈
- 初始化TCB,设置任务名称、优先级、选项等属性
- 将任务置于就绪状态(READY),等待调度执行
创建的任务会立即进入就绪队列,如果其优先级高于当前运行任务,将立即抢占CPU。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
/* 任务入口函数 */
void myTask(int param1, int param2)
{
printf("任务启动!参数1=%d,参数2=%d\n", param1, param2);
/* 任务主体代码 */
for (int i = 0; i < 5; i++) {
printf("任务执行第%d次\n", i + 1);
taskDelay(sysClkRateGet()); /* 延迟1秒 */
}
printf("任务完成\n");
}
/* 创建任务函数 */
void createTasks(void)
{
TASK_ID tid1, tid2;
/* 创建第一个任务 */
tid1 = taskSpawn(
"DataProcessor", /* 任务名称 */
100, /* 优先级100(中等) */
VX_FP_TASK, /* 启用浮点支持 */
2048, /* 堆栈大小2KB */
(FUNCPTR)myTask, /* 入口函数 */
100, /* 参数1 */
200, /* 参数2 */
0,0,0,0,0,0,0,0 /* 剩余参数填0 */
);
if (tid1 == ERROR) {
printf("创建任务1失败!\n");
return;
}
printf("任务1创建成功,ID=%d\n", tid1);
/* 创建第二个任务 */
tid2 = taskSpawn(
"NetworkHandler", /* 任务名称 */
110, /* 优先级110(稍低) */
0, /* 无特殊选项 */
4096, /* 堆栈大小4KB */
(FUNCPTR)myTask, /* 入口函数 */
300, /* 参数1 */
400, /* 参数2 */
0,0,0,0,0,0,0,0 /* 剩余参数填0 */
);
if (tid2 == ERROR) {
printf("创建任务2失败!\n");
return;
}
printf("任务2创建成功,ID=%d\n", tid2);
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 10);
}
注意事项
- 任务名称不要求全局唯一,多个任务可以使用相同名称
- 堆栈大小应根据任务实际需求合理设置,过小可能导致栈溢出
- 如果任务需要浮点运算,必须设置
VX_FP_TASK选项 - 创建任务失败通常是因为内存不足
2. taskInit – 初始化任务
函数原型
STATUS taskInit(
WIND_TCB *pTcb, /* TCB结构指针 */
char *name, /* 任务名称 */
int priority, /* 任务优先级 */
int options, /* 任务选项 */
char *pStackBase, /* 堆栈基地址 */
int stackSize, /* 堆栈大小(字节) */
FUNCPTR entryPt, /* 入口函数指针 */
int arg1, /* 参数1 */
int arg2, /* 参数2 */
int arg3, /* 参数3 */
int arg4, /* 参数4 */
int arg5, /* 参数5 */
int arg6, /* 参数6 */
int arg7, /* 参数7 */
int arg8, /* 参数8 */
int arg9, /* 参数9 */
int arg10 /* 参数10 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
pTcb |
WIND_TCB * |
指向任务控制块(TCB)的指针。必须由调用者分配内存。 |
name |
char * |
任务名称字符串。 |
priority |
int |
任务优先级,范围0-255。 |
options |
int |
任务选项标志位。 |
pStackBase |
char * |
堆栈基地址。必须由调用者分配内存。 |
stackSize |
int |
堆栈大小(字节)。 |
entryPt |
FUNCPTR |
任务入口函数指针。 |
arg1–arg10
|
int |
传递给入口函数的参数。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskInit()函数初始化一个任务,但不激活它。与taskSpawn()不同,taskInit()需要调用者提供TCB和堆栈的内存空间。初始化后的任务处于休眠状态(DORMANT),需要调用taskActivate()才能激活。
这种方法适用于需要精确控制内存分配的场景,或者需要在特定内存区域创建任务的情况。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
#include <stdlib.h>
/* 任务入口函数 */
void customTask(int param)
{
printf("自定义任务启动,参数=%d\n", param);
for (int i = 0; i < 3; i++) {
printf("自定义任务执行中...\n");
taskDelay(sysClkRateGet());
}
printf("自定义任务完成\n");
}
void createCustomTask(void)
{
WIND_TCB *pTcb;
char *pStack;
int stackSize = 4096; /* 4KB堆栈 */
/* 分配TCB内存 */
pTcb = (WIND_TCB *)malloc(sizeof(WIND_TCB));
if (pTcb == NULL) {
printf("分配TCB内存失败!\n");
return;
}
/* 分配堆栈内存 */
pStack = (char *)malloc(stackSize);
if (pStack == NULL) {
printf("分配堆栈内存失败!\n");
free(pTcb);
return;
}
/* 初始化任务 */
STATUS status = taskInit(
pTcb, /* TCB指针 */
"CustomTask", /* 任务名称 */
120, /* 优先级120 */
0, /* 无特殊选项 */
pStack, /* 堆栈基地址 */
stackSize, /* 堆栈大小 */
(FUNCPTR)customTask, /* 入口函数 */
999, /* 参数1 */
0,0,0,0,0,0,0,0,0 /* 剩余参数 */
);
if (status != OK) {
printf("任务初始化失败!\n");
free(pStack);
free(pTcb);
return;
}
printf("任务初始化成功\n");
/* 激活任务 */
TASK_ID tid = (TASK_ID)pTcb; /* TCB地址即为任务ID */
status = taskActivate(tid);
if (status != OK) {
printf("任务激活失败!\n");
} else {
printf("任务激活成功,ID=%d\n", tid);
}
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 5);
/* 清理内存(实际应用中应在任务删除后清理) */
free(pStack);
free(pTcb);
}
注意事项
- 调用者必须确保TCB和堆栈内存正确对齐
- 堆栈内存应足够大,避免溢出
- 初始化后必须调用
taskActivate()才能运行任务 - 内存管理由调用者负责,包括分配和释放
3. taskActivate – 激活任务
函数原型
STATUS taskActivate(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要激活的任务ID。对于taskInit()创建的任务,TCB地址即为任务ID。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskActivate()函数激活一个由taskInit()初始化的任务。激活后,任务进入就绪状态(READY),可以参与调度。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void delayedTask(int delaySeconds)
{
printf("延迟任务启动,将延迟%d秒\n", delaySeconds);
taskDelay(sysClkRateGet() * delaySeconds);
printf("延迟任务完成\n");
}
void activateTaskDemo(void)
{
WIND_TCB tcb;
char stack[2048]; /* 2KB堆栈 */
/* 初始化任务但不激活 */
STATUS status = taskInit(
&tcb,
"DelayedTask",
130,
0,
stack,
sizeof(stack),
(FUNCPTR)delayedTask,
3, /* 延迟3秒 */
0,0,0,0,0,0,0,0,0
);
if (status != OK) {
printf("任务初始化失败\n");
return;
}
printf("任务已初始化,准备激活...\n");
/* 延迟2秒后激活任务 */
taskDelay(sysClkRateGet() * 2);
TASK_ID tid = (TASK_ID)&tcb;
status = taskActivate(tid);
if (status == OK) {
printf("任务激活成功,ID=%d\n", tid);
} else {
printf("任务激活失败\n");
}
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 5);
}
4. taskDelete – 删除任务
函数原型
STATUS taskDelete(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要删除的任务ID。如果为0,表示删除调用任务自身。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskDelete()函数删除指定的任务,释放任务占用的资源(TCB和堆栈)。如果任务处于保护状态(通过taskSafe()),调用者将被阻塞,直到任务解除保护。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void workerTask(void)
{
printf("工作者任务启动\n");
/* 保护自己不被删除 */
taskSafe();
/* 执行关键操作 */
for (int i = 0; i < 10; i++) {
printf("工作者任务执行第%d次\n", i + 1);
taskDelay(sysClkRateGet() / 2); /* 延迟0.5秒 */
if (i == 5) {
printf("解除保护,允许被删除\n");
taskUnsafe();
}
}
printf("工作者任务自然结束\n");
}
void taskManager(void)
{
printf("任务管理器启动\n");
/* 创建工作者任务 */
TASK_ID workerTid = taskSpawn(
"Worker",
140,
0,
2048,
(FUNCPTR)workerTask,
0,0,0,0,0,0,0,0,0,0
);
if (workerTid == ERROR) {
printf("创建工作者任务失败\n");
return;
}
printf("工作者任务创建成功,ID=%d\n", workerTid);
/* 等待3秒 */
taskDelay(sysClkRateGet() * 3);
/* 尝试删除工作者任务 */
printf("尝试删除工作者任务...\n");
STATUS status = taskDelete(workerTid);
if (status == OK) {
printf("工作者任务删除成功\n");
} else {
printf("工作者任务删除失败(可能处于保护状态)\n");
}
/* 再等待2秒查看结果 */
taskDelay(sysClkRateGet() * 2);
printf("任务管理器结束\n");
}
注意事项
- 删除正在使用关键资源的任务可能导致系统不稳定
- 建议使用
taskSafe()/taskUnsafe()保护关键任务 - 任务删除后,其ID不再有效
5. taskDeleteForce – 强制删除任务
函数原型
STATUS taskDeleteForce(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要强制删除的任务ID。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskDeleteForce()函数强制删除指定的任务,即使任务处于保护状态(通过taskSafe())。使用此函数需要特别小心,因为可能破坏任务正在使用的资源。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void protectedTask(void)
{
printf("受保护任务启动\n");
/* 保护自己 */
taskSafe();
printf("受保护任务:我已进入保护状态\n");
/* 模拟长时间运行 */
while (1) {
printf("受保护任务运行中...\n");
taskDelay(sysClkRateGet());
}
/* 这行代码永远不会执行 */
taskUnsafe();
}
void forceDeleteDemo(void)
{
printf("强制删除演示开始\n");
/* 创建受保护任务 */
TASK_ID protectedTid = taskSpawn(
"ProtectedTask",
150,
0,
2048,
(FUNCPTR)protectedTask,
0,0,0,0,0,0,0,0,0,0
);
if (protectedTid == ERROR) {
printf("创建受保护任务失败\n");
return;
}
printf("受保护任务创建成功,ID=%d\n", protectedTid);
/* 等待2秒让任务运行 */
taskDelay(sysClkRateGet() * 2);
/* 尝试普通删除(会失败) */
printf("尝试普通删除...\n");
if (taskDelete(protectedTid) != OK) {
printf("普通删除失败(预期中,任务受保护)\n");
}
/* 等待1秒 */
taskDelay(sysClkRateGet());
/* 强制删除 */
printf("尝试强制删除...\n");
if (taskDeleteForce(protectedTid) == OK) {
printf("强制删除成功\n");
} else {
printf("强制删除失败\n");
}
printf("强制删除演示结束\n");
}
注意事项
- 强制删除可能破坏系统稳定性
- 仅在紧急情况下使用
- 删除后无法恢复任务状态
6. taskSuspend – 挂起任务
函数原型
STATUS taskSuspend(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要挂起的任务ID。如果为0,表示挂起调用任务自身。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskSuspend()函数挂起指定的任务,使其暂停执行。挂起的任务不会参与调度,直到被taskResume()恢复。任务可以在任何状态下被挂起。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void periodicTask(void)
{
int count = 0;
while (1) {
count++;
printf("周期性任务:第%d次执行\n", count);
taskDelay(sysClkRateGet()); /* 每秒执行一次 */
}
}
void suspendResumeDemo(void)
{
printf("挂起/恢复演示开始\n");
/* 创建周期性任务 */
TASK_ID periodicTid = taskSpawn(
"PeriodicTask",
160,
0,
2048,
(FUNCPTR)periodicTask,
0,0,0,0,0,0,0,0,0,0
);
if (periodicTid == ERROR) {
printf("创建周期性任务失败\n");
return;
}
printf("周期性任务创建成功,ID=%d\n", periodicTid);
/* 让任务运行3秒 */
for (int i = 0; i < 3; i++) {
taskDelay(sysClkRateGet());
}
/* 挂起任务 */
printf("挂起周期性任务...\n");
if (taskSuspend(periodicTid) == OK) {
printf("任务挂起成功\n");
}
/* 等待2秒,期间任务不应执行 */
printf("等待2秒(任务应暂停)...\n");
taskDelay(sysClkRateGet() * 2);
/* 恢复任务 */
printf("恢复周期性任务...\n");
if (taskResume(periodicTid) == OK) {
printf("任务恢复成功\n");
}
/* 让任务再运行3秒 */
for (int i = 0; i < 3; i++) {
taskDelay(sysClkRateGet());
}
/* 删除任务 */
taskDelete(periodicTid);
printf("挂起/恢复演示结束\n");
}
7. taskResume – 恢复任务
函数原型
STATUS taskResume(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要恢复的任务ID。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskResume()函数恢复被taskSuspend()挂起的任务。恢复后,任务重新进入就绪状态,可以参与调度。
使用示例
(见taskSuspend示例)
8. taskRestart – 重启任务
函数原型
STATUS taskRestart(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要重启的任务ID。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskRestart()函数重启指定的任务。任务将从其入口函数重新开始执行,但保留原有的ID、优先级、选项和堆栈大小。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void restartableTask(void)
{
static int executionCount = 0;
executionCount++;
printf("可重启任务:第%d次执行开始\n", executionCount);
for (int i = 0; i < 5; i++) {
printf(" 执行步骤%d\n", i + 1);
taskDelay(sysClkRateGet() / 2); /* 延迟0.5秒 */
}
printf("可重启任务:第%d次执行结束\n", executionCount);
}
void restartDemo(void)
{
printf("任务重启演示开始\n");
/* 创建可重启任务 */
TASK_ID restartableTid = taskSpawn(
"RestartableTask",
170,
0,
2048,
(FUNCPTR)restartableTask,
0,0,0,0,0,0,0,0,0,0
);
if (restartableTid == ERROR) {
printf("创建可重启任务失败\n");
return;
}
printf("可重启任务创建成功,ID=%d\n", restartableTid);
/* 等待任务完成第一次执行 */
taskDelay(sysClkRateGet() * 4);
/* 重启任务 */
printf("重启任务...\n");
if (taskRestart(restartableTid) == OK) {
printf("任务重启成功\n");
}
/* 等待任务完成第二次执行 */
taskDelay(sysClkRateGet() * 4);
/* 再次重启 */
printf("再次重启任务...\n");
if (taskRestart(restartableTid) == OK) {
printf("任务再次重启成功\n");
}
/* 等待任务完成第三次执行 */
taskDelay(sysClkRateGet() * 4);
/* 删除任务 */
taskDelete(restartableTid);
printf("任务重启演示结束\n");
}
9. taskDelay – 延迟任务
函数原型
STATUS taskDelay(
int ticks /* 延迟的tick数 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
ticks |
int |
延迟的时间长度,以系统tick为单位。如果为0,任务将让出CPU给同优先级的其他任务。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskDelay()函数使当前任务延迟指定的时间。任务进入延迟状态(DELAYED),在指定时间后重新进入就绪状态。常用于实现周期性任务或简单的超时等待。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
#include <sysLib.h>
void delayedOperations(void)
{
printf("延迟操作演示开始\n");
/* 获取系统时钟频率 */
int ticksPerSecond = sysClkRateGet();
printf("系统时钟频率:%d ticks/秒\n", ticksPerSecond);
/* 延迟1秒 */
printf("延迟1秒...\n");
taskDelay(ticksPerSecond);
printf("1秒延迟完成\n");
/* 延迟500毫秒 */
printf("延迟500毫秒...\n");
taskDelay(ticksPerSecond / 2);
printf("500毫秒延迟完成\n");
/* 延迟2.5秒 */
printf("延迟2.5秒...\n");
taskDelay(ticksPerSecond * 2 + ticksPerSecond / 2);
printf("2.5秒延迟完成\n");
/* 让出CPU(参数为0) */
printf("让出CPU给同优先级任务...\n");
taskDelay(0);
printf("重新获得CPU\n");
printf("延迟操作演示结束\n");
}
void periodicTaskDemo(void)
{
printf("周期性任务演示\n");
int interval = sysClkRateGet(); /* 1秒间隔 */
int count = 0;
while (count < 10) {
count++;
printf("周期性任务:第%d次执行,时间=%lu\n",
count, tickGet());
/* 等待下一个周期 */
taskDelay(interval);
}
printf("周期性任务完成10次执行\n");
}
注意事项
- 延迟时间不精确,受系统调度影响
- 参数为0时用于主动让出CPU
- 延迟期间任务不消耗CPU资源
10. taskPrioritySet – 设置任务优先级
函数原型
STATUS taskPrioritySet(
int tid, /* 任务ID */
int newPriority /* 新优先级 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要设置优先级的任务ID。如果为0,表示设置调用任务自身的优先级。 |
newPriority |
int |
新的优先级值,范围0-255。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskPrioritySet()函数动态修改任务的优先级。优先级改变后,任务可能立即被抢占或获得CPU,具体取决于新的优先级与当前运行任务优先级的比较结果。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void adaptiveTask(void)
{
int myTid = taskIdSelf();
int originalPriority;
/* 获取原始优先级 */
taskPriorityGet(myTid, &originalPriority);
printf("自适应任务启动,原始优先级=%d\n", originalPriority);
/* 第一阶段:高优先级运行 */
printf("第一阶段:提高优先级到80\n");
taskPrioritySet(myTid, 80);
for (int i = 0; i < 3; i++) {
printf(" 高优先级执行第%d次\n", i + 1);
taskDelay(sysClkRateGet() / 2);
}
/* 第二阶段:降低优先级 */
printf("第二阶段:降低优先级到150\n");
taskPrioritySet(myTid, 150);
for (int i = 0; i < 3; i++) {
printf(" 低优先级执行第%d次\n", i + 1);
taskDelay(sysClkRateGet() / 2);
}
/* 恢复原始优先级 */
printf("恢复原始优先级=%d\n", originalPriority);
taskPrioritySet(myTid, originalPriority);
printf("自适应任务结束\n");
}
void priorityControlDemo(void)
{
printf("优先级控制演示开始\n");
/* 创建自适应任务 */
TASK_ID adaptiveTid = taskSpawn(
"AdaptiveTask",
120, /* 初始优先级 */
0,
2048,
(FUNCPTR)adaptiveTask,
0,0,0,0,0,0,0,0,0,0
);
if (adaptiveTid == ERROR) {
printf("创建自适应任务失败\n");
return;
}
/* 监控任务优先级变化 */
int currentPriority;
for (int i = 0; i < 8; i++) {
taskDelay(sysClkRateGet());
if (taskPriorityGet(adaptiveTid, ¤tPriority) == OK) {
printf("监控:任务当前优先级=%d\n", currentPriority);
}
}
printf("优先级控制演示结束\n");
}
11. taskPriorityGet – 获取任务优先级
函数原型
STATUS taskPriorityGet(
int tid, /* 任务ID */
int *pPriority /* 优先级输出指针 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要获取优先级的任务ID。如果为0,表示获取调用任务自身的优先级。 |
pPriority |
int * |
指向存储优先级值的指针。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskPriorityGet()函数获取指定任务的当前优先级。
使用示例
(见taskPrioritySet示例)
12. taskLock – 禁止任务调度
函数原型
STATUS taskLock(void);
参数说明
无参数。
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskLock()函数禁止任务调度,防止当前任务被更高优先级的任务抢占。调用taskLock()后,当前任务将独占CPU,直到调用taskUnlock()。
注意:taskLock()只禁止任务切换,不禁止中断。应尽量缩短锁定时间。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void criticalSectionTask(void)
{
printf("关键区任务启动\n");
/* 模拟非关键区操作 */
for (int i = 0; i < 3; i++) {
printf("非关键区操作%d\n", i + 1);
taskDelay(sysClkRateGet() / 4);
}
/* 进入关键区 - 禁止调度 */
printf("进入关键区,禁止任务调度...\n");
taskLock();
/* 执行关键操作 */
printf("执行关键操作(不应被抢占)...\n");
for (int i = 0; i < 5; i++) {
printf(" 关键操作步骤%d\n", i + 1);
/* 模拟耗时操作 */
volatile int j;
for (j = 0; j < 1000000; j++);
}
/* 退出关键区 - 允许调度 */
printf("退出关键区,允许任务调度...\n");
taskUnlock();
/* 继续非关键区操作 */
for (int i = 0; i < 3; i++) {
printf("非关键区操作%d(恢复后)\n", i + 1);
taskDelay(sysClkRateGet() / 4);
}
printf("关键区任务结束\n");
}
void highPriorityTask(void)
{
printf("高优先级任务启动(应能抢占低优先级任务)\n");
for (int i = 0; i < 5; i++) {
printf("高优先级任务执行%d\n", i + 1);
taskDelay(sysClkRateGet() / 2);
}
printf("高优先级任务结束\n");
}
void lockDemo(void)
{
printf("任务锁定演示开始\n");
/* 创建低优先级任务(有关键区) */
TASK_ID lowPriTid = taskSpawn(
"LowPriorityTask",
180, /* 低优先级 */
0,
2048,
(FUNCPTR)criticalSectionTask,
0,0,0,0,0,0,0,0,0,0
);
/* 创建高优先级任务 */
TASK_ID highPriTid = taskSpawn(
"HighPriorityTask",
100, /* 高优先级 */
0,
2048,
(FUNCPTR)highPriorityTask,
0,0,0,0,0,0,0,0,0,0
);
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 10);
printf("任务锁定演示结束\n");
}
13. taskUnlock – 允许任务调度
函数原型
STATUS taskUnlock(void);
参数说明
无参数。
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskUnlock()函数恢复任务调度,允许更高优先级的任务抢占当前任务。必须与taskLock()配对使用。
使用示例
(见taskLock示例)
14. taskSafe – 保护任务不被删除
函数原型
STATUS taskSafe(void);
参数说明
无参数。
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskSafe()函数保护当前任务不被意外删除。每个taskSafe()调用都会增加任务的保护计数器,只有计数器为0时任务才能被删除。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void protectedResourceTask(void)
{
printf("受保护资源任务启动\n");
/* 保护任务 */
taskSafe();
printf("任务已受保护(保护计数器=1)\n");
/* 模拟访问受保护资源 */
printf("访问受保护资源...\n");
taskDelay(sysClkRateGet());
/* 再次保护(嵌套保护) */
taskSafe();
printf("任务再次受保护(保护计数器=2)\n");
/* 更多资源访问 */
printf("继续访问资源...\n");
taskDelay(sysClkRateGet());
/* 解除一层保护 */
taskUnsafe();
printf("解除一层保护(保护计数器=1)\n");
/* 最终解除保护 */
taskUnsafe();
printf("解除所有保护(保护计数器=0)\n");
printf("受保护资源任务结束\n");
}
void deleterTask(void)
{
printf("删除者任务启动\n");
/* 等待2秒 */
taskDelay(sysClkRateGet() * 2);
/* 尝试删除受保护任务 */
printf("尝试删除受保护任务...\n");
/* 注意:这里需要知道受保护任务的ID */
/* 在实际应用中,可能需要通过其他方式获取 */
printf("删除者任务结束\n");
}
void safeDemo(void)
{
printf("任务保护演示开始\n");
/* 创建受保护任务 */
TASK_ID protectedTid = taskSpawn(
"ProtectedTask",
190,
0,
2048,
(FUNCPTR)protectedResourceTask,
0,0,0,0,0,0,0,0,0,0
);
/* 创建删除者任务 */
TASK_ID deleterTid = taskSpawn(
"DeleterTask",
195,
0,
2048,
(FUNCPTR)deleterTask,
0,0,0,0,0,0,0,0,0,0
);
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 10);
printf("任务保护演示结束\n");
}
15. taskUnsafe – 解除任务保护
函数原型
STATUS taskUnsafe(void);
参数说明
无参数。
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskUnsafe()函数减少任务的保护计数器。必须与taskSafe()配对使用。
使用示例
(见taskSafe示例)
16. taskIdSelf – 获取当前任务ID
函数原型
int taskIdSelf(void);
参数说明
无参数。
返回值
返回调用任务自身的任务ID。
描述
taskIdSelf()函数返回当前调用任务的ID。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void selfAwareTask(void)
{
int myTid = taskIdSelf();
printf("自我感知任务启动\n");
printf("我的任务ID: %d\n", myTid);
/* 使用自身ID进行其他操作 */
int priority;
if (taskPriorityGet(myTid, &priority) == OK) {
printf("我的优先级: %d\n", priority);
}
printf("自我感知任务结束\n");
}
17. taskIdVerify – 验证任务ID是否存在
函数原型
STATUS taskIdVerify(
int tid /* 要验证的任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要验证的任务ID。 |
返回值
-
存在:返回
OK(0) -
不存在:返回
ERROR(-1)
描述
taskIdVerify()函数验证指定的任务ID是否对应一个存在的任务。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void verifyTask(void)
{
printf("任务验证演示\n");
/* 创建一个任务 */
TASK_ID testTid = taskSpawn(
"TestTask",
200,
0,
1024,
(FUNCPTR)taskDelay,
2, /* 延迟2秒 */
0,0,0,0,0,0,0,0,0
);
if (testTid == ERROR) {
printf("创建测试任务失败\n");
return;
}
printf("测试任务创建成功,ID=%d\n", testTid);
/* 验证任务存在 */
if (taskIdVerify(testTid) == OK) {
printf("验证:任务%d存在\n", testTid);
}
/* 验证不存在的任务 */
if (taskIdVerify(99999) != OK) {
printf("验证:任务99999不存在(预期)\n");
}
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 3);
/* 删除任务后验证 */
taskDelete(testTid);
if (taskIdVerify(testTid) != OK) {
printf("验证:任务%d已被删除(预期)\n", testTid);
}
printf("任务验证演示结束\n");
}
18. taskName – 获取任务名称
函数原型
STATUS taskName(
int tid, /* 任务ID */
char *name /* 名称缓冲区 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要获取名称的任务ID。 |
name |
char * |
指向缓冲区的指针,用于接收任务名称。缓冲区大小至少为NAME_LENGTH+1字节。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskName()函数获取指定任务的名称。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
#include <string.h>
void nameDemo(void)
{
printf("任务名称演示\n");
/* 创建几个有名称的任务 */
TASK_ID tid1 = taskSpawn("DataProcessor", 210, 0, 1024,
(FUNCPTR)taskDelay, 3, 0,0,0,0,0,0,0,0,0);
TASK_ID tid2 = taskSpawn("NetworkHandler", 210, 0, 1024,
(FUNCPTR)taskDelay, 3, 0,0,0,0,0,0,0,0,0);
/* 获取任务名称 */
char name[NAME_LENGTH + 1];
if (taskName(tid1, name) == OK) {
printf("任务%d的名称: %s\n", tid1, name);
}
if (taskName(tid2, name) == OK) {
printf("任务%d的名称: %s\n", tid2, name);
}
/* 获取自身任务名称 */
int myTid = taskIdSelf();
if (taskName(myTid, name) == OK) {
printf("自身任务名称: %s\n", name);
}
/* 清理 */
taskDelay(sysClkRateGet() * 4);
taskDelete(tid1);
taskDelete(tid2);
printf("任务名称演示结束\n");
}
19. taskNameToId – 通过名称获取任务ID
函数原型
int taskNameToId(
char *name /* 任务名称 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
name |
char * |
要查找的任务名称。 |
返回值
- 成功:返回第一个匹配名称的任务ID
-
失败:返回
ERROR(-1)
描述
taskNameToId()函数通过任务名称查找对应的任务ID。如果有多个任务使用相同的名称,返回第一个找到的任务ID。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void nameToIdDemo(void)
{
printf("通过名称查找任务ID演示\n");
/* 创建几个任务,其中两个任务名称相同 */
TASK_ID tid1 = taskSpawn("WorkerTask", 220, 0, 1024,
(FUNCPTR)taskDelay, 5, 0,0,0,0,0,0,0,0,0);
TASK_ID tid2 = taskSpawn("WorkerTask", 220, 0, 1024, // 相同名称
(FUNCPTR)taskDelay, 5, 0,0,0,0,0,0,0,0,0);
TASK_ID tid3 = taskSpawn("MonitorTask", 220, 0, 1024,
(FUNCPTR)taskDelay, 5, 0,0,0,0,0,0,0,0,0);
printf("创建的任务ID: %d, %d, %d\n", tid1, tid2, tid3);
/* 通过名称查找任务ID */
int foundId = taskNameToId("WorkerTask");
if (foundId != ERROR) {
printf("找到名为'WorkerTask'的任务,ID=%d\n", foundId);
// 注意:如果有多个同名任务,只返回第一个
}
foundId = taskNameToId("MonitorTask");
if (foundId != ERROR) {
printf("找到名为'MonitorTask'的任务,ID=%d\n", foundId);
}
foundId = taskNameToId("NonExistentTask");
if (foundId == ERROR) {
printf("没有找到名为'NonExistentTask'的任务\n");
}
/* 清理 */
taskDelay(sysClkRateGet() * 6);
taskDelete(tid1);
taskDelete(tid2);
taskDelete(tid3);
printf("通过名称查找任务ID演示结束\n");
}
20. taskTcb – 获取任务控制块地址
函数原型
WIND_TCB *taskTcb(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要获取TCB的任务ID。 |
返回值
- 成功:返回指向任务控制块(TCB)的指针
-
失败:返回
NULL
描述
taskTcb()函数返回指定任务的控制块地址。任务控制块(TCB)是内核内部数据结构,包含任务的所有状态信息。
警告:直接访问TCB可能导致系统不稳定,这个函数主要用于调试和特殊目的。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void tcbDemo(void)
{
printf("任务控制块演示\n");
/* 创建一个任务 */
TASK_ID tid = taskSpawn("TCBTask", 220, 0, 1024,
(FUNCPTR)taskDelay, 3, 0,0,0,0,0,0,0,0,0);
if (tid == ERROR) {
printf("创建任务失败\n");
return;
}
printf("任务创建成功,ID=%d\n", tid);
/* 获取任务TCB地址 */
WIND_TCB *tcb = taskTcb(tid);
if (tcb != NULL) {
printf("任务TCB地址: 0x%p\n", tcb);
printf("TCB大小: %lu 字节\n", sizeof(WIND_TCB));
} else {
printf("获取TCB失败\n");
}
/* 获取自身任务TCB */
int myTid = taskIdSelf();
WIND_TCB *myTcb = taskTcb(myTid);
if (myTcb != NULL) {
printf("自身任务TCB地址: 0x%p\n", myTcb);
}
/* 清理 */
taskDelay(sysClkRateGet() * 4);
taskDelete(tid);
printf("任务控制块演示结束\n");
}
21. taskIdDefault – 设置默认任务ID
函数原型
STATUS taskIdDefault(
int tid /* 默认任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要设置为默认值的任务ID。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskIdDefault()函数设置默认任务ID。当某些任务管理函数接收0作为任务ID参数时,会使用这个默认值而不是调用任务自身。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void defaultIdDemo(void)
{
printf("默认任务ID演示\n");
/* 创建两个任务 */
TASK_ID tid1 = taskSpawn("TaskA", 230, 0, 1024,
(FUNCPTR)taskDelay, 5, 0,0,0,0,0,0,0,0,0);
TASK_ID tid2 = taskSpawn("TaskB", 230, 0, 1024,
(FUNCPTR)taskDelay, 5, 0,0,0,0,0,0,0,0,0);
printf("创建任务: TaskA=%d, TaskB=%d\n", tid1, tid2);
/* 设置tid2为默认任务 */
if (taskIdDefault(tid2) == OK) {
printf("设置默认任务为: %d\n", tid2);
}
/* 现在使用0作为参数会影响tid2 */
printf("挂起默认任务(应该是tid2)...\n");
if (taskSuspend(0) == OK) {
printf("默认任务已挂起\n");
}
/* 验证tid2是否被挂起 */
BOOL isSuspended = taskIsSuspended(tid2);
if (isSuspended == TRUE) {
printf("确认: tid2已被挂起\n");
}
/* 恢复tid2 */
taskResume(tid2);
/* 恢复默认值为0 */
taskIdDefault(0);
/* 清理 */
taskDelay(sysClkRateGet() * 6);
taskDelete(tid1);
taskDelete(tid2);
printf("默认任务ID演示结束\n");
}
22. taskRegsGet – 获取任务寄存器
函数原型
STATUS taskRegsGet(
int tid, /* 任务ID */
REG_SET *pRegs /* 寄存器集合指针 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要获取寄存器的任务ID。 |
pRegs |
REG_SET * |
指向REG_SET结构体的指针,用于接收寄存器值。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskRegsGet()函数获取指定任务的CPU寄存器值。这是一个低级调试函数,通常用于崩溃分析和系统调试。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
#include <regs.h>
void registersDemo(void)
{
printf("任务寄存器演示\n");
TASK_ID tid = taskSpawn("RegsTask", 240, 0, 1024,
(FUNCPTR)taskDelay, 3, 0,0,0,0,0,0,0,0,0);
if (tid == ERROR) {
printf("创建任务失败\n");
return;
}
/* 获取任务寄存器 */
REG_SET regs;
if (taskRegsGet(tid, ®s) == OK) {
printf("任务寄存器值:\n");
printf(" 程序计数器(PC): 0x%08x\n", regs.pc);
printf(" 堆栈指针(SP): 0x%08x\n", regs.sp);
printf(" 状态寄存器: 0x%08x\n", regs.psr);
} else {
printf("获取寄存器失败\n");
}
/* 获取自身寄存器 */
int myTid = taskIdSelf();
if (taskRegsGet(myTid, ®s) == OK) {
printf("\n自身任务寄存器值:\n");
printf(" 程序计数器(PC): 0x%08x\n", regs.pc);
printf(" 堆栈指针(SP): 0x%08x\n", regs.sp);
}
/* 清理 */
taskDelay(sysClkRateGet() * 4);
taskDelete(tid);
printf("任务寄存器演示结束\n");
}
23. taskRegsSet – 设置任务寄存器
函数原型
STATUS taskRegsSet(
int tid, /* 任务ID */
REG_SET *pRegs /* 寄存器集合指针 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要设置寄存器的任务ID。 |
pRegs |
REG_SET * |
指向REG_SET结构体的指针,包含要设置的寄存器值。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskRegsSet()函数设置指定任务的CPU寄存器值。这是一个危险的低级函数,应仅在调试和特殊恢复场景中使用。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void regsSetDemo(void)
{
printf("设置寄存器演示\n");
printf("警告:此函数可能使系统崩溃!\n");
printf("本演示只展示用法,不实际设置寄存器\n");
TASK_ID tid = taskSpawn("TestTask", 250, 0, 1024,
(FUNCPTR)taskDelay, 2, 0,0,0,0,0,0,0,0,0);
if (tid == ERROR) {
printf("创建任务失败\n");
return;
}
/* 获取当前寄存器值 */
REG_SET originalRegs;
if (taskRegsGet(tid, &originalRegs) != OK) {
printf("获取寄存器失败\n");
taskDelete(tid);
return;
}
printf("原始PC: 0x%08x\n", originalRegs.pc);
printf("原始SP: 0x%08x\n", originalRegs.sp);
/* 备份寄存器值 */
REG_SET backupRegs = originalRegs;
/* 在实际应用中,这里可能会修改某些寄存器值 */
/* 例如:backupRegs.pc = newAddress; */
printf("演示:理论上可以修改寄存器值\n");
printf("但强烈不建议在生产代码中使用!\n");
/* 恢复原始寄存器值 */
if (taskRegsSet(tid, &backupRegs) == OK) {
printf("寄存器已恢复\n");
}
/* 清理 */
taskDelay(sysClkRateGet() * 3);
taskDelete(tid);
printf("设置寄存器演示结束\n");
}
24. taskVarAdd – 添加任务变量
函数原型
STATUS taskVarAdd(
int tid, /* 任务ID */
int *pVar /* 任务变量指针 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要添加变量的任务ID。 |
pVar |
int * |
指向任务变量的指针。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskVarAdd()函数为任务添加一个任务变量。任务变量是任务私有的全局变量,每个任务有自己独立的副本。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
/* 任务变量声明 */
int taskSpecificData;
void taskWithVar(int taskNum)
{
/* 添加任务变量 */
taskVarAdd(taskIdSelf(), &taskSpecificData);
/* 设置任务特定的值 */
taskSpecificData = taskNum * 100;
printf("任务%d: 我的数据 = %d\n", taskNum, taskSpecificData);
/* 修改变量(只影响当前任务的副本) */
for (int i = 0; i < 3; i++) {
taskSpecificData++;
printf("任务%d: 更新后数据 = %d\n", taskNum, taskSpecificData);
taskDelay(sysClkRateGet());
}
}
void taskVarDemo(void)
{
printf("任务变量演示\n");
/* 创建多个使用相同任务变量的任务 */
TASK_ID tasks[3];
for (int i = 0; i < 3; i++) {
char name[20];
sprintf(name, "VarTask%d", i+1);
tasks[i] = taskSpawn(name, 200, 0, 1024,
(FUNCPTR)taskWithVar, i+1, 0,0,0,0,0,0,0,0,0);
}
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 5);
printf("任务变量演示结束\n");
}
25. taskVarDelete – 删除任务变量
函数原型
STATUS taskVarDelete(
int tid, /* 任务ID */
int *pVar /* 任务变量指针 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要删除变量的任务ID。 |
pVar |
int * |
要删除的任务变量的指针。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskVarDelete()函数从任务中删除一个任务变量。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
int sharedTaskVar;
void managedTask(void)
{
int myTid = taskIdSelf();
printf("任务%d启动\n", myTid);
/* 添加任务变量 */
if (taskVarAdd(myTid, &sharedTaskVar) == OK) {
printf("任务%d: 变量添加成功\n", myTid);
/* 使用变量 */
sharedTaskVar = myTid;
printf("任务%d: 变量值 = %d\n", myTid, sharedTaskVar);
/* 模拟工作 */
taskDelay(sysClkRateGet());
/* 删除变量 */
if (taskVarDelete(myTid, &sharedTaskVar) == OK) {
printf("任务%d: 变量删除成功\n", myTid);
}
}
}
void varDeleteDemo(void)
{
printf("任务变量删除演示\n");
TASK_ID tid = taskSpawn("ManagedTask", 210, 0, 1024,
(FUNCPTR)managedTask, 0,0,0,0,0,0,0,0,0,0);
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 3);
printf("任务变量删除演示结束\n");
}
26. taskVarSet – 设置任务变量值
函数原型
STATUS taskVarSet(
int tid, /* 任务ID */
int *pVar, /* 任务变量指针 */
int value /* 要设置的值 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
任务ID。 |
pVar |
int * |
任务变量指针。 |
value |
int |
要设置的值。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskVarSet()函数设置指定任务的任务变量值。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
int configParam;
void configuredTask(void)
{
int myTid = taskIdSelf();
/* 添加任务变量 */
taskVarAdd(myTid, &configParam);
printf("任务%d启动\n", myTid);
printf("初始配置值 = %d\n", configParam);
for (int i = 0; i < 3; i++) {
printf("任务%d: 使用配置值 %d\n", myTid, configParam);
taskDelay(sysClkRateGet());
}
}
void varSetDemo(void)
{
printf("任务变量设置演示\n");
TASK_ID tid = taskSpawn("ConfigTask", 220, 0, 1024,
(FUNCPTR)configuredTask, 0,0,0,0,0,0,0,0,0,0);
/* 从外部设置任务变量值 */
for (int i = 1; i <= 3; i++) {
taskDelay(sysClkRateGet());
printf("设置任务变量值为: %d\n", i * 10);
if (taskVarSet(tid, &configParam, i * 10) == OK) {
printf("值设置成功\n");
}
}
/* 等待任务完成 */
taskDelay(sysClkRateGet() * 4);
printf("任务变量设置演示结束\n");
}
27. taskVarGet – 获取任务变量值
函数原型
STATUS taskVarGet(
int tid, /* 任务ID */
int *pVar, /* 任务变量指针 */
int *pValue /* 值指针 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
任务ID。 |
pVar |
int * |
任务变量指针。 |
pValue |
int * |
指向整数的指针,用于接收变量值。 |
返回值
-
成功:返回
OK(0) -
失败:返回
ERROR(-1)
描述
taskVarGet()函数获取指定任务的任务变量值。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
int statusVar;
void monitoredTask(void)
{
int myTid = taskIdSelf();
/* 添加任务变量 */
taskVarAdd(myTid, &statusVar);
/* 设置初始状态 */
statusVar = 0; /* 0=空闲 */
for (int i = 1; i <= 5; i++) {
statusVar = i; /* 更新状态 */
printf("任务%d: 状态更新为 %d\n", myTid, statusVar);
taskDelay(sysClkRateGet());
}
statusVar = 99; /* 完成 */
printf("任务%d: 完成\n", myTid);
}
void varGetDemo(void)
{
printf("任务变量获取演示\n");
TASK_ID tid = taskSpawn("MonitoredTask", 230, 0, 1024,
(FUNCPTR)monitoredTask, 0,0,0,0,0,0,0,0,0,0);
/* 监控任务状态 */
for (int i = 0; i < 7; i++) {
int status;
if (taskVarGet(tid, &statusVar, &status) == OK) {
printf("监控: 任务状态 = %d", status);
if (status == 0) printf(" (空闲)");
else if (status == 99) printf(" (完成)");
else printf(" (工作中)");
printf("\n");
}
taskDelay(sysClkRateGet());
}
printf("任务变量获取演示结束\n");
}
28. taskErrnoGet – 获取任务错误号
函数原型
int taskErrnoGet(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要获取错误号的任务ID。如果为0,表示获取调用任务自身的错误号。 |
返回值
返回指定任务的错误号(errno)。
描述
taskErrnoGet()函数获取指定任务的错误号。每个任务都有自己的错误号副本。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
#include <errnoLib.h>
void errorDemo(void)
{
printf("错误号演示\n");
TASK_ID tid = taskSpawn("ErrorTask", 240, 0, 1024,
(FUNCPTR)taskDelay, 2, 0,0,0,0,0,0,0,0,0);
if (tid == ERROR) {
printf("创建任务失败\n");
return;
}
/* 设置一个模拟错误号 */
errnoSet(S_memLib_NOT_ENOUGH_MEMORY);
/* 获取错误号 */
int err = taskErrnoGet(0);
printf("自身任务错误号: %d\n", err);
/* 获取错误字符串 */
const char *errStr = errnoGetString(err);
printf("错误描述: %s\n", errStr);
/* 获取其他任务的错误号 */
int otherErr = taskErrnoGet(tid);
printf("其他任务错误号: %d\n", otherErr);
/* 清理 */
taskDelay(sysClkRateGet() * 3);
taskDelete(tid);
printf("错误号演示结束\n");
}
29. taskErrnoSet – 设置任务错误号
函数原型
void taskErrnoSet(
int tid, /* 任务ID */
int errno /* 错误号 */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要设置错误号的任务ID。如果为0,表示设置调用任务自身的错误号。 |
errno |
int |
要设置的错误号。 |
返回值
无。
描述
taskErrnoSet()函数设置指定任务的错误号。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
/* 自定义错误号 */
#define MY_ERROR_CUSTOM 1000
void errorSettingDemo(void)
{
printf("错误号设置演示\n");
TASK_ID tid = taskSpawn("ErrorSetTask", 250, 0, 1024,
(FUNCPTR)taskDelay, 2, 0,0,0,0,0,0,0,0,0);
if (tid == ERROR) {
printf("创建任务失败\n");
return;
}
/* 设置自定义错误号 */
printf("设置自定义错误号: %d\n", MY_ERROR_CUSTOM);
taskErrnoSet(tid, MY_ERROR_CUSTOM);
/* 验证设置 */
int err = taskErrnoGet(tid);
printf("验证: 任务错误号 = %d\n", err);
/* 设置自身错误号 */
taskErrnoSet(0, MY_ERROR_CUSTOM + 1);
int myErr = taskErrnoGet(0);
printf("自身错误号 = %d\n", myErr);
/* 清理 */
taskDelay(sysClkRateGet() * 3);
taskDelete(tid);
printf("错误号设置演示结束\n");
}
30. taskIsReady – 检查任务是否就绪
函数原型
BOOL taskIsReady(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要检查的任务ID。 |
返回值
- TRUE (1):任务处于就绪状态
- FALSE (0):任务不处于就绪状态
- ERROR:检查失败
描述
taskIsReady()函数检查指定任务是否处于就绪状态(READY)。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>
void readyCheckDemo(void)
{
printf("就绪状态检查演示\n");
TASK_ID tid = taskSpawn("ReadyTask", 100, 0, 1024,
(FUNCPTR)taskDelay, 3, 0,0,0,0,0,0,0,0,0);
if (tid == ERROR) {
printf("创建任务失败\n");
return;
}
printf("检查任务就绪状态:\n");
/* 检查就绪状态 */
BOOL isReady = taskIsReady(tid);
if (isReady == TRUE) {
printf(" 任务就绪\n");
} else if (isReady == FALSE) {
printf(" 任务非就绪\n");
} else {
printf(" 检查失败\n");
}
/* 挂起任务后检查 */
taskSuspend(tid);
isReady = taskIsReady(tid);
if (isReady == TRUE) {
printf(" 挂起后: 任务就绪(不应发生)\n");
} else if (isReady == FALSE) {
printf(" 挂起后: 任务非就绪(预期)\n");
}
/* 恢复任务 */
taskResume(tid);
/* 清理 */
taskDelay(sysClkRateGet() * 4);
taskDelete(tid);
printf("就绪状态检查演示结束\n");
}
31. taskIsPended – 检查任务是否阻塞
函数原型
BOOL taskIsPended(
int tid /* 任务ID */
);
参数说明
| 参数 | 类型 | 描述 |
|---|---|---|
tid |
int |
要检查的任务ID。 |
返回值
- TRUE (1):任务处于阻塞状态
- FALSE (0):任务不处于阻塞状态
- ERROR:检查失败
描述
taskIsPended()函数检查指定任务是否处于阻塞状态(PENDED)。
使用示例
#include <vxWorks.h>
#include <taskLib.h>
#include <semLib.h>
#include <stdio.h>
SEM_ID testSem;
void blockedTask(void)
{
printf("阻塞任务启动\n");
/* 尝试获取信号量(会阻塞) */
printf("尝试获取信号量...\n");
semTake(testSem, WAIT_FOREVER);
printf("获取信号量成功\n");
/* 释放信号量 */
semGive(testSem);
}
void pendedCheckDemo(void)
{
printf("阻塞状态检查演示\n");
/* 创建信号量(初始为空) */
testSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
TASK_ID tid = taskSpawn("BlockedTask", 100, 0, 1024,
(FUNCPTR)blockedTask, 0,0,0,0,0,0,0,0,0,0);
if (tid == ERROR) {
printf("创建任务失败\n");
semDelete(testSem);
return;
}
/* 等待任务运行到阻塞点 */
taskDelay(sysClkRateGet() / 2);
printf("检查阻塞状态:\n");
BOOL isPended = taskIsPended(tid);
if (isPended == TRUE) {
printf(" 任务阻塞(预期)\n");
} else if (isPended == FALSE) {
printf(" 任务非阻塞\n");
} else {
printf(" 检查失败\n");
}
/* 释放信号量,让任务继续 */
semGive(testSem);
/* 等待任务完成 */
taskDelay(sysClkRateGet());
/* 再次检查 */
isPended = taskIsPended(tid);
if (isPended == TRUE) {
printf(" 信号量释放后: 任务仍阻塞\n");
} else if (isPended == FALSE) {
printf(" 信号量释放后: 任务非阻塞(预期)\n");
}
/* 清理 */
taskDelay(sysClkRateGet() * 2);
taskDelete(tid);
semDelete(testSem);
printf("阻塞状态检查演示结束\n");
}
总结
本手册详细介绍了VxWorks任务管理API的31个核心函数,涵盖了任务生命周期的各个方面:
核心功能分类:
-
任务创建与初始化:
-
taskSpawn()– 创建并激活任务 -
taskInit()– 初始化任务 -
taskActivate()– 激活任务
-
-
任务控制:
-
taskDelete()– 删除任务 -
taskDeleteForce()– 强制删除任务 -
taskSuspend()/taskResume()– 挂起/恢复任务 -
taskRestart()– 重启任务 -
taskDelay()– 延迟任务
-
-
任务调度控制:
-
taskPrioritySet()/taskPriorityGet()– 优先级管理 -
taskLock()/taskUnlock()– 调度锁定 -
taskSafe()/taskUnsafe()– 删除保护
-
-
任务信息查询:
-
taskIdSelf()– 获取自身ID -
taskIdVerify()– 验证任务ID -
taskName()/taskNameToId()– 名称与ID转换 -
taskTcb()– 获取TCB地址 -
taskIdDefault()– 默认ID设置 -
taskIsReady()/taskIsPended()– 状态检查
-
-
调试与诊断:
-
taskRegsGet()/taskRegsSet()– 寄存器访问 -
taskErrnoGet()/taskErrnoSet()– 错误号管理 -
taskInfoGet()– 获取任务信息
-
-
任务变量管理:
-
taskVarAdd()/taskVarDelete()– 变量增删 -
taskVarSet()/taskVarGet()– 变量读写
-
使用建议:
- 合理规划优先级:避免优先级反转,为系统任务保留高优先级
- 适当堆栈大小:根据任务需求合理分配,定期检查堆栈使用
- 资源管理:确保任务退出时释放所有资源
- 错误处理:检查API返回值,正确处理错误情况
- 实时性考虑:关键区尽量短,避免长时间禁用调度
- 调试支持:使用有意义的任务名称,便于调试
性能考虑:
- 任务切换开销较小,但频繁切换仍影响性能
- 优先级继承可防止优先级反转
- 合理使用调度锁定,避免影响系统响应性
安全注意事项:
- 慎用强制删除,可能破坏资源管理
- 直接修改TCB和寄存器可能导致系统崩溃
- 确保任务变量正确管理,避免内存泄漏
本手册提供了完整的使用示例和注意事项,可作为VxWorks多任务编程的参考指南。在实际应用中,应根据具体需求选择合适的API,并遵循实时系统开发的最佳实践。