Merge pull request #114 from Flipper-Zero/printf

Implement transparent printf support
This commit is contained in:
Vadim Kaushan 2020-09-17 11:33:43 +03:00 committed by GitHub
commit 93cee4c37c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 4 deletions

View File

@ -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

View File

@ -1,3 +1,5 @@
#define _GNU_SOURCE
#include <stdio.h>
#include "furi.h"
#include "main.h"
@ -7,14 +9,46 @@ 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);
if (log == NULL) {
return -1;
}
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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -195,4 +195,48 @@ BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore) {
xSemaphore->give_counter++;
return pdTRUE;
}
}
#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);
}