From d39d2265e35a13803a96594e6cfc7be7cc2c3cdc Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 10 Sep 2020 21:55:10 +0300 Subject: [PATCH 1/6] Implement transparent printf support --- core/tty_uart.c | 35 ++++++++++++++++++++++++++++++++-- target_f1/Inc/FreeRTOSConfig.h | 1 + target_f2/Inc/FreeRTOSConfig.h | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/core/tty_uart.c b/core/tty_uart.c index 4e10e880e20..d687b14b43c 100644 --- a/core/tty_uart.c +++ b/core/tty_uart.c @@ -1,3 +1,5 @@ +#define _GNU_SOURCE +#include #include "furi.h" #include "main.h" @@ -7,14 +9,43 @@ void handle_uart_write(const void* data, size_t size, void* ctx) { HAL_UART_Transmit(&DEBUG_UART, (uint8_t*)data, (uint16_t)size, HAL_MAX_DELAY); } +static ssize_t stdout_write(void *_cookie, const char *buf, size_t n) { + FuriRecordSubscriber *log = pvTaskGetThreadLocalStoragePointer(NULL, 0); + if (log == NULL) { + log = furi_open("tty", false, false, NULL, NULL, NULL); + vTaskSetThreadLocalStoragePointer(NULL, 0, log); + } + if (buf == 0) { + /* + * This means that we should flush internal buffers. Since we + * don't we just return. (Remember, "handle" == -1 means that all + * handles should be flushed.) + */ + return 0; + } + + furi_write(log, buf, n); + + return n; +} + bool register_tty_uart() { if(!furi_create("tty", NULL, 0)) { return false; } - + if(furi_open("tty", false, false, handle_uart_write, NULL, NULL) == NULL) { return false; } + FILE* fp = fopencookie(NULL, "w+", (cookie_io_functions_t) { + .read = NULL, + .write = stdout_write, + .seek = NULL, + .close = NULL, + }); + setvbuf(fp, NULL, _IONBF, 0); + stdout = fp; + return true; -} \ No newline at end of file +} diff --git a/target_f1/Inc/FreeRTOSConfig.h b/target_f1/Inc/FreeRTOSConfig.h index 7b29e66cea0..085eb0c7977 100644 --- a/target_f1/Inc/FreeRTOSConfig.h +++ b/target_f1/Inc/FreeRTOSConfig.h @@ -68,6 +68,7 @@ #define configQUEUE_REGISTRY_SIZE 8 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_COUNTING_SEMAPHORES 1 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 1 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 diff --git a/target_f2/Inc/FreeRTOSConfig.h b/target_f2/Inc/FreeRTOSConfig.h index 7b29e66cea0..085eb0c7977 100644 --- a/target_f2/Inc/FreeRTOSConfig.h +++ b/target_f2/Inc/FreeRTOSConfig.h @@ -68,6 +68,7 @@ #define configQUEUE_REGISTRY_SIZE 8 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_COUNTING_SEMAPHORES 1 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 1 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 From 449e905f461f75cca54b06a0c3717a5f7a7dbe35 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 10 Sep 2020 22:06:39 +0300 Subject: [PATCH 2/6] Handle furi_open() error --- core/tty_uart.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/tty_uart.c b/core/tty_uart.c index d687b14b43c..5a2b360c738 100644 --- a/core/tty_uart.c +++ b/core/tty_uart.c @@ -13,6 +13,9 @@ static ssize_t stdout_write(void *_cookie, const char *buf, size_t n) { FuriRecordSubscriber *log = pvTaskGetThreadLocalStoragePointer(NULL, 0); if (log == NULL) { log = furi_open("tty", false, false, NULL, NULL, NULL); + if (log == NULL) { + return -1; + } vTaskSetThreadLocalStoragePointer(NULL, 0, log); } if (buf == 0) { From aa859586a95c1548b406ee9f501af8c9df60e6a6 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 10 Sep 2020 22:52:58 +0300 Subject: [PATCH 3/6] Implement TLS for target_lo --- target_lo/Src/lo_os.c | 46 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/target_lo/Src/lo_os.c b/target_lo/Src/lo_os.c index 240139f03ed..14d79f0ac97 100644 --- a/target_lo/Src/lo_os.c +++ b/target_lo/Src/lo_os.c @@ -195,4 +195,48 @@ BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore) { xSemaphore->give_counter++; return pdTRUE; -} \ No newline at end of file +} + +#define TLS_ITEM_COUNT 1 +static pthread_key_t tls_keys[TLS_ITEM_COUNT]; +static pthread_once_t tls_keys_once = PTHREAD_ONCE_INIT; + +static void create_tls_keys() { + for (size_t i = 0; i < TLS_ITEM_COUNT; i++) { + pthread_key_create(&tls_keys[i], NULL); + } +} + +void* pvTaskGetThreadLocalStoragePointer( + TaskHandle_t xTaskToQuery, BaseType_t xIndex +) { + // Non-current task TLS access is not allowed + if (xTaskToQuery != NULL) { + return NULL; + } + + if (xIndex >= TLS_ITEM_COUNT) { + return NULL; + } + + pthread_once(&tls_keys_once, create_tls_keys); + + return pthread_getspecific(tls_keys[xIndex]); +} + +void vTaskSetThreadLocalStoragePointer( + TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue +) { + // Non-current task TLS access is not allowed + if (xTaskToSet != NULL) { + return; + } + + if (xIndex >= TLS_ITEM_COUNT) { + return; + } + + pthread_once(&tls_keys_once, create_tls_keys); + + pthread_setspecific(tls_keys[xIndex], pvValue); +} From d376982b4c58519963aca8fa8e4cf3edbef265aa Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 10 Sep 2020 23:35:50 +0300 Subject: [PATCH 4/6] Fix fopencookie open flags --- core/tty_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/tty_uart.c b/core/tty_uart.c index 5a2b360c738..e4e729d72a9 100644 --- a/core/tty_uart.c +++ b/core/tty_uart.c @@ -41,7 +41,7 @@ bool register_tty_uart() { return false; } - FILE* fp = fopencookie(NULL, "w+", (cookie_io_functions_t) { + FILE* fp = fopencookie(NULL, "w", (cookie_io_functions_t) { .read = NULL, .write = stdout_write, .seek = NULL, From cea7b2bde06b8dbdbe45f4a62ef11617e1a7a022 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Mon, 14 Sep 2020 21:26:36 +0300 Subject: [PATCH 5/6] Replace fuprintf with printf in the uart_write example --- applications/examples/uart_write.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/examples/uart_write.c b/applications/examples/uart_write.c index c660212394b..1025eeaaa87 100644 --- a/applications/examples/uart_write.c +++ b/applications/examples/uart_write.c @@ -19,7 +19,7 @@ void application_uart_write(void* p) { while(1) { // continously write it to UART - fuprintf(log, "counter: %d\n", counter); + printf("counter: %d\n", counter); counter++; // flash at every send From b96336fefa2c365a9bad218ee0d9c93b625bce59 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 17 Sep 2020 00:12:00 +0300 Subject: [PATCH 6/6] Add TLS method definitions to cmsis_os.h --- target_lo/Inc/cmsis_os.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target_lo/Inc/cmsis_os.h b/target_lo/Inc/cmsis_os.h index e4bc7b66115..985e0e8bf09 100644 --- a/target_lo/Inc/cmsis_os.h +++ b/target_lo/Inc/cmsis_os.h @@ -74,3 +74,6 @@ BaseType_t xQueueSend( ); BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait); + +void* pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, BaseType_t xIndex); +void vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue);