Reputation: 4848
I'm writing a simple FreeRTOS app in which I create a new task and block until the new task has been initialized. However, the task never proceeds to run after hitting the semaphore block. Check this out:
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_;
};
}
This will just output:
init!
Hello World!
(and then stall which causes the task watchdog to be triggered)
But the worker task is never called. It seems that the program is blocking on xSemaphoreTake( comm.sem, portMAX_DELAY );
but in this case the task should yield and the newly created task should start to run (if my logic is correct). Why is that not happening?
Upvotes: 0
Views: 228
Reputation: 4848
The problem was that the task scheduler never had a chance to start as the thread object is statically initialized which happens before the scheduler is started. So when the constructor is run it immediately hits the semaphore block and everything after that can't ever be executed because there is no multithreading at this stage.
Upvotes: 1