2. 任务优先级抢占

任务目标

创建两个不同优先级的VxWorks任务,通过共享变量的输出顺序,验证高优先级任务能够抢占低优先级任务的CPU执行权。

核心原理

VxWorks采用基于优先级的抢占式调度。当高优先级任务就绪时,系统立即保存当前运行任务的上下文,切换到高优先级任务执行。本案例通过两个任务循环打印各自计数器,观察高优先级任务(priority=100)始终先于低优先级任务(priority=150)完成每一轮打印,从而证明抢占行为。

完整实现代码

/* task_preempt_demo.c - VxWorks任务优先级抢占验证 */
#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>

/* 共享标志:用于同步两个任务的启动 */
static volatile int startFlag = 0;

/* 低优先级任务:priority = 150 */
static void lowPriorityTask(void)
{
    int i;
    while (startFlag == 0)    /* 等待启动信号 */
        taskDelay(1);

    for (i = 0; i < 5; i++) {
        printf("[LOW ] Round %d\n", i + 1);
        taskDelay(10);        /* 主动让出CPU,给高优先级任务运行机会 */
    }
}

/* 高优先级任务:priority = 100 */
static void highPriorityTask(void)
{
    int i;
    while (startFlag == 0)
        taskDelay(1);

    for (i = 0; i < 5; i++) {
        printf("[HIGH] Round %d\n", i + 1);
        taskDelay(10);
    }
}

/* 任务创建入口 */
void taskPreemptDemo(void)
{
    int tidLow, tidHigh;

    /* 创建低优先级任务(priority=150) */
    tidLow = taskSpawn("tLow", 150, 0, 0x2000,
                       (FUNCPTR)lowPriorityTask, 0,0,0,0,0,0,0,0,0,0);
    if (tidLow == ERROR) {
        printf("Failed to spawn low priority task\n");
        return;
    }

    /* 创建高优先级任务(priority=100) */
    tidHigh = taskSpawn("tHigh", 100, 0, 0x2000,
                        (FUNCPTR)highPriorityTask, 0,0,0,0,0,0,0,0,0,0);
    if (tidHigh == ERROR) {
        printf("Failed to spawn high priority task\n");
        return;
    }

    /* 释放启动信号 */
    startFlag = 1;
}

编译与运行

  1. 在VxWorks开发环境(如Workbench)中创建C文件,将上述代码粘贴保存为task_preempt_demo.c。
  2. 将该文件添加到当前VxWorks镜像工程或可加载模块工程中。
  3. 编译生成可加载模块(.out文件)或直接编译进VxWorks镜像。
  4. 在VxWorks Shell中加载模块(若为可加载模块):
    ld < task_preempt_demo.out
  5. 调用入口函数:
    taskPreemptDemo()

验证方法与判定标准

运行后在Shell终端观察输出。由于高优先级任务(priority=100)数值更小、优先级更高,当两个任务都处于就绪态时,高优先级任务会先获得CPU。预期输出模式为:

[HIGH] Round 1
[LOW ] Round 1
[HIGH] Round 2
[LOW ] Round 2
[HIGH] Round 3
[LOW ] Round 3
[HIGH] Round 4
[LOW ] Round 4
[HIGH] Round 5
[LOW ] Round 5

通过条件:每一轮中[HIGH]均先于[LOW]打印。若出现连续两个[LOW]或[LOW]先于[HIGH]打印,则说明抢占未生效,需检查任务优先级设置或系统调度配置。

关键说明

  • 两个任务均调用taskDelay(10)主动让出CPU,使两个任务交替获得运行机会,便于观察调度顺序。
  • VxWorks中优先级数值越小,优先级越高。本案例中100高于150。
  • 若需验证抢占的即时性(非时间片轮转),可删除taskDelay,此时高优先级任务将独占CPU,低优先级任务永远无法运行——这也是抢占调度的直接体现,但不利于观察交替输出,故本案例保留taskDelay以展示抢占顺序。