From 21bfc93676c56e2265f330170d319da2c480987d Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 9 May 2024 15:18:51 +0200 Subject: working FreeRTOS + lwIP blink/wifi connect example again --- main/init.cpp | 30 ++++++++++++++++++++++++++---- main/init.h | 35 ++++++++++++++++++++++++++++++++++- main/main.cpp | 27 ++++++++++++++++----------- 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/main/init.cpp b/main/init.cpp index 425f591..48f3774 100644 --- a/main/init.cpp +++ b/main/init.cpp @@ -1,9 +1,15 @@ #include "config.h" #include "init.h" +#include +#include +#include + #include #include +EventGroupHandle_t init_complete; + static void init_stdio() { stdio_init_all(); } @@ -20,13 +26,29 @@ static void init_wifi() { if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, CONF_NET_CONN_TIMEOUT)) panic("cyw43_arch_wifi_connect failed\n"); - // TODO: announce hostname + // TODO: announce hostname(?) } void init() { + init_complete = xEventGroupCreate(); + + // used for debug `printf` and `panic` on errors init_stdio(); - init_cyw34(); - init_wifi(); - // TODO: initialize i2c + + // defer other initialization until the task scheduler is running (important) + xTaskCreate((TaskFunction_t) [](void*) { + init_cyw34(); + init_wifi(); + // TODO: initialize i2c + + xEventGroupSetBits(init_complete, 1); + + // delete self + vTaskDelete(NULL); + }, "init", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 4, NULL); +} + +void await_init() { + xEventGroupWaitBits(init_complete, 1, pdFALSE, pdFALSE, portMAX_DELAY); } diff --git a/main/init.h b/main/init.h index 1f931dc..97b2e20 100644 --- a/main/init.h +++ b/main/init.h @@ -1,5 +1,38 @@ #pragma once -/** @brief initialize all peripherals on the pico */ +#include +#include + +/** + * @brief init function complete event group handle + * + * This is required to make sure the main task waits until initialization is + * complete. Due to the combination of FreeRTOS + lwIP, the initialization + * should be done while the task scheduler is running. Specifically the + * cyw43_arch_init functions make the pico hang indefinitely when used while + * the task scheduler is not running. + * + * @note `init_complete` only utilizes LSB, so `uxBitsToWaitFor` should always + * be set to *1* + */ +extern EventGroupHandle_t init_complete; + +/** + * @brief initialize all peripherals on the pico + * + * This function only synchronously initializes the standard input/output (used + * for `printf` and `panic`), and queues all other types of initialization in + * the `init` task using FreeRTOS. + * + * @note Tasks dependent on the wifi being initialized should use the + * `init_complete` event group to wait for initialization to complete! + */ void init(); +/** + * @brief block task until all initialization is complete + * + * utility function, see above comments + */ +void await_init(); + diff --git a/main/main.cpp b/main/main.cpp index ace9f01..c97a808 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -7,11 +7,13 @@ #include "config.h" #include "init.h" -#include -#include -#include +// #include +// #include +// #include void blink_task() { + await_init(); // `blink_task` uses GPIO + while (true) { cyw43_arch_gpio_put(LED_PIN, 0); vTaskDelay(250 / portTICK_PERIOD_MS); @@ -20,18 +22,21 @@ void blink_task() { } } +void test_task() { + int i = 0; + while (true) { + // stdio is initialized synchronously, so no `await_init` is needed + printf("hello #%d...\n", ++i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +} + int main() { init(); - for (int i = 5; i > 0; i--) { - printf("starting in %d...\n", i); - sleep_ms(1000); - } - - // this should compile but not work - lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + xTaskCreate((TaskFunction_t) test_task, "test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); - xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL); vTaskStartScheduler(); } -- cgit v1.2.3