You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Twister中Zephyr任务线程与测试线程并行运行?

问题

我基于Zephyr开发了一个包含多个交互任务的应用,其中一个任务负责读写虚拟仪表与阀门。现在要为项目添加测试,验证该任务能否正常运行并正确响应。

我已在Twister中启动了该任务的线程,但它无法与测试线程并行运行。当前只能通过k_sleep()暂停测试线程,但这会导致获取任务剩余水量、虚拟仪表数值等辅助函数无法正常工作。

相关代码如下:

CMake配置:

cmake_minimum_required(VERSION 3.13.1)
set(APP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)

list(APPEND ZEPHYR_EXTRA_MODULES ${APP_ROOT}/src/drivers/meter)
list(APPEND ZEPHYR_EXTRA_MODULES ${APP_ROOT}/src/drivers/valve)

list(APPEND SYSCALL_INCLUDE_DIRS ${APP_ROOT}/include/)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(MyProject)
zephyr_include_directories(${ZEPHYR_BASE}/include/zephyr/drivers/)

# C sources
target_sources(app PRIVATE src/main.c)
target_sources(app PRIVATE ${APP_ROOT}/src/task/MterTask.c)

任务线程定义:

K_THREAD_DEFINE(metertask_id, METER_TASK_STACKSIZE, _meter_thread, NULL, NULL, NULL,
        METER_TASK_PRIORITY, K_ESSENTIAL, 0);

请问是否有办法让Twister中任务线程与测试线程并行运行?


解决方案

以下几种方案可以实现Twister测试线程与仪表任务线程的并行运行:

1. 调整线程优先级

Zephyr采用抢占式调度,若测试线程优先级高于仪表任务,会持续占用CPU导致后者无法运行:

  • 检查CONFIG_TEST_THREAD_PRIORITY(测试线程默认优先级),确保其值大于等于METER_TASK_PRIORITY的定义值。可以在prj.conf中配置:
    CONFIG_TEST_THREAD_PRIORITY=5
    
  • 也可以在测试代码中动态调整测试线程优先级:
    k_thread_priority_set(k_current_get(), METER_TASK_PRIORITY + 1);
    

2. 用同步原语替代k_sleep()

k_sleep()会强制挂起测试线程,改用信号量、事件等同步机制,既能保证线程并行,又能精准控制测试时机:

// 全局定义信号量(或静态初始化)
struct k_sem meter_op_done_sem;

// 测试初始化时初始化信号量
static void test_setup(void) {
    k_sem_init(&meter_op_done_sem, 0, 1);
}

// 仪表任务中完成读写操作后释放信号量
void _meter_thread(void *p1, void *p2, void *p3) {
    while (1) {
        // 执行仪表/阀门读写逻辑
        update_meter_and_valve();
        // 操作完成后通知测试线程
        k_sem_give(&meter_op_done_sem);
        // 任务自身的循环延迟(按需设置)
        k_msleep(100);
    }
}

// 测试线程中等待信号量,替代k_sleep()
ZTEST(meter_tests, test_meter_response) {
    // 触发仪表任务操作(若需要)
    trigger_meter_task();
    // 等待操作完成
    k_sem_take(&meter_op_done_sem, K_FOREVER);
    // 此时安全调用辅助函数验证结果
    int remaining_water = get_remaining_water();
    zassert_equal(remaining_water, EXPECTED_WATER, "剩余水量不符");
}

3. 启用必要的Zephyr配置

确保项目配置中开启多线程和抢占调度支持:

CONFIG_MULTITHREADING=y
CONFIG_SCHED_PREEMPT=y
CONFIG_TEST=y
CONFIG_TEST_RUNNER=y

4. 测试线程主动让出CPU

如果测试线程有循环检查逻辑,加入k_yield()主动释放CPU,让仪表任务获得运行机会:

ZTEST(meter_tests, test_meter_loop) {
    int target_val = 100;
    while (true) {
        int current_val = get_meter_value();
        if (current_val == target_val) {
            break;
        }
        // 主动让出CPU给其他线程
        k_yield();
    }
    zassert_true(true, "仪表数值达到目标");
}

内容的提问来源于stack exchange,提问作者obvg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:56:04