Skip to content

Commit

Permalink
Merge pull request #114 from Flipper-Zero/printf
Browse files Browse the repository at this point in the history
Implement transparent printf support
  • Loading branch information
Disasm authored Sep 17, 2020
2 parents 2d66f55 + 19aaf9a commit 93cee4c
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 4 deletions.
2 changes: 1 addition & 1 deletion applications/examples/uart_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 36 additions & 2 deletions core/tty_uart.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#define _GNU_SOURCE
#include <stdio.h>
#include "furi.h"
#include "main.h"

Expand All @@ -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;
}
}
1 change: 1 addition & 0 deletions target_f1/Inc/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions target_f2/Inc/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions target_lo/Inc/cmsis_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
46 changes: 45 additions & 1 deletion target_lo/Src/lo_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 93cee4c

Please sign in to comment.