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

问题描述 投票:0回答:2

我正在编写一个简单的 FreeRTOS 应用程序,在其中创建一个新任务并阻塞,直到新任务初始化为止。但是,任务在到达信号量块后永远不会继续运行。看看这个:

main.cpp

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

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

thread2.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!

(然后停止,导致任务看门狗被触发)

但是工作任务永远不会被调用。看起来程序在

xSemaphoreTake( comm.sem, portMAX_DELAY );
上阻塞,但在这种情况下,任务应该产生并且新创建的任务应该开始运行(如果我的逻辑是正确的)。为什么没有发生这种情况?

c++ task semaphore freertos
2个回答
1
投票

问题是任务调度程序从未有机会启动,因为线程对象是在调度程序启动之前静态初始化的。因此,当构造函数运行时,它会立即命中信号量块,之后的所有内容都无法执行,因为此阶段没有多线程。


0
投票

抱歉,我必须创建一个答案,因为我无法创建评论,因为我没有 50 个声誉点...常规 SoF BS...

我也有同样的问题,你能告诉我你是如何解决的吗?

© www.soinside.com 2019 - 2024. All rights reserved.