我正在编写一个简单的 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 );
上阻塞,但在这种情况下,任务应该产生并且新创建的任务应该开始运行(如果我的逻辑是正确的)。为什么没有发生这种情况?
问题是任务调度程序从未有机会启动,因为线程对象是在调度程序启动之前静态初始化的。因此,当构造函数运行时,它会立即命中信号量块,之后的所有内容都无法执行,因为此阶段没有多线程。
抱歉,我必须创建一个答案,因为我无法创建评论,因为我没有 50 个声誉点...常规 SoF BS...
我也有同样的问题,你能告诉我你是如何解决的吗?