Skip to content

Commit

Permalink
Make printf great again (#1438)
Browse files Browse the repository at this point in the history
* Printf lib: wrap *printf* functions
* Printf lib, FW: drop sprintf. Dolphin: dump timestamp as is, wo asctime.
* FW: remove sniprintf, wrap assert functions
* Printf lib: wrap putc, puts, putchar
* Printf: a working but not thread-safe concept.
* Poorly wrap fflush
* stdglue: buffers
* Core: thread local buffers
* Core: move stdglue to thread api, add ability to get FuriThread instance of current thread.
* RPC tests: replace sprintf with snprintf
* Applications: use new stdout api
* Printf lib: wrap more printf-like and stdout functions
* Documentation
* Apps: snprintf size fixes

Co-authored-by: あく <[email protected]>
  • Loading branch information
DrZlo13 and skotopes authored Aug 3, 2022
1 parent eed4296 commit bc34689
Show file tree
Hide file tree
Showing 22 changed files with 1,484 additions and 175 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_stdglue_set_thread_stdout_callback(cli->session->tx_stdout);
furi_thread_set_stdout_callback(cli->session->tx_stdout);
} else {
furi_stdglue_set_thread_stdout_callback(NULL);
furi_thread_set_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_stdglue_set_thread_stdout_callback(NULL);
furi_thread_set_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_stdglue_set_thread_stdout_callback(cli->session->tx_stdout);
furi_thread_set_stdout_callback(cli->session->tx_stdout);
} else {
furi_stdglue_set_thread_stdout_callback(NULL);
furi_thread_set_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 @@ -25,7 +25,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)(void* _cookie, const char* data, size_t size);
void (*tx_stdout)(const char* data, size_t size);
bool (*is_connected)(void);
};

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

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

Expand Down
10 changes: 5 additions & 5 deletions applications/debug_tools/keypad_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ static void keypad_test_render_callback(Canvas* canvas, void* ctx) {
canvas_clear(canvas);
char strings[5][20];

sprintf(strings[0], "Ok: %d", state->ok);
sprintf(strings[1], "L: %d", state->left);
sprintf(strings[2], "R: %d", state->right);
sprintf(strings[3], "U: %d", state->up);
sprintf(strings[4], "D: %d", state->down);
snprintf(strings[0], 20, "Ok: %d", state->ok);
snprintf(strings[1], 20, "L: %d", state->left);
snprintf(strings[2], 20, "R: %d", state->right);
snprintf(strings[3], 20, "U: %d", state->up);
snprintf(strings[4], 20, "D: %d", state->down);

canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 0, 10, "Keypad test");
Expand Down
9 changes: 5 additions & 4 deletions applications/desktop/views/desktop_view_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ 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 @@ -87,18 +86,20 @@ 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, 64, "Icounter: %ld Butthurt %ld", m->icounter, m->butthurt);
snprintf(buffer, sizeof(buffer), "Icounter: %ld Butthurt %ld", m->icounter, m->butthurt);
canvas_draw_str(canvas, 5, 19 + STATUS_BAR_Y_SHIFT, buffer);

snprintf(
buffer,
64,
sizeof(buffer),
"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);

snprintf(buffer, 64, "%s", asctime(localtime((const time_t*)&m->timestamp)));
// 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);

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 = sniprintf(
buf_cnt = snprintf(
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 = sniprintf(buf, sizeof(buf), "RAW, %d samples:\r\n", timings_cnt);
buf_cnt = snprintf(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 = sniprintf(buf, sizeof(buf), "%lu ", timings[i]);
buf_cnt = snprintf(buf, sizeof(buf), "%lu ", timings[i]);
cli_write(cli, (uint8_t*)buf, buf_cnt);
}
buf_cnt = sniprintf(buf, sizeof(buf), "\r\n");
buf_cnt = snprintf(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 += sprintf(md5sum, "%02x", hash[i]);
md5sum += snprintf(md5sum, md5sum_size, "%02x", hash[i]);
}

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

if(subghz->txrx->hopper_state == SubGhzHopperStateOFF) {
char text_buf[10] = {0};
sprintf(
snprintf(
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 @@ -106,8 +107,9 @@ 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};
sprintf(
snprintf(
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 @@ -160,8 +162,9 @@ 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};
sprintf(
snprintf(
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: 8 additions & 7 deletions applications/unit_tests/rpc/rpc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,9 @@ 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)) {
char* fullname = malloc(strlen(clean_dir) + strlen(name) + 1 + 1);
sprintf(fullname, "%s/%s", clean_dir, name);
size_t size = strlen(clean_dir) + strlen(name) + 1 + 1;
char* fullname = malloc(size);
snprintf(fullname, size, "%s/%s", clean_dir, name);
if(fileinfo.flags & FSF_DIRECTORY) {
clean_directory(fs_api, fullname);
}
Expand Down Expand Up @@ -1226,7 +1227,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) {
static void test_storage_calculate_md5sum(const char* path, char* md5sum, size_t md5sum_size) {
Storage* api = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(api);

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

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

free(hash);
Expand Down Expand Up @@ -1299,9 +1300,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);
test_storage_calculate_md5sum(TEST_DIR "file2.txt", md5sum2);
test_storage_calculate_md5sum(TEST_DIR "file3.txt", md5sum3);
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_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: 1 addition & 2 deletions firmware.scons
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,6 @@ fwenv.AppendUnique(
"-Wl,--wrap,_free_r",
"-Wl,--wrap,_calloc_r",
"-Wl,--wrap,_realloc_r",
"-u",
"_printf_float",
"-n",
"-Xlinker",
"-Map=${TARGET}.map",
Expand All @@ -181,6 +179,7 @@ fwelf = fwenv["FW_ELF"] = fwenv.Program(
"${FIRMWARE_BUILD_CFG}",
sources,
LIBS=[
"print",
"flipper${TARGET_HW}",
"furi",
"freertos",
Expand Down
102 changes: 0 additions & 102 deletions furi/core/stdglue.c

This file was deleted.

36 changes: 0 additions & 36 deletions furi/core/stdglue.h

This file was deleted.

Loading

0 comments on commit bc34689

Please sign in to comment.