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, ...)
arg1arg10 int 传递给入口函数的参数,最多10个。

返回值

  • 成功:返回新创建任务的ID(TASK_ID类型)
  • 失败:返回ERROR(-1)

描述

taskSpawn()是VxWorks中最常用的任务创建函数。它一次性完成以下操作:

  1. 分配内存用于任务控制块(TCB)和堆栈
  2. 初始化TCB,设置任务名称、优先级、选项等属性
  3. 将任务置于就绪状态(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);
}

注意事项

  1. 任务名称不要求全局唯一,多个任务可以使用相同名称
  2. 堆栈大小应根据任务实际需求合理设置,过小可能导致栈溢出
  3. 如果任务需要浮点运算,必须设置VX_FP_TASK选项
  4. 创建任务失败通常是因为内存不足

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 任务入口函数指针。
arg1arg10 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);
}

注意事项

  1. 调用者必须确保TCB和堆栈内存正确对齐
  2. 堆栈内存应足够大,避免溢出
  3. 初始化后必须调用taskActivate()才能运行任务
  4. 内存管理由调用者负责,包括分配和释放

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");
}

注意事项

  1. 删除正在使用关键资源的任务可能导致系统不稳定
  2. 建议使用taskSafe()/taskUnsafe()保护关键任务
  3. 任务删除后,其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");
}

注意事项

  1. 强制删除可能破坏系统稳定性
  2. 仅在紧急情况下使用
  3. 删除后无法恢复任务状态

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");
}

注意事项

  1. 延迟时间不精确,受系统调度影响
  2. 参数为0时用于主动让出CPU
  3. 延迟期间任务不消耗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, &currentPriority) == 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, &regs) == 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, &regs) == 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个核心函数,涵盖了任务生命周期的各个方面:

核心功能分类:

  1. 任务创建与初始化

    • taskSpawn() – 创建并激活任务
    • taskInit() – 初始化任务
    • taskActivate() – 激活任务
  2. 任务控制

    • taskDelete() – 删除任务
    • taskDeleteForce() – 强制删除任务
    • taskSuspend()/taskResume() – 挂起/恢复任务
    • taskRestart() – 重启任务
    • taskDelay() – 延迟任务
  3. 任务调度控制

    • taskPrioritySet()/taskPriorityGet() – 优先级管理
    • taskLock()/taskUnlock() – 调度锁定
    • taskSafe()/taskUnsafe() – 删除保护
  4. 任务信息查询

    • taskIdSelf() – 获取自身ID
    • taskIdVerify() – 验证任务ID
    • taskName()/taskNameToId() – 名称与ID转换
    • taskTcb() – 获取TCB地址
    • taskIdDefault() – 默认ID设置
    • taskIsReady()/taskIsPended() – 状态检查
  5. 调试与诊断

    • taskRegsGet()/taskRegsSet() – 寄存器访问
    • taskErrnoGet()/taskErrnoSet() – 错误号管理
    • taskInfoGet() – 获取任务信息
  6. 任务变量管理

    • taskVarAdd()/taskVarDelete() – 变量增删
    • taskVarSet()/taskVarGet() – 变量读写

使用建议:

  1. 合理规划优先级:避免优先级反转,为系统任务保留高优先级
  2. 适当堆栈大小:根据任务需求合理分配,定期检查堆栈使用
  3. 资源管理:确保任务退出时释放所有资源
  4. 错误处理:检查API返回值,正确处理错误情况
  5. 实时性考虑:关键区尽量短,避免长时间禁用调度
  6. 调试支持:使用有意义的任务名称,便于调试

性能考虑:

  1. 任务切换开销较小,但频繁切换仍影响性能
  2. 优先级继承可防止优先级反转
  3. 合理使用调度锁定,避免影响系统响应性

安全注意事项:

  1. 慎用强制删除,可能破坏资源管理
  2. 直接修改TCB和寄存器可能导致系统崩溃
  3. 确保任务变量正确管理,避免内存泄漏

本手册提供了完整的使用示例和注意事项,可作为VxWorks多任务编程的参考指南。在实际应用中,应根据具体需求选择合适的API,并遵循实时系统开发的最佳实践。

© 版权声明

相关文章