/** * @file fullDemo.cpp * @author Gustice * @brief Coherent demonstration of FreeRTOS-Abstraction in small environment * @copyright Copyright (c) 2024 */ #include "esp_log.h" #include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "sdkconfig.h" #include constexpr int StackSize = 1024; constexpr int LED = 2; #define TerminalPrint(format, ...) ESP_LOGI("main", format, __VA_ARGS__) #include "Mutex.hpp" #include "Queue.hpp" #include "Semaphore.hpp" #include "Task.hpp" #include using namespace fos; using namespace std::literals::string_view_literals; constexpr int WAIT = 1000; /// @brief Arbitrary definition for message type (to be used as queue template parameter) struct TxMsg { TxMsg(uint32_t c, std::string m) : cnt(c), message(m){}; uint32_t cnt; std::string message; }; /// @brief Global semaphore for blink tasks Semaphore blinkSem; void setupLedPin(); void toggleLedPin(); /// @brief Parameterless task entry for generation of blink signals /// @note uses global semaphore void TaskBlinkProvider() { TerminalPrint("starting blink provider task"); while (true) { Task::delayMs(WAIT); // wait blinkSem.give(); // then signal a blink event } } /// @brief Parameterless task entry for execution of blink signals /// @note uses global semaphore void TaskBlink() { TerminalPrint("starting blink execution task"); setupLedPin(); while (true) { blinkSem.take(); // wait for blink event signal toggleLedPin(); // execute blink event Task::delayMs(100); // wait toggleLedPin(); // execute blink event TerminalPrint("Blink tick"); } } /// @brief Parametrized task entry for message provider (generates message object) /// @param queue reference to appropriate queue void MessageProvider(Queue &queue) { uint32_t cnt{}; while (true) { auto e = std::make_unique(cnt++, "tick"); queue.enqueue(std::move(e)); Task::delayMs(WAIT); } } /// @brief Parametrized task entry for message consumer (sends message over UART) /// @param queue reference to appropriate queue void MessageConsumer(Queue &queue) { while (true) { auto msg = queue.dequeue(); // Wait with infinit timeout, guaranteed to succeed TerminalPrint("Message: %s %lu", msg->message.c_str(), msg->cnt); } } void setupTasks() { /// @note: All definitions as static instances to not be destructed after loosing scope static Queue txQueue(8); static Task blinkerTask(TaskBlink, "BlinkExec", StackSize); static Task blinkeProviderTask(TaskBlinkProvider, "BlinkFlags", StackSize); static TaskT &> tickerTask(MessageProvider, txQueue, "Tick", StackSize); static TaskT &> senderTask(MessageConsumer, txQueue, "Sender", StackSize); } extern "C" { // This switch allows the ROS C-implementation to find this main void app_main(void); } void app_main() { void setupTasks(); while (true) { ESP_LOGI("main", "healt tick"); vTaskDelay(1000 / portTICK_PERIOD_MS); } } void setupLedPin() { // no Buildin-led on XIAO C3 } void toggleLedPin() { // no Buildin-led on XIAO C3 }