c++ FreeRTOS任务无限期阻塞,无上下文切换

chhqkbe1  于 2023-03-09  发布在  其他
关注(0)|答案(1)|浏览(174)

我正在编写一个简单的FreeRTOS应用程序,在其中创建一个新任务并阻塞,直到新任务初始化为止。然而,在遇到信号量阻塞后,任务再也不会继续运行。

主.cpp

#include "thread2.hpp"
os2::thread2 th{};

extern "C" auto app_main() -> void {
    vTaskDelay(portMAX_DELAY);
};

线程2.hpp

#include <cstdio>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"

namespace os2
{

    struct comm_obj
    {
        SemaphoreHandle_t sem;
    };

    inline auto worker(void* const param) -> void
    {
        printf("Worker task before giving mux");
        fflush(stdout);

        auto& comm = *static_cast<comm_obj*>(param);

        xSemaphoreGive( comm.sem );

        printf("Worker after giving mux!\n");
        fflush(stdout);

        vTaskDelete(NULL);
    }

    struct thread2
    {

        thread2() {

            printf("init!\n");
            StaticSemaphore_t stack;

            comm_obj comm{
                .sem = xSemaphoreCreateBinaryStatic(&stack),
            };

            printf("Hello ");
            fflush(stdout);
            [[maybe_unused]] TaskHandle_t handle = xTaskCreateStaticPinnedToCore(
                &worker,
                "default",
                5*1024,
                &comm,
                10,
                stack_.data(),
                &tcb_,
                0);

            printf("World!");
            fflush(stdout);
            xSemaphoreTake( comm.sem, portMAX_DELAY );
        }

        StaticTask_t tcb_;
        std::array<StackType_t, 5*1024> stack_;
    };

}

这将只输出:

init!
Hello World!

(and然后停止,导致任务看门狗被触发)
但是worker任务从来没有被调用过,看起来程序在xSemaphoreTake( comm.sem, portMAX_DELAY );上阻塞了,但是在这种情况下,任务应该让步,新创建的任务应该开始运行(如果我的逻辑正确的话),为什么没有发生呢?

eit6fx6z

eit6fx6z1#

问题是任务调度器从来没有机会启动,因为线程对象是在调度器启动之前静态初始化的,所以当构造函数运行时,它会立即命中信号量块,之后的所有操作都不能执行,因为在这个阶段没有多线程。

相关问题