[FL-781] FURI, CLI, stdlib: stdout hooks, integration between subsystems, uniform printf usage (#311)

* FURI stdglue: stdout hooks, local and global, ISR safe printf. Uniform newlines for terminal/debug output. Power: prevent sleep while core 2 has not started.
* Furi record, stdglue: check mutex allocation
* remove unused test
* Furi stdglue: buferized output, dynamically allocated state. Furi record: dynamically allocated state. Input dump: proper line ending. Hal VCP: dynamically allocated state.
* Interrupt manager: explicitly init list.
* Makefile: cleanup rules, fix broken dfu upload. F4: add compiler stack protection options.
* BLE: call debug uart callback on transmission complete
* FreeRTOS: add configUSE_NEWLIB_REENTRANT
* API HAL Timebase: fix issue with idle thread stack corruption caused by systick interrupt. BT: cleanup debug info output. FreeRTOS: disable reentry for newlib.
* F4: update stack protection CFLAGS to match used compiller
* F4: disable compiller stack protection because of incompatibility with current compiller
* Makefile: return openocd logs to gdb
* BLE: fixed pin, moar power, ble trace info.
* Prevent sleep when connection is active
* Makefile: return serial port to upload rule, add workaround for mac os
* Furi: prevent usage of stack for cmsis functions.
* F4: add missing includes, add debugger breakpoints
* Applications: per app stack size.
* Furi: honor kernel state in stdglue
* FreeRTOS: remove unused hooks
* Cleanup and format sources

Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
This commit is contained in:
あく
2021-01-29 03:09:33 +03:00
committed by GitHub
parent fd5f694758
commit 584c0962d8
52 changed files with 517 additions and 389 deletions

View File

@@ -60,7 +60,7 @@ static void handle_menu(void* _ctx) {
ctx->state->app_thread_attr.cb_mem = NULL;
ctx->state->app_thread_attr.cb_size = 0;
ctx->state->app_thread_attr.stack_mem = NULL;
ctx->state->app_thread_attr.stack_size = 1024;
ctx->state->app_thread_attr.stack_size = ctx->app->stack_size;
ctx->state->app_thread_attr.priority = osPriorityNormal;
ctx->state->app_thread_attr.tz_module = 0;
ctx->state->app_thread_attr.reserved = 0;
@@ -72,7 +72,7 @@ static void handle_cli(string_t args, void* _ctx) {
if(ctx->app->app == NULL) return;
cli_print("Starting furi application\r\n");
printf("Starting furi application\r\n");
ctx->state->current_app = ctx->app;
ctx->state->app_thread_attr.name = ctx->app->name;
@@ -80,13 +80,13 @@ static void handle_cli(string_t args, void* _ctx) {
ctx->state->app_thread_attr.cb_mem = NULL;
ctx->state->app_thread_attr.cb_size = 0;
ctx->state->app_thread_attr.stack_mem = NULL;
ctx->state->app_thread_attr.stack_size = 1024;
ctx->state->app_thread_attr.stack_size = ctx->app->stack_size;
ctx->state->app_thread_attr.priority = osPriorityNormal;
ctx->state->app_thread_attr.tz_module = 0;
ctx->state->app_thread_attr.reserved = 0;
ctx->state->app_thread_id = osThreadNew(ctx->app->app, NULL, &ctx->state->app_thread_attr);
cli_print("Press any key to kill application");
printf("Press any key to kill application");
char c;
cli_read(&c, 1);
@@ -184,7 +184,7 @@ void app_loader(void* p) {
menu_item_add(menu, menu_plugins);
});
printf("[app loader] start\n");
printf("[app loader] start\r\n");
osThreadSuspend(self_id);
}

View File

@@ -38,114 +38,129 @@ void sd_filesystem(void* p);
const FuriApplication FLIPPER_SERVICES[] = {
#ifdef APP_DISPLAY
{.app = display_u8g2, .name = "display_u8g2", .icon = A_Plugins_14},
{.app = display_u8g2, .name = "display_u8g2", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_CLI
{.app = cli_task, .name = "cli_task", .icon = A_Plugins_14},
{.app = cli_task, .name = "cli_task", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_EXAMPLE_BLINK
{.app = application_blink, .name = "blink", .icon = A_Plugins_14},
{.app = application_blink, .name = "blink", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_INPUT
{.app = input_task, .name = "input_task", .icon = A_Plugins_14},
{.app = input_task, .name = "input_task", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_EXAMPLE_INPUT_DUMP
{.app = application_input_dump, .name = "input dump", .icon = A_Plugins_14},
{.app = application_input_dump, .name = "input dump", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_GUI
{.app = backlight_control, .name = "backlight_control", .icon = A_Plugins_14},
{.app = gui_task, .name = "gui_task", .icon = A_Plugins_14},
{.app = backlight_control,
.name = "backlight_control",
.stack_size = 1024,
.icon = A_Plugins_14},
{.app = gui_task, .name = "gui_task", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_MENU
{.app = menu_task, .name = "menu_task", .icon = A_Plugins_14},
{.app = app_loader, .name = "app_loader", .icon = A_Plugins_14},
{.app = menu_task, .name = "menu_task", .stack_size = 1024, .icon = A_Plugins_14},
{.app = app_loader, .name = "app_loader", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_SD_FILESYSTEM
{.app = sd_filesystem, .name = "sd_filesystem", .icon = A_Plugins_14},
{.app = sd_filesystem, .name = "sd_filesystem", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_DOLPHIN
{.app = dolphin_task, .name = "dolphin_task", .icon = A_Plugins_14},
{.app = dolphin_task, .name = "dolphin_task", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_POWER
{.app = power_task, .name = "power_task", .icon = A_Plugins_14},
{.app = power_task, .name = "power_task", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_BT
{.app = bt_task, .name = "bt_task", .icon = A_Plugins_14},
{.app = bt_task, .name = "bt_task", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_CC1101
{.app = cc1101_workaround, .name = "cc1101 workaround", .icon = A_Plugins_14},
{.app = cc1101_workaround,
.name = "cc1101 workaround",
.stack_size = 1024,
.icon = A_Plugins_14},
#endif
#ifdef APP_LF_RFID
{.app = lf_rfid_workaround, .name = "lf rfid workaround", .icon = A_Plugins_14},
{.app = lf_rfid_workaround,
.name = "lf rfid workaround",
.stack_size = 1024,
.icon = A_Plugins_14},
#endif
#ifdef APP_IRDA
{.app = irda, .name = "irda", .icon = A_Plugins_14},
{.app = irda, .name = "irda", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_NFC
{.app = nfc_task, .name = "nfc_task", .icon = A_Plugins_14},
{.app = nfc_task, .name = "nfc_task", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_TEST
{.app = flipper_test_app, .name = "test app", .icon = A_Plugins_14},
{.app = flipper_test_app, .name = "test app", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_EXAMPLE_IPC
{.app = application_ipc_display, .name = "ipc display", .icon = A_Plugins_14},
{.app = application_ipc_widget, .name = "ipc widget", .icon = A_Plugins_14},
{.app = application_ipc_display,
.name = "ipc display",
.stack_size = 1024,
.icon = A_Plugins_14},
{.app = application_ipc_widget, .name = "ipc widget", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_EXAMPLE_QRCODE
{.app = u8g2_qrcode, .name = "u8g2_qrcode", .icon = A_Plugins_14},
{.app = u8g2_qrcode, .name = "u8g2_qrcode", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_EXAMPLE_FATFS
{.app = fatfs_list, .name = "fatfs_list", .icon = A_Plugins_14},
{.app = fatfs_list, .name = "fatfs_list", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_EXAMPLE_DISPLAY
{.app = u8g2_example, .name = "u8g2_example", .icon = A_Plugins_14},
{.app = u8g2_example, .name = "u8g2_example", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_SPEAKER_DEMO
{.app = coreglitch_demo_0, .name = "coreglitch_demo_0", .icon = A_Plugins_14},
{.app = coreglitch_demo_0,
.name = "coreglitch_demo_0",
.stack_size = 1024,
.icon = A_Plugins_14},
#endif
#ifdef APP_SD_TEST
{.app = sd_card_test, .name = "sd_card_test", .icon = A_Plugins_14},
{.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = A_Plugins_14},
#endif
#ifdef APP_MUSIC_PLAYER
{.app = music_player, .name = "music player", .icon = A_Plugins_14},
{.app = music_player, .name = "music player", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_IBUTTON
{.app = app_ibutton, .name = "ibutton", .icon = A_Plugins_14},
{.app = app_ibutton, .name = "ibutton", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_GPIO_DEMO
{.app = app_gpio_test, .name = "gpio test", .icon = A_Plugins_14},
{.app = app_gpio_test, .name = "gpio test", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef APP_FLOOPPER_BLOOPPER
{.app = floopper_bloopper, .name = "Floopper Bloopper", .icon = A_Games_14},
{.app = floopper_bloopper, .name = "Floopper Bloopper", .stack_size = 1024, .icon = A_Games_14},
#endif
#ifdef APP_SDNFC
{.app = sdnfc, .name = "sdnfc", .icon = A_Plugins_14},
{.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = A_Plugins_14},
#endif
};
@@ -156,23 +171,23 @@ size_t FLIPPER_SERVICES_size() {
// Main menu APP
const FuriApplication FLIPPER_APPS[] = {
#ifdef BUILD_CC1101
{.app = cc1101_workaround, .name = "Sub-1 GHz", .icon = A_Sub1ghz_14},
{.app = cc1101_workaround, .name = "Sub-1 GHz", .stack_size = 1024, .icon = A_Sub1ghz_14},
#endif
#ifdef BUILD_LF_RFID
{.app = lf_rfid_workaround, .name = "125 kHz RFID", .icon = A_125khz_14},
{.app = lf_rfid_workaround, .name = "125 kHz RFID", .stack_size = 1024, .icon = A_125khz_14},
#endif
#ifdef BUILD_IRDA
{.app = irda, .name = "Infrared", .icon = A_Infrared_14},
{.app = irda, .name = "Infrared", .stack_size = 1024, .icon = A_Infrared_14},
#endif
#ifdef BUILD_IBUTTON
{.app = app_ibutton, .name = "iButton", .icon = A_iButton_14},
{.app = app_ibutton, .name = "iButton", .stack_size = 1024, .icon = A_iButton_14},
#endif
#ifdef BUILD_GPIO_DEMO
{.app = app_gpio_test, .name = "GPIO", .icon = A_GPIO_14},
{.app = app_gpio_test, .name = "GPIO", .stack_size = 1024, .icon = A_GPIO_14},
#endif
};
@@ -183,35 +198,41 @@ size_t FLIPPER_APPS_size() {
// Plugin menu
const FuriApplication FLIPPER_PLUGINS[] = {
#ifdef BUILD_EXAMPLE_BLINK
{.app = application_blink, .name = "blink", .icon = A_Plugins_14},
{.app = application_blink, .name = "blink", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef BUILD_EXAMPLE_INPUT_DUMP
{.app = application_input_dump, .name = "input dump", .icon = A_Plugins_14},
{.app = application_input_dump, .name = "input dump", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef BUILD_SPEAKER_DEMO
{.app = coreglitch_demo_0, .name = "coreglitch_demo_0", .icon = A_Plugins_14},
{.app = coreglitch_demo_0,
.name = "coreglitch_demo_0",
.stack_size = 1024,
.icon = A_Plugins_14},
#endif
#ifdef BUILD_SD_TEST
{.app = sd_card_test, .name = "sd_card_test", .icon = A_Plugins_14},
{.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = A_Plugins_14},
#endif
#ifdef BUILD_VIBRO_DEMO
{.app = application_vibro, .name = "application_vibro", .icon = A_Plugins_14},
{.app = application_vibro,
.name = "application_vibro",
.stack_size = 1024,
.icon = A_Plugins_14},
#endif
#ifdef BUILD_MUSIC_PLAYER
{.app = music_player, .name = "music player", .icon = A_Plugins_14},
{.app = music_player, .name = "music player", .stack_size = 1024, .icon = A_Plugins_14},
#endif
#ifdef BUILD_FLOOPPER_BLOOPPER
{.app = floopper_bloopper, .name = "Floopper Bloopper", .icon = A_Games_14},
{.app = floopper_bloopper, .name = "Floopper Bloopper", .stack_size = 1024, .icon = A_Games_14},
#endif
#ifdef BUILD_SDNFC
{.app = sdnfc, .name = "sdnfc", .icon = A_Plugins_14},
{.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = A_Plugins_14},
#endif
};

View File

@@ -8,6 +8,7 @@ typedef void (*FlipperApplication)(void*);
typedef struct {
const FlipperApplication app;
const char* name;
const size_t stack_size;
const IconName icon;
} FuriApplication;

View File

@@ -33,7 +33,7 @@ void bt_cli_info(string_t args, void* context) {
string_t buffer;
string_init(buffer);
api_hal_bt_dump_state(buffer);
cli_print(string_get_cstr(buffer));
printf(string_get_cstr(buffer));
string_clear(buffer);
}

View File

@@ -3,8 +3,6 @@
#include <gui/gui.h>
#include <input/input.h>
extern "C" void cli_print(const char* str);
#define RSSI_DELAY 5000 //rssi delay in micro second
#define CHAN_SPA 0.05 // channel spacing
@@ -81,9 +79,9 @@ int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) {
/*
char buf[256];
sprintf(buf, "status: %d -> %d, rssi: %d\n", rx_status, cc1101->SpiReadStatus(CC1101_MARCSTATE), rssi_dBm);
cli_print(buf);
printf(buf);
sprintf(buf, "begin: %d, end: %d\n", begin_size, end_size);
cli_print(buf);
printf(buf);
*/
// uint8_t rx_data[64];
@@ -101,7 +99,7 @@ int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) {
}
printf(" ");
}
printf("\n");
printf("\r\n");
*
for(uint8_t i = 0; i < fifo_length; i++) {
@@ -111,7 +109,7 @@ int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) {
}
}
} else {
cli_print("fifo size over\n");
printf("fifo size over\r\n");
}
*/
@@ -158,12 +156,12 @@ void flp_config(CC1101* cc1101) {
// bandwidth 50-100 kHz
if(!cc1101->setRxBandwidth(75.0)) {
printf("wrong rx bw\n");
printf("wrong rx bw\r\n");
}
// datarate ~30 kbps
if(!cc1101->setBitRate(100.)) {
printf("wrong bitrate\n");
printf("wrong bitrate\r\n");
}
// mod
@@ -361,7 +359,7 @@ extern "C" void cc1101_workaround(void* p) {
ValueMutex state_mutex;
if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
printf("[cc1101] cannot create mutex\n");
printf("[cc1101] cannot create mutex\r\n");
furiac_exit(NULL);
}
@@ -373,7 +371,7 @@ extern "C" void cc1101_workaround(void* p) {
// Open GUI and register widget
Gui* gui = (Gui*)furi_record_open("gui");
if(gui == NULL) {
printf("[cc1101] gui is not available\n");
printf("[cc1101] gui is not available\r\n");
furiac_exit(NULL);
}
gui_add_widget(gui, widget, GuiLayerFullscreen);
@@ -381,7 +379,7 @@ extern "C" void cc1101_workaround(void* p) {
gpio_init(&debug_0, GpioModeOutputPushPull);
gpio_write((GpioPin*)&debug_0, false);
printf("[cc1101] creating device\n");
printf("[cc1101] creating device\r\n");
GpioPin cs_pin = {CC1101_CS_GPIO_Port, CC1101_CS_Pin};
gpio_init(&cc1101_g0_gpio, GpioModeInput);
@@ -389,13 +387,13 @@ extern "C" void cc1101_workaround(void* p) {
// TODO open record
GpioPin* cs_pin_record = &cs_pin;
CC1101 cc1101(cs_pin_record);
printf("[cc1101] init device\n");
printf("[cc1101] init device\r\n");
uint8_t address = cc1101.Init();
if(address > 0) {
printf("[cc1101] init done: %d\n", address);
printf("[cc1101] init done: %d\r\n", address);
} else {
printf("[cc1101] init fail\n");
printf("[cc1101] init fail\r\n");
furiac_exit(NULL);
}
@@ -406,7 +404,7 @@ extern "C" void cc1101_workaround(void* p) {
// setup_freq(&cc1101, &FREQ_LIST[4]);
// enable_cc1101_irq();
printf("init ok\n");
printf("init ok\r\n");
// TODO open record
GpioPin* led_record = (GpioPin*)&led_gpio[1];
@@ -428,12 +426,12 @@ extern "C" void cc1101_workaround(void* p) {
if(event_status == osOK) {
if(event.type == EventTypeKey) {
if(event.value.input.state && event.value.input.input == InputBack) {
printf("[cc1101] bye!\n");
cli_print("[cc1101] bye!\n");
printf("[cc1101] bye!\r\n");
cc1101.SpiStrobe(CC1101_SIDLE);
cc1101.SpiStrobe(CC1101_SPWD);
cli_print("[cc1101] go to power down\n");
printf("[cc1101] go to power down\r\n");
// TODO remove all widgets create by app
widget_enabled_set(widget, false);

View File

@@ -227,14 +227,14 @@ bool CC1101::SpiSetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb
****************************************************************/
uint8_t CC1101::Init(void) {
#ifdef CC1101_DEBUG
printf("Init SPI...\n");
printf("Init SPI...\r\n");
#endif
SpiInit(); //spi initialization
gpio_write(ss_pin, true);
// gpio_write(SCK_PIN, true);
// gpio_write(MOSI_PIN, false);
#ifdef CC1101_DEBUG
printf("Reset CC1101...\n");
printf("Reset CC1101...\r\n");
#endif
Reset(); // CC1101 reset
@@ -256,7 +256,7 @@ uint8_t CC1101::Init(void) {
// RegConfigSettings(); //CC1101 register config
#ifdef CC1101_DEBUG
printf("Done!\n");
printf("Done!\r\n");
#endif
return version;
@@ -308,7 +308,7 @@ void CC1101::SetMod(uint8_t mode) {
}
}
printf("\n");
printf("\r\n");
#endif
}
/****************************************************************
@@ -394,7 +394,7 @@ void CC1101::SetReceive(void) {
SpiStrobe(CC1101_SRX);
while(SpiReadStatus(CC1101_MARCSTATE) ^ CC1101_STATUS_RX) {
// delay(1);
// printf("wait status\n");
// printf("wait status\r\n");
}
}
/****************************************************************

View File

@@ -27,32 +27,42 @@ void cli_putc(char c) {
api_hal_vcp_tx((uint8_t*)&c, 1);
}
char cli_getc(Cli* cli) {
furi_assert(cli);
char c;
if(api_hal_vcp_rx((uint8_t*)&c, 1) == 0) {
cli_reset_state(cli);
}
return c;
}
void cli_stdout_callback(void* _cookie, const char* data, size_t size) {
api_hal_vcp_tx((const uint8_t*)data, size);
}
void cli_read(char* buffer, size_t size) {
api_hal_vcp_rx((uint8_t*)buffer, size);
}
void cli_print(const char* str) {
api_hal_vcp_tx((uint8_t*)str, strlen(str));
}
void cli_print_version() {
cli_print("Build date:" BUILD_DATE ". "
"Git Commit:" GIT_COMMIT ". "
"Git Branch:" GIT_BRANCH ". "
"Commit Number:" GIT_BRANCH_NUM ".");
printf("Build date:" BUILD_DATE ". "
"Git Commit:" GIT_COMMIT ". "
"Git Branch:" GIT_BRANCH ". "
"Commit Number:" GIT_BRANCH_NUM ".");
}
void cli_motd() {
cli_print("Flipper cli.\r\n");
printf("Flipper cli.\r\n");
cli_print_version();
}
void cli_nl() {
cli_print("\r\n");
printf("\r\n");
}
void cli_prompt() {
cli_print("\r\n>: ");
printf("\r\n>: ");
fflush(stdout);
}
void cli_backspace(Cli* cli) {
@@ -100,8 +110,8 @@ void cli_enter(Cli* cli) {
cli_prompt();
} else {
cli_nl();
cli_print("Command not found: ");
cli_print(string_get_cstr(command));
printf("Command not found: ");
printf(string_get_cstr(command));
cli_prompt();
cli_putc(CliSymbolAsciiBell);
}
@@ -112,14 +122,9 @@ void cli_enter(Cli* cli) {
}
void cli_process_input(Cli* cli) {
char c;
char c = cli_getc(cli);
size_t r;
r = api_hal_vcp_rx((uint8_t*)&c, 1);
if(r == 0) {
cli_reset_state(cli);
}
if(c == CliSymbolAsciiTab) {
cli_putc(CliSymbolAsciiBell);
} else if(c == CliSymbolAsciiSOH) {
@@ -175,6 +180,7 @@ void cli_task(void* p) {
furi_record_create("cli", cli);
furi_stdglue_set_thread_stdout_callback(cli_stdout_callback);
while(1) {
cli_process_input(cli);
}

View File

@@ -34,12 +34,6 @@ void cli_add_command(Cli* cli, const char* name, CliCallback callback, void* con
*/
void cli_read(char* buffer, size_t size);
/* Print to terminal
* Do it only from inside of callback.
* @param buffer - pointer to null terminated string to print.
*/
void cli_print(const char* buffer);
/* New line
* Send new ine sequence
*/

View File

@@ -5,22 +5,22 @@
void cli_command_help(string_t args, void* context) {
(void)args;
Cli* cli = context;
cli_print("Commands we have:");
printf("Commands we have:");
furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK);
CliCommandDict_it_t it;
for(CliCommandDict_it(it, cli->commands); !CliCommandDict_end_p(it); CliCommandDict_next(it)) {
CliCommandDict_itref_t* ref = CliCommandDict_ref(it);
cli_print(" ");
cli_print(string_get_cstr(ref->key));
printf(" ");
printf(string_get_cstr(ref->key));
};
furi_check(osMutexRelease(cli->mutex) == osOK);
if(string_size(args) > 0) {
cli_nl();
cli_print("Also I have no clue what '");
cli_print(string_get_cstr(args));
cli_print("' is.");
printf("Also I have no clue what '");
printf(string_get_cstr(args));
printf("' is.");
}
}
@@ -43,7 +43,7 @@ void cli_command_uuid(string_t args, void* context) {
uint8_t uid_byte = uid[i];
string_cat_printf(byte_str, "%02X", uid_byte);
}
cli_print(string_get_cstr(byte_str));
printf(string_get_cstr(byte_str));
}
void cli_command_date(string_t args, void* context) {
@@ -61,11 +61,19 @@ void cli_command_date(string_t args, void* context) {
string_cat_printf(datetime_str, "%.2d:%.2d:%.2d ", time.Hours, time.Minutes, time.Seconds);
string_cat_printf(datetime_str, "%.2d-%.2d-%.2d", date.Month, date.Date, 2000 + date.Year);
cli_print(string_get_cstr(datetime_str));
printf(string_get_cstr(datetime_str));
string_clear(datetime_str);
}
void cli_command_log(string_t args, void* context) {
Cli* cli = context;
furi_stdglue_set_global_stdout_callback(cli_stdout_callback);
printf("Press any key to stop...\r\n");
cli_getc(cli);
furi_stdglue_set_global_stdout_callback(NULL);
}
void cli_commands_init(Cli* cli) {
cli_add_command(cli, "help", cli_command_help, cli);
cli_add_command(cli, "?", cli_command_help, cli);
@@ -73,4 +81,5 @@ void cli_commands_init(Cli* cli) {
cli_add_command(cli, "!", cli_command_version, cli);
cli_add_command(cli, "uid", cli_command_uuid, cli);
cli_add_command(cli, "date", cli_command_date, cli);
cli_add_command(cli, "log", cli_command_log, cli);
}

View File

@@ -38,4 +38,6 @@ Cli* cli_alloc();
void cli_free(Cli* cli);
void cli_reset_state(Cli* cli);
void cli_print_version();
char cli_getc(Cli* cli);
void cli_putc(char c);
void cli_stdout_callback(void* _cookie, const char* data, size_t size);

View File

@@ -4,7 +4,7 @@
extern TIM_HandleTypeDef SPEAKER_TIM;
void coreglitch_demo_0(void* p) {
printf("coreglitch demo!\n");
printf("coreglitch demo!\r\n");
float notes[] = {
0.0,

View File

@@ -11,13 +11,13 @@ static void state_cb(const void* value, void* ctx) {
InputDump dump = {.packed = 0};
dump.state = *(InputState*)value;
printf("state: %02x\n", dump.packed);
printf("state: %02x\r\n", dump.packed);
}
static void event_cb(const void* value, void* ctx) {
const InputEvent* event = value;
printf("event: %02x %s\n", event->input, event->state ? "pressed" : "released");
printf("event: %02x %s\r\n", event->input, event->state ? "pressed" : "released");
}
void application_input_dump(void* p) {
@@ -28,7 +28,7 @@ void application_input_dump(void* p) {
PubSub* event_record = furi_record_open("input_events");
subscribe_pubsub(event_record, event_cb, NULL);
printf("Example app [input dump]\n");
printf("Example app [input dump]\r\n");
for(;;) {
delay(100);

View File

@@ -37,7 +37,7 @@ void u8g2_qrcode(void* p) {
qrcode_initText(&qrcode, qrcodeBytes, qr_version, qr_error_correction, "HELLO FLIPPER");
if(fb_record == NULL) {
printf("[widget] cannot create fb record\n");
printf("[widget] cannot create fb record\r\n");
furiac_exit(NULL);
}

View File

@@ -66,7 +66,7 @@ void app_gpio_test(void* p) {
ValueMutex state_mutex;
if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
printf("[gpio-tester] cannot create mutex\n");
printf("[gpio-tester] cannot create mutex\r\n");
furiac_exit(NULL);
}
@@ -94,7 +94,7 @@ void app_gpio_test(void* p) {
if(event_status == osOK) {
if(event.type == EventTypeKey) {
if(event.value.input.state && event.value.input.input == InputBack) {
printf("[gpio-tester] bye!\n");
printf("[gpio-tester] bye!\r\n");
// TODO remove all widgets create by app
widget_enabled_set(widget, false);
furiac_exit(NULL);

View File

@@ -76,7 +76,7 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_
case U8X8_MSG_BYTE_INIT:
#ifdef DEBUG
printf("[u8g2] init\n");
printf("[u8g2] init\r\n");
#endif
// TODO change it to FuriRecord pin
@@ -85,7 +85,7 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_
case U8X8_MSG_BYTE_START_TRANSFER:
#ifdef DEBUG
printf("[u8g2] start\n");
printf("[u8g2] start\r\n");
#endif
// TODO: SPI manager
@@ -98,7 +98,7 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_
case U8X8_MSG_BYTE_END_TRANSFER:
#ifdef DEBUG
printf("[u8g2] end\n");
printf("[u8g2] end\r\n");
#endif
asm("nop");

View File

@@ -25,15 +25,15 @@ void input_task(void* p) {
uint8_t debounce_counters[INPUT_COUNT];
if(!init_managed(&input_state_record, &input_state, sizeof(input_state))) {
printf("[input_task] cannot initialize ValueManager for input_state\n");
printf("[input_task] cannot initialize ValueManager for input_state\r\n");
furiac_exit(NULL);
}
if(!init_pubsub(&input_events_record)) {
printf("[input_task] cannot initialize PubSub for input_events\n");
printf("[input_task] cannot initialize PubSub for input_events\r\n");
furiac_exit(NULL);
}
if(!init_event(&event)) {
printf("[input_task] cannot initialize Event\n");
printf("[input_task] cannot initialize Event\r\n");
furiac_exit(NULL);
}

View File

@@ -263,7 +263,7 @@ void irda(void* p) {
ValueMutex state_mutex;
if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
printf("cannot create mutex\n");
printf("cannot create mutex\r\n");
furiac_exit(NULL);
}

View File

@@ -48,7 +48,7 @@ void prepare_data(uint32_t ID, uint32_t VENDOR, uint8_t* data) {
for(uint8_t i = 0; i < 64; i++) {
printf("%d ", data[i]);
}
printf("\n");
printf("\r\n");
*/
}

View File

@@ -106,7 +106,7 @@ static bool even_check(uint8_t* buf) {
buf[line * (ROW_SIZE + 1) + ROW_SIZE]);
return false;
}
printf("\n");
printf("\r\n");
}
for(uint8_t col = 0; col < ROW_SIZE; col++) {
@@ -138,7 +138,7 @@ static void extract_data(uint8_t* buf, uint8_t* customer, uint32_t* em_data) {
offset++;
}
}
printf("\n");
printf("\r\n");
*customer = data;
@@ -155,7 +155,7 @@ static void extract_data(uint8_t* buf, uint8_t* customer, uint32_t* em_data) {
offset++;
}
}
printf("\n");
printf("\r\n");
*em_data = data;
}
@@ -194,7 +194,7 @@ void lf_rfid_workaround(void* p) {
ValueMutex state_mutex;
if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
printf("cannot create mutex\n");
printf("cannot create mutex\r\n");
furiac_exit(NULL);
}

View File

@@ -33,7 +33,7 @@ ValueMutex* menu_init() {
ValueMutex* menu_mutex = furi_alloc(sizeof(ValueMutex));
if(menu_mutex == NULL || !init_mutex(menu_mutex, menu, sizeof(Menu))) {
printf("[menu_task] cannot create menu mutex\n");
printf("[menu_task] cannot create menu mutex\r\n");
furiac_exit(NULL);
}

View File

@@ -369,7 +369,7 @@ void music_player(void* p) {
ValueMutex state_mutex;
if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
printf("cannot create mutex\n");
printf("cannot create mutex\r\n");
furiac_exit(NULL);
}
@@ -393,7 +393,7 @@ void music_player(void* p) {
osThreadId_t player = osThreadNew(music_player_thread, &context, &player_attr);
if(player == NULL) {
printf("cannot create player thread\n");
printf("cannot create player thread\r\n");
furiac_exit(NULL);
}

View File

@@ -142,19 +142,19 @@ void power_free(Power* power) {
}
void power_cli_poweroff(string_t args, void* context) {
cli_print("Poweroff in 3 seconds");
printf("Poweroff in 3 seconds");
osDelay(3000);
api_hal_power_off();
}
void power_cli_reset(string_t args, void* context) {
cli_print("NVIC System Reset in 3 seconds");
printf("NVIC System Reset in 3 seconds");
osDelay(3000);
NVIC_SystemReset();
}
void power_cli_dfu(string_t args, void* context) {
cli_print("NVIC System Reset to DFU mode in 3 seconds");
printf("NVIC System Reset to DFU mode in 3 seconds");
api_hal_boot_set_mode(ApiHalBootModeDFU);
osDelay(3000);
NVIC_SystemReset();
@@ -164,7 +164,7 @@ void power_cli_test(string_t args, void* context) {
string_t buffer;
string_init(buffer);
api_hal_power_dump_state(buffer);
cli_print(string_get_cstr(buffer));
printf(string_get_cstr(buffer));
string_clear(buffer);
}

View File

@@ -610,99 +610,99 @@ void SdTest::cli_read_benchmark(string_t args, void* _ctx) {
const uint8_t str_buffer_size = 64;
char str_buffer[str_buffer_size];
cli_print("preparing benchmark data\r\n");
printf("preparing benchmark data\r\n");
bool data_prepared = _this->prepare_benchmark_data();
if(data_prepared) {
cli_print("benchmark data prepared\r\n");
printf("benchmark data prepared\r\n");
} else {
cli_print("error: cannot allocate buffer for benchmark data\r\n");
printf("error: cannot allocate buffer for benchmark data\r\n");
}
// prepare data for read test
cli_print("prepare data for read speed test, procedure can be lengthy, please wait\r\n");
printf("prepare data for read speed test, procedure can be lengthy, please wait\r\n");
if(!_this->fs_api->file.open(&file, "read.test", FSAM_WRITE, FSOM_OPEN_ALWAYS)) {
cli_print("error: cannot open file in prepare read\r\n");
printf("error: cannot open file in prepare read\r\n");
}
for(size_t i = 0; i < benchmark_data_size / b4096_size; i++) {
bytes_written = _this->fs_api->file.write(&file, benchmark_data, b4096_size);
if(bytes_written != b4096_size || file.error_id != FSE_OK) {
cli_print("error: cannot write to file in prepare read\r\n");
printf("error: cannot write to file in prepare read\r\n");
}
}
if(!_this->fs_api->file.close(&file)) {
cli_print("error: cannot close file in prepare read\r\n");
printf("error: cannot close file in prepare read\r\n");
}
// test start
cli_print("read speed test, procedure can be lengthy, please wait\r\n");
printf("read speed test, procedure can be lengthy, please wait\r\n");
// open file
if(!_this->fs_api->file.open(&file, "read.test", FSAM_READ, FSOM_OPEN_EXISTING)) {
cli_print("error: cannot open file in read benchmark\r\n");
printf("error: cannot open file in read benchmark\r\n");
}
// 1b test
benchmark_bps =
_this->read_benchmark_internal(b1_size, benchmark_data_size / b1_size, &file, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 1-byte read test\r\n");
printf("error: in 1-byte read test\r\n");
} else {
snprintf(str_buffer, str_buffer_size, "1-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// 8b test
benchmark_bps =
_this->read_benchmark_internal(b8_size, benchmark_data_size / b8_size, &file, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 8-byte read test\r\n");
printf("error: in 8-byte read test\r\n");
} else {
snprintf(str_buffer, str_buffer_size, "8-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// 32b test
benchmark_bps =
_this->read_benchmark_internal(b32_size, benchmark_data_size / b32_size, &file, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 32-byte read test\r\n");
printf("error: in 32-byte read test\r\n");
} else {
snprintf(str_buffer, str_buffer_size, "32-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// 256b test
benchmark_bps =
_this->read_benchmark_internal(b256_size, benchmark_data_size / b256_size, &file, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 256-byte read test\r\n");
printf("error: in 256-byte read test\r\n");
} else {
snprintf(str_buffer, str_buffer_size, "256-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// 4096b test
benchmark_bps =
_this->read_benchmark_internal(b4096_size, benchmark_data_size / b4096_size, &file, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 4096-byte read test\r\n");
printf("error: in 4096-byte read test\r\n");
} else {
snprintf(
str_buffer, str_buffer_size, "4096-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// close file
if(!_this->fs_api->file.close(&file)) {
cli_print("error: cannot close file\r\n");
printf("error: cannot close file\r\n");
}
_this->free_benchmark_data();
cli_print("test completed\r\n");
printf("test completed\r\n");
}
void SdTest::cli_write_benchmark(string_t args, void* _ctx) {
@@ -721,68 +721,68 @@ void SdTest::cli_write_benchmark(string_t args, void* _ctx) {
const uint8_t str_buffer_size = 64;
char str_buffer[str_buffer_size];
cli_print("preparing benchmark data\r\n");
printf("preparing benchmark data\r\n");
bool data_prepared = _this->prepare_benchmark_data();
if(data_prepared) {
cli_print("benchmark data prepared\r\n");
printf("benchmark data prepared\r\n");
} else {
cli_print("error: cannot allocate buffer for benchmark data\r\n");
printf("error: cannot allocate buffer for benchmark data\r\n");
}
cli_print("write speed test, procedure can be lengthy, please wait\r\n");
printf("write speed test, procedure can be lengthy, please wait\r\n");
// 1b test
benchmark_bps = _this->write_benchmark_internal(b1_size, benchmark_data_size / b1_size, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 1-byte write test\r\n");
printf("error: in 1-byte write test\r\n");
} else {
snprintf(str_buffer, str_buffer_size, "1-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// 8b test
benchmark_bps = _this->write_benchmark_internal(b8_size, benchmark_data_size / b8_size, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 8-byte write test\r\n");
printf("error: in 8-byte write test\r\n");
} else {
snprintf(str_buffer, str_buffer_size, "8-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// 32b test
benchmark_bps =
_this->write_benchmark_internal(b32_size, benchmark_data_size / b32_size, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 32-byte write test\r\n");
printf("error: in 32-byte write test\r\n");
} else {
snprintf(str_buffer, str_buffer_size, "32-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// 256b test
benchmark_bps =
_this->write_benchmark_internal(b256_size, benchmark_data_size / b256_size, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 256-byte write test\r\n");
printf("error: in 256-byte write test\r\n");
} else {
snprintf(str_buffer, str_buffer_size, "256-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
// 4096b test
benchmark_bps =
_this->write_benchmark_internal(b4096_size, benchmark_data_size / b4096_size, true);
if(benchmark_bps == BENCHMARK_ERROR) {
cli_print("error: in 4096-byte write test\r\n");
printf("error: in 4096-byte write test\r\n");
} else {
snprintf(
str_buffer, str_buffer_size, "4096-byte: %lu bytes per second\r\n", benchmark_bps);
cli_print(str_buffer);
printf(str_buffer);
}
_this->free_benchmark_data();
cli_print("test completed\r\n");
printf("test completed\r\n");
}
// wait for button press
@@ -873,7 +873,7 @@ template <class T> void SdTest::set_error(std::initializer_list<T> list) {
template <class T> void SdTest::set_text(std::initializer_list<T> list) {
uint8_t line_position = 0;
acquire_state();
printf("------------------------\n");
printf("------------------------\r\n");
// set line strings from args
for(auto element : list) {
@@ -886,10 +886,10 @@ template <class T> void SdTest::set_text(std::initializer_list<T> list) {
// set empty lines
for(; line_position < state.lines_count; line_position++) {
state.line[line_position] = "";
printf("\n");
printf("\r\n");
}
printf("------------------------\n");
printf("------------------------\r\n");
release_state();
update_gui();
}

View File

@@ -174,7 +174,7 @@ void app_sd_info_callback(void* context) {
if(str_buffer[i] == NULL) {
memory_error = true;
} else {
snprintf(str_buffer[i], str_buffer_size, "");
str_buffer[i][0] = 0;
}
}
@@ -365,25 +365,25 @@ void app_sd_eject_callback(void* context) {
static void cli_sd_status(string_t args, void* _ctx) {
SdApp* sd_app = (SdApp*)_ctx;
cli_print("SD status: ");
cli_print(fs_error_get_internal_desc(sd_app->info.status));
cli_print("\r\n");
printf("SD status: ");
printf(fs_error_get_internal_desc(sd_app->info.status));
printf("\r\n");
}
static void cli_sd_format(string_t args, void* _ctx) {
SdApp* sd_app = (SdApp*)_ctx;
cli_print("formatting SD card, please wait\r\n");
printf("formatting SD card, please wait\r\n");
// format card
app_sd_format_internal(sd_app);
if(sd_app->info.status != SD_OK) {
cli_print("SD card format error: ");
cli_print(fs_error_get_internal_desc(sd_app->info.status));
cli_print("\r\n");
printf("SD card format error: ");
printf(fs_error_get_internal_desc(sd_app->info.status));
printf("\r\n");
} else {
cli_print("SD card formatted\r\n");
printf("SD card formatted\r\n");
}
}
@@ -437,42 +437,42 @@ static void cli_sd_info(string_t args, void* _ctx) {
}
snprintf(str_buffer, str_buffer_size, "Label: %s\r\n", volume_label);
cli_print(str_buffer);
printf(str_buffer);
snprintf(str_buffer, str_buffer_size, "%s, S/N: %lu\r\n", fs_type, serial_num);
cli_print(str_buffer);
printf(str_buffer);
snprintf(str_buffer, str_buffer_size, "Cluster: %d sectors\r\n", fs->csize);
cli_print(str_buffer);
printf(str_buffer);
snprintf(str_buffer, str_buffer_size, "Sector: %d bytes\r\n", sector_size);
cli_print(str_buffer);
printf(str_buffer);
snprintf(
str_buffer, str_buffer_size, "%lu KB total\r\n", total_sectors / 1024 * sector_size);
cli_print(str_buffer);
printf(str_buffer);
snprintf(
str_buffer, str_buffer_size, "%lu KB free\r\n", free_sectors / 1024 * sector_size);
cli_print(str_buffer);
printf(str_buffer);
} else {
cli_print("SD status error: ");
printf("SD status error: ");
snprintf(
str_buffer,
str_buffer_size,
"%s\r\n",
fs_error_get_internal_desc(_fs_status(&sd_app->info)));
cli_print(str_buffer);
printf(str_buffer);
cli_print("Label error: ");
printf("Label error: ");
snprintf(
str_buffer, str_buffer_size, "%s\r\n", fs_error_get_internal_desc(get_label_result));
cli_print(str_buffer);
printf(str_buffer);
cli_print("Get free error: ");
printf("Get free error: ");
snprintf(
str_buffer, str_buffer_size, "%s\r\n", fs_error_get_internal_desc(get_free_result));
cli_print(str_buffer);
printf(str_buffer);
}
}
@@ -511,7 +511,7 @@ void sd_filesystem(void* p) {
with_value_mutex(
menu_vm, (Menu * menu) { menu_item_add(menu, menu_item); });
printf("[sd_filesystem] start\n");
printf("[sd_filesystem] start\r\n");
// add api record
furi_record_create("sdcard", fs_api);
@@ -522,7 +522,7 @@ void sd_filesystem(void* p) {
while(true) {
if(sd_was_present) {
if(hal_gpio_read_sd_detect()) {
printf("[sd_filesystem] card detected\n");
printf("[sd_filesystem] card detected\r\n");
uint8_t bsp_result = BSP_SD_Init();
@@ -530,13 +530,13 @@ void sd_filesystem(void* p) {
sd_app->info.status = SD_LOW_LEVEL_ERR;
printf("[sd_filesystem] bsp error: %x\n", bsp_result);
} else {
printf("[sd_filesystem] bsp ok\n");
printf("[sd_filesystem] bsp ok\r\n");
sd_app->info.status = f_mount(&sd_app->info.fat_fs, sd_app->info.path, 1);
if(sd_app->info.status != SD_OK) {
printf("[sd_filesystem] mount error: %d\n", sd_app->info.status);
} else {
printf("[sd_filesystem] mount ok\n");
printf("[sd_filesystem] mount ok\r\n");
}
}
@@ -545,7 +545,7 @@ void sd_filesystem(void* p) {
}
} else {
if(!hal_gpio_read_sd_detect()) {
printf("[sd_filesystem] card removed\n");
printf("[sd_filesystem] card removed\r\n");
widget_enabled_set(sd_app->icon.widget, false);
app_sd_unmount_card(sd_app);

View File

@@ -44,7 +44,7 @@ void template_app(void* p) {
/* init state here */
ValueMutex state_mutex;
if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
printf("cannot create mutex\n");
printf("cannot create mutex\r\n");
furiac_exit(NULL);
}
@@ -56,7 +56,7 @@ void template_app(void* p) {
// Open GUI and register widget
Gui* gui = furi_record_open("gui");
if(gui == NULL) {
printf("gui is not available\n");
printf("gui is not available\r\n");
furiac_exit(NULL);
}
gui_add_widget(gui, widget, /* specify UI layer */);

View File

@@ -59,7 +59,7 @@ typedef struct {
void furi_concurent_app(void* p) {
ValueMutex* mutex = (ValueMutex*)p;
if(mutex == NULL) {
printf("cannot open mutex\n");
printf("cannot open mutex\r\n");
furiac_exit(NULL);
}
@@ -67,7 +67,7 @@ void furi_concurent_app(void* p) {
ConcurrentValue* value = (ConcurrentValue*)acquire_mutex_block(mutex);
if(value == NULL) {
printf("cannot take record\n");
printf("cannot take record\r\n");
release_mutex(mutex, value);
furiac_exit(NULL);
}
@@ -103,7 +103,7 @@ void test_furi_concurrent_access() {
if(value == NULL) {
release_mutex(&mutex, value);
mu_fail("cannot take record\n");
mu_fail("cannot take record\r\n");
}
// emulate read-modify-write broken by context switching

View File

@@ -31,19 +31,19 @@ bool test_furi_ac_create_kill() {
FuriApp* widget = furiac_start(create_kill_app, "create_kill_app", (void*)&counter);
if(widget == NULL) {
printf("create widget fail\n");
printf("create widget fail\r\n");
return false;
}
delay(10);
if(!furiac_kill(widget)) {
printf("kill widget fail\n");
printf("kill widget fail\r\n");
return false;
}
if(value_a == counter) {
printf("counter unchanged\n");
printf("counter unchanged\r\n");
return false;
}