3. 任务状态转换监控

任务说明

本案例演示如何在VxWorks中创建两个任务,通过taskStatusShow()和taskIdVerify()等API实时监控任务在不同状态(就绪、挂起、延迟)之间的转换。程序将创建一个被挂起的任务,随后将其恢复并延迟执行,在每个阶段调用taskStatusShow()输出任务状态字,以验证状态转换是否符合预期。

核心实现

/* task_monitor.c - 任务状态转换监控示例 */
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>

/* 被监控任务的入口函数 */
static void monitoredTask(void)
{
    while (1) {
        printf("monitoredTask: running...\n");
        taskDelay(sysClkRateGet() / 2);  /* 延迟500ms */
    }
}

/* 监控任务:创建并跟踪目标任务的状态变化 */
void taskMonitor(void)
{
    int tId;
    char taskName[] = "tMonitored";

    /* 1. 创建目标任务(初始状态为挂起) */
    tId = taskSpawn(taskName, 100, VX_SUPERVISOR_MODE, 0x2000,
                    (FUNCPTR)monitoredTask, 0,0,0,0,0,0,0,0,0,0);
    if (tId == ERROR) {
        printf("taskSpawn failed\n");
        return;
    }
    printf("=== 1. Task created (suspended) ===\n");
    taskStatusShow(tId, 1);   /* 显示完整状态字 */

    /* 2. 恢复任务运行 */
    if (taskResume(tId) == OK) {
        printf("\n=== 2. Task resumed (ready/running) ===\n");
        taskDelay(sysClkRateGet() / 10);   /* 等待100ms让任务运行 */
        taskStatusShow(tId, 1);
    }

    /* 3. 让目标任务进入延迟状态 */
    printf("\n=== 3. Task delaying ===\n");
    taskDelay(sysClkRateGet() / 10);       /* 等待目标任务进入taskDelay */
    taskStatusShow(tId, 1);

    /* 4. 验证任务ID合法性并删除任务 */
    if (taskIdVerify(tId) == OK) {
        printf("\n=== 4. Task ID verified, deleting ===\n");
        taskDelete(tId);
        printf("Task deleted successfully\n");
    } else {
        printf("Task ID verification failed\n");
    }
}

编译与运行

  1. 在VxWorks开发环境中创建源文件task_monitor.c,将上述代码完整粘贴。
  2. 编译生成目标文件:ccarm task_monitor.c -o task_monitor.o(或使用Workbench直接构建)。
  3. 将目标文件下载到目标机,在Shell中调用:taskMonitor()。

验证方法

程序执行后,串口终端应依次输出4个阶段的状态信息。判定通过的观察点如下:

  • 阶段1:状态字中SUSPEND位(0x10)被置位,表明任务创建后处于挂起状态。
  • 阶段2:SUSPEND位清除,出现READY或RUNNING状态,且能看到monitoredTask: running...打印。
  • 阶段3:状态字中DELAY位(0x08)被置位,表明任务已进入延迟状态。
  • 阶段4:输出Task deleted successfully,且taskIdVerify()返回OK。

若各阶段状态字与上述预期一致,则说明任务状态转换监控功能正常。

关键说明

  • taskStatusShow(tId, 1)的第二个参数为1时显示完整状态字,为0时仅显示任务名和状态缩写。
  • 状态字中各状态位定义可参考taskLib.h中的VX_*宏(如VX_SUSPEND=0x10,VX_DELAY=0x08)。
  • 本示例使用taskDelay()让监控任务主动让出CPU,确保目标任务有机会被调度执行。