Skip to content

Commit

Permalink
Revert "Make printf great again (flipperdevices#1438)"
Browse files Browse the repository at this point in the history
This reverts commit bc34689.
  • Loading branch information
RogueMaster committed Aug 3, 2022
1 parent b8c0b25 commit 67d2451
Show file tree
Hide file tree
Showing 20 changed files with 169 additions and 1,477 deletions.
10 changes: 5 additions & 5 deletions applications/cli/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,9 +439,9 @@ void cli_session_open(Cli* cli, void* session) {
cli->session = session;
if(cli->session != NULL) {
cli->session->init();
furi_thread_set_stdout_callback(cli->session->tx_stdout);
furi_stdglue_set_thread_stdout_callback(cli->session->tx_stdout);
} else {
furi_thread_set_stdout_callback(NULL);
furi_stdglue_set_thread_stdout_callback(NULL);
}
furi_semaphore_release(cli->idle_sem);
furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk);
Expand All @@ -455,7 +455,7 @@ void cli_session_close(Cli* cli) {
cli->session->deinit();
}
cli->session = NULL;
furi_thread_set_stdout_callback(NULL);
furi_stdglue_set_thread_stdout_callback(NULL);
furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk);
}

Expand All @@ -469,9 +469,9 @@ int32_t cli_srv(void* p) {
furi_record_create(RECORD_CLI, cli);

if(cli->session != NULL) {
furi_thread_set_stdout_callback(cli->session->tx_stdout);
furi_stdglue_set_thread_stdout_callback(cli->session->tx_stdout);
} else {
furi_thread_set_stdout_callback(NULL);
furi_stdglue_set_thread_stdout_callback(NULL);
}

if(furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) {
Expand Down
2 changes: 1 addition & 1 deletion applications/cli/cli_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct CliSession {
void (*deinit)(void);
size_t (*rx)(uint8_t* buffer, size_t size, uint32_t timeout);
void (*tx)(const uint8_t* buffer, size_t size);
void (*tx_stdout)(const char* data, size_t size);
void (*tx_stdout)(void* _cookie, const char* data, size_t size);
bool (*is_connected)(void);
};

Expand Down
3 changes: 2 additions & 1 deletion applications/cli/cli_vcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) {
#endif
}

static void cli_vcp_tx_stdout(const char* data, size_t size) {
static void cli_vcp_tx_stdout(void* _cookie, const char* data, size_t size) {
UNUSED(_cookie);
cli_vcp_tx((const uint8_t*)data, size);
}

Expand Down
9 changes: 4 additions & 5 deletions applications/desktop/views/desktop_view_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ void desktop_debug_render(Canvas* canvas, void* model) {
canvas_draw_str(canvas, 5, 50 + STATUS_BAR_Y_SHIFT, buffer);

} else {
char buffer[64];
Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN);
DolphinStats stats = dolphin_stats(dolphin);
furi_record_close(RECORD_DOLPHIN);
Expand All @@ -85,20 +86,18 @@ void desktop_debug_render(Canvas* canvas, void* model) {
uint32_t remaining = dolphin_state_xp_to_levelup(m->icounter);

canvas_set_font(canvas, FontSecondary);
snprintf(buffer, sizeof(buffer), "Icounter: %ld Butthurt %ld", m->icounter, m->butthurt);
snprintf(buffer, 64, "Icounter: %ld Butthurt %ld", m->icounter, m->butthurt);
canvas_draw_str(canvas, 5, 19 + STATUS_BAR_Y_SHIFT, buffer);

snprintf(
buffer,
sizeof(buffer),
64,
"Level: %ld To level up: %ld",
current_lvl,
(remaining == (uint32_t)(-1) ? remaining : 0));
canvas_draw_str(canvas, 5, 29 + STATUS_BAR_Y_SHIFT, buffer);

// even if timestamp is uint64_t, it's safe to cast it to uint32_t, because furi_hal_rtc_datetime_to_timestamp only returns uint32_t
snprintf(buffer, sizeof(buffer), "%ld", (uint32_t)m->timestamp);

snprintf(buffer, 64, "%s", asctime(localtime((const time_t*)&m->timestamp)));
canvas_draw_str(canvas, 5, 39 + STATUS_BAR_Y_SHIFT, buffer);
canvas_draw_str(canvas, 0, 49 + STATUS_BAR_Y_SHIFT, "[< >] icounter value [ok] save");
}
Expand Down
8 changes: 4 additions & 4 deletions applications/infrared/infrared_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static void signal_received_callback(void* context, InfraredWorkerSignal* receiv

if(infrared_worker_signal_is_decoded(received_signal)) {
const InfraredMessage* message = infrared_worker_get_decoded_signal(received_signal);
buf_cnt = snprintf(
buf_cnt = sniprintf(
buf,
sizeof(buf),
"%s, A:0x%0*lX, C:0x%0*lX%s\r\n",
Expand All @@ -43,13 +43,13 @@ static void signal_received_callback(void* context, InfraredWorkerSignal* receiv
size_t timings_cnt;
infrared_worker_get_raw_signal(received_signal, &timings, &timings_cnt);

buf_cnt = snprintf(buf, sizeof(buf), "RAW, %d samples:\r\n", timings_cnt);
buf_cnt = sniprintf(buf, sizeof(buf), "RAW, %d samples:\r\n", timings_cnt);
cli_write(cli, (uint8_t*)buf, buf_cnt);
for(size_t i = 0; i < timings_cnt; ++i) {
buf_cnt = snprintf(buf, sizeof(buf), "%lu ", timings[i]);
buf_cnt = sniprintf(buf, sizeof(buf), "%lu ", timings[i]);
cli_write(cli, (uint8_t*)buf, buf_cnt);
}
buf_cnt = snprintf(buf, sizeof(buf), "\r\n");
buf_cnt = sniprintf(buf, sizeof(buf), "\r\n");
cli_write(cli, (uint8_t*)buf, buf_cnt);
}
}
Expand Down
2 changes: 1 addition & 1 deletion applications/rpc/rpc_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ static void rpc_system_storage_md5sum_process(const PB_Main* request, void* cont
(void)md5sum_size;
furi_assert(hash_size <= ((md5sum_size - 1) / 2));
for(uint8_t i = 0; i < hash_size; i++) {
md5sum += snprintf(md5sum, md5sum_size, "%02x", hash[i]);
md5sum += sprintf(md5sum, "%02x", hash[i]);
}

free(hash);
Expand Down
9 changes: 3 additions & 6 deletions applications/subghz/scenes/subghz_scene_receiver_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ static void subghz_scene_receiver_config_set_frequency(VariableItem* item) {

if(subghz->txrx->hopper_state == SubGhzHopperStateOFF) {
char text_buf[10] = {0};
snprintf(
sprintf(
text_buf,
sizeof(text_buf),
"%lu.%02lu",
subghz_setting_get_frequency(subghz->setting, index) / 1000000,
(subghz_setting_get_frequency(subghz->setting, index) % 1000000) / 10000);
Expand Down Expand Up @@ -146,9 +145,8 @@ static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item)
variable_item_set_current_value_text(item, hopping_text[index]);
if(hopping_value[index] == SubGhzHopperStateOFF) {
char text_buf[10] = {0};
snprintf(
sprintf(
text_buf,
sizeof(text_buf),
"%lu.%02lu",
subghz_setting_get_default_frequency(subghz->setting) / 1000000,
(subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000);
Expand Down Expand Up @@ -201,9 +199,8 @@ void subghz_scene_receiver_config_on_enter(void* context) {
subghz->scene_manager, SubGhzSceneReceiverConfig, (uint32_t)item);
variable_item_set_current_value_index(item, value_index);
char text_buf[10] = {0};
snprintf(
sprintf(
text_buf,
sizeof(text_buf),
"%lu.%02lu",
subghz_setting_get_frequency(subghz->setting, value_index) / 1000000,
(subghz_setting_get_frequency(subghz->setting, value_index) % 1000000) / 10000);
Expand Down
15 changes: 7 additions & 8 deletions applications/unit_tests/rpc/rpc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,8 @@ static void clean_directory(Storage* fs_api, const char* clean_dir) {
FileInfo fileinfo;
char* name = malloc(MAX_NAME_LENGTH + 1);
while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
size_t size = strlen(clean_dir) + strlen(name) + 1 + 1;
char* fullname = malloc(size);
snprintf(fullname, size, "%s/%s", clean_dir, name);
char* fullname = malloc(strlen(clean_dir) + strlen(name) + 1 + 1);
sprintf(fullname, "%s/%s", clean_dir, name);
if(fileinfo.flags & FSF_DIRECTORY) {
clean_directory(fs_api, fullname);
}
Expand Down Expand Up @@ -1227,7 +1226,7 @@ MU_TEST(test_storage_mkdir) {
mu_check(test_is_exists(TEST_DIR "dir2"));
}

static void test_storage_calculate_md5sum(const char* path, char* md5sum, size_t md5sum_size) {
static void test_storage_calculate_md5sum(const char* path, char* md5sum) {
Storage* api = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(api);

Expand All @@ -1248,7 +1247,7 @@ static void test_storage_calculate_md5sum(const char* path, char* md5sum, size_t
free(md5_ctx);

for(uint8_t i = 0; i < hash_size; i++) {
md5sum += snprintf(md5sum, md5sum_size, "%02x", hash[i]);
md5sum += sprintf(md5sum, "%02x", hash[i]);
}

free(hash);
Expand Down Expand Up @@ -1300,9 +1299,9 @@ MU_TEST(test_storage_md5sum) {
test_create_file(TEST_DIR "file1.txt", 0);
test_create_file(TEST_DIR "file2.txt", 1);
test_create_file(TEST_DIR "file3.txt", 512);
test_storage_calculate_md5sum(TEST_DIR "file1.txt", md5sum1, MD5SUM_SIZE * 2 + 1);
test_storage_calculate_md5sum(TEST_DIR "file2.txt", md5sum2, MD5SUM_SIZE * 2 + 1);
test_storage_calculate_md5sum(TEST_DIR "file3.txt", md5sum3, MD5SUM_SIZE * 2 + 1);
test_storage_calculate_md5sum(TEST_DIR "file1.txt", md5sum1);
test_storage_calculate_md5sum(TEST_DIR "file2.txt", md5sum2);
test_storage_calculate_md5sum(TEST_DIR "file3.txt", md5sum3);

test_storage_md5sum_run(TEST_DIR "file1.txt", ++command_id, md5sum1, PB_CommandStatus_OK);
test_storage_md5sum_run(TEST_DIR "file1.txt", ++command_id, md5sum1, PB_CommandStatus_OK);
Expand Down
3 changes: 2 additions & 1 deletion firmware.scons
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ fwenv.AppendUnique(
"-Wl,--wrap,_free_r",
"-Wl,--wrap,_calloc_r",
"-Wl,--wrap,_realloc_r",
"-u",
"_printf_float",
"-n",
"-Xlinker",
"-Map=${TARGET}.map",
Expand All @@ -199,7 +201,6 @@ fwelf = fwenv["FW_ELF"] = fwenv.Program(
"${FIRMWARE_BUILD_CFG}",
sources,
LIBS=[
"print",
"flipper${TARGET_HW}",
"furi",
"freertos",
Expand Down
102 changes: 102 additions & 0 deletions furi/core/stdglue.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "stdglue.h"
#include "check.h"
#include "memmgr.h"

#include <FreeRTOS.h>
#include <task.h>

#include <furi_hal.h>
#include <m-dict.h>

DICT_DEF2(
FuriStdglueCallbackDict,
uint32_t,
M_DEFAULT_OPLIST,
FuriStdglueWriteCallback,
M_PTR_OPLIST)

typedef struct {
FuriMutex* mutex;
FuriStdglueCallbackDict_t thread_outputs;
} FuriStdglue;

static FuriStdglue* furi_stdglue = NULL;

static ssize_t stdout_write(void* _cookie, const char* data, size_t size) {
furi_assert(furi_stdglue);
bool consumed = false;
FuriThreadId task_id = furi_thread_get_current_id();
if(xTaskGetSchedulerState() == taskSCHEDULER_RUNNING && task_id &&
furi_mutex_acquire(furi_stdglue->mutex, FuriWaitForever) == FuriStatusOk) {
// We are in the thread context
// Handle thread callbacks
FuriStdglueWriteCallback* callback_ptr =
FuriStdglueCallbackDict_get(furi_stdglue->thread_outputs, (uint32_t)task_id);
if(callback_ptr) {
(*callback_ptr)(_cookie, data, size);
consumed = true;
}
furi_check(furi_mutex_release(furi_stdglue->mutex) == FuriStatusOk);
}
// Flush
if(data == 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;
}
// Debug uart
if(!consumed) furi_hal_console_tx((const uint8_t*)data, size);
// All data consumed
return size;
}

void furi_stdglue_init() {
furi_stdglue = malloc(sizeof(FuriStdglue));
// Init outputs structures
furi_stdglue->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
furi_check(furi_stdglue->mutex);
FuriStdglueCallbackDict_init(furi_stdglue->thread_outputs);
// Prepare and set stdout descriptor
FILE* fp = fopencookie(
NULL,
"w",
(cookie_io_functions_t){
.read = NULL,
.write = stdout_write,
.seek = NULL,
.close = NULL,
});
setvbuf(fp, NULL, _IOLBF, 0);
stdout = fp;
}

bool furi_stdglue_set_thread_stdout_callback(FuriStdglueWriteCallback callback) {
furi_assert(furi_stdglue);
FuriThreadId task_id = furi_thread_get_current_id();
if(task_id) {
furi_check(furi_mutex_acquire(furi_stdglue->mutex, FuriWaitForever) == FuriStatusOk);
if(callback) {
FuriStdglueCallbackDict_set_at(
furi_stdglue->thread_outputs, (uint32_t)task_id, callback);
} else {
FuriStdglueCallbackDict_erase(furi_stdglue->thread_outputs, (uint32_t)task_id);
}
furi_check(furi_mutex_release(furi_stdglue->mutex) == FuriStatusOk);
return true;
} else {
return false;
}
}

void __malloc_lock(struct _reent* REENT) {
UNUSED(REENT);
vTaskSuspendAll();
}

void __malloc_unlock(struct _reent* REENT) {
UNUSED(REENT);
xTaskResumeAll();
}
36 changes: 36 additions & 0 deletions furi/core/stdglue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* @file stdglue.h
* Furi: stdlibc glue
*/

#pragma once

#include <stdbool.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

/** Write callback
* @param _cookie pointer to cookie (see stdio gnu extension)
* @param data pointer to data
* @param size data size @warnign your handler must consume everything
*/
typedef void (*FuriStdglueWriteCallback)(void* _cookie, const char* data, size_t size);

/** Initialized std library glue code */
void furi_stdglue_init();

/** Set STDOUT callback for your thread
*
* @param callback callback or NULL to clear
*
* @return true on success, otherwise fail
* @warning function is thread aware, use this API from the same thread
*/
bool furi_stdglue_set_thread_stdout_callback(FuriStdglueWriteCallback callback);

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit 67d2451

Please sign in to comment.