[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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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);
}

@ -1 +1 @@
Subproject commit 621044255a8be4d2c3f342e2b22178a342ccbfe8
Subproject commit 7ba50ef912566c78d2ddd37ab5912a8cada5c35d

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;
}

View File

@ -5,12 +5,12 @@ FW_ADDRESS = 0x08008000
OS_OFFSET = 0x00008000
FLASH_ADDRESS = 0x08000000
OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "init"
OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "stm32wbx.cpu configure -rtos auto" -c "init"
BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OFFSET=$(OS_OFFSET)
MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard
CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections
LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs
LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs
CUBE_DIR = ../lib/STM32CubeWB

View File

@ -120,4 +120,4 @@ void api_interrupt_call(InterruptType type, void* hw) {
}
}
}
}
}

View File

@ -17,20 +17,22 @@ void furi_init() {
int systemd() {
furi_init();
printf("[systemd] furi initialized\r\n");
// FURI startup
for(size_t i = 0; i < FLIPPER_SERVICES_size(); i++) {
printf("[systemd] starting service %s\r\n", FLIPPER_SERVICES[i].name);
osThreadAttr_t* attr = furi_alloc(sizeof(osThreadAttr_t));
attr->name = FLIPPER_SERVICES[i].name;
attr->stack_size = 1024;
attr->stack_size = FLIPPER_SERVICES[i].stack_size;
osThreadNew(FLIPPER_SERVICES[i].app, NULL, attr);
}
printf("[systemd] all services started\r\n");
while(1) {
osThreadSuspend(osThreadGetId());
}
printf("\n=== Bye from Flipper Zero! ===\n\n");
printf("[systemd] === Bye from Flipper Zero! ===\r\n");
return (int)exitcode;
}

View File

@ -5,10 +5,7 @@ bool init_pubsub(PubSub* pubsub) {
// mutex without name,
// no attributes (unfortunatly robust mutex is not supported by FreeRTOS),
// with dynamic memory allocation
const osMutexAttr_t value_mutex_attr = {
.name = NULL, .attr_bits = 0, .cb_mem = NULL, .cb_size = 0U};
pubsub->mutex = osMutexNew(&value_mutex_attr);
pubsub->mutex = osMutexNew(NULL);
if(pubsub->mutex == NULL) return false;
// construct list

View File

@ -1,5 +1,6 @@
#include "record.h"
#include "check.h"
#include "memmgr.h"
#include <cmsis_os2.h>
#include <m-string.h>
@ -22,34 +23,38 @@ typedef struct {
FuriRecordDict_t records;
} FuriRecordData;
FuriRecordData furi_record_data;
static FuriRecordData* furi_record_data = NULL;
void furi_record_init() {
furi_record_data.records_mutex = osMutexNew(NULL);
FuriRecordDict_init(furi_record_data.records);
furi_record_data = furi_alloc(sizeof(FuriRecordData));
furi_record_data->records_mutex = osMutexNew(NULL);
furi_check(furi_record_data->records_mutex);
FuriRecordDict_init(furi_record_data->records);
}
FuriRecord* furi_record_get_or_create(string_t name_str) {
FuriRecord* record = FuriRecordDict_get(furi_record_data.records, name_str);
assert(furi_record_data);
FuriRecord* record = FuriRecordDict_get(furi_record_data->records, name_str);
if(!record) {
FuriRecord new_record;
new_record.data = NULL;
new_record.owner = NULL;
osThreadIdSet_init(new_record.holders);
FuriRecordDict_set_at(furi_record_data.records, name_str, new_record);
record = FuriRecordDict_get(furi_record_data.records, name_str);
FuriRecordDict_set_at(furi_record_data->records, name_str, new_record);
record = FuriRecordDict_get(furi_record_data->records, name_str);
}
return record;
}
void furi_record_create(const char* name, void* data) {
assert(furi_record_data);
osThreadId_t thread_id = osThreadGetId();
string_t name_str;
string_init_set_str(name_str, name);
// Acquire mutex
furi_check(osMutexAcquire(furi_record_data.records_mutex, osWaitForever) == osOK);
furi_check(osMutexAcquire(furi_record_data->records_mutex, osWaitForever) == osOK);
FuriRecord* record = furi_record_get_or_create(name_str);
record->data = data;
record->owner = thread_id;
@ -60,31 +65,34 @@ void furi_record_create(const char* name, void* data) {
osThreadFlagsSet((osThreadId_t)*osThreadIdSet_ref(it), FURI_RECORD_FLAG_UPDATED);
}
// Release mutex
furi_check(osMutexRelease(furi_record_data.records_mutex) == osOK);
furi_check(osMutexRelease(furi_record_data->records_mutex) == osOK);
string_clear(name_str);
}
bool furi_record_destroy(const char* name) {
assert(furi_record_data);
osThreadId_t thread_id = osThreadGetId();
string_t name_str;
string_init_set_str(name_str, name);
bool destroyed = false;
furi_check(osMutexAcquire(furi_record_data.records_mutex, osWaitForever) == osOK);
FuriRecord* record = FuriRecordDict_get(furi_record_data.records, name_str);
furi_check(osMutexAcquire(furi_record_data->records_mutex, osWaitForever) == osOK);
FuriRecord* record = FuriRecordDict_get(furi_record_data->records, name_str);
if(record && record->owner == thread_id && osThreadIdSet_size(record->holders) == 0) {
osThreadIdSet_clear(record->holders);
FuriRecordDict_erase(furi_record_data.records, name_str);
FuriRecordDict_erase(furi_record_data->records, name_str);
destroyed = true;
}
furi_check(osMutexRelease(furi_record_data.records_mutex) == osOK);
furi_check(osMutexRelease(furi_record_data->records_mutex) == osOK);
string_clear(name_str);
return destroyed;
}
void* furi_record_open(const char* name) {
assert(furi_record_data);
osThreadId_t thread_id = osThreadGetId();
string_t name_str;
@ -92,10 +100,10 @@ void* furi_record_open(const char* name) {
FuriRecord* record = NULL;
while(1) {
furi_check(osMutexAcquire(furi_record_data.records_mutex, osWaitForever) == osOK);
furi_check(osMutexAcquire(furi_record_data->records_mutex, osWaitForever) == osOK);
record = furi_record_get_or_create(name_str);
osThreadIdSet_push(record->holders, (uint32_t)thread_id);
furi_check(osMutexRelease(furi_record_data.records_mutex) == osOK);
furi_check(osMutexRelease(furi_record_data->records_mutex) == osOK);
// Check if owner is already arrived
if(record->owner) {
break;
@ -109,15 +117,16 @@ void* furi_record_open(const char* name) {
}
void furi_record_close(const char* name) {
assert(furi_record_data);
osThreadId_t thread_id = osThreadGetId();
string_t name_str;
string_init_set_str(name_str, name);
furi_check(osMutexAcquire(furi_record_data.records_mutex, osWaitForever) == osOK);
FuriRecord* record = FuriRecordDict_get(furi_record_data.records, name_str);
furi_check(osMutexAcquire(furi_record_data->records_mutex, osWaitForever) == osOK);
FuriRecord* record = FuriRecordDict_get(furi_record_data->records, name_str);
osThreadIdSet_erase(record->holders, (uint32_t)thread_id);
furi_check(osMutexRelease(furi_record_data.records_mutex) == osOK);
furi_check(osMutexRelease(furi_record_data->records_mutex) == osOK);
string_clear(name_str);
}

View File

@ -1,12 +1,57 @@
#include "stdglue.h"
#include <main.h>
#include "check.h"
#include "memmgr.h"
#include <main.h>
#include <cmsis_os2.h>
#include <stdio.h>
#include <string.h>
#include <m-dict.h>
extern UART_HandleTypeDef DEBUG_UART;
DICT_DEF2(
FuriStdglueCallbackDict,
uint32_t,
M_DEFAULT_OPLIST,
FuriStdglueWriteCallback,
M_PTR_OPLIST)
typedef struct {
osMutexId_t mutex;
FuriStdglueCallbackDict_t global_outputs;
FuriStdglueCallbackDict_t thread_outputs;
} FuriStdglue;
static FuriStdglue* furi_stdglue = NULL;
static ssize_t stdout_write(void* _cookie, const char* data, size_t size) {
assert(furi_stdglue);
osKernelState_t state = osKernelGetState();
osThreadId_t thread_id = osThreadGetId();
if(state == osKernelRunning && thread_id &&
osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK) {
// We are in the thread context
// Handle global callbacks
FuriStdglueCallbackDict_it_t it;
for(FuriStdglueCallbackDict_it(it, furi_stdglue->global_outputs);
!FuriStdglueCallbackDict_end_p(it);
FuriStdglueCallbackDict_next(it)) {
osThreadId_t it_thread = (osThreadId_t)FuriStdglueCallbackDict_ref(it)->key;
FuriStdglueWriteCallback it_callback = FuriStdglueCallbackDict_ref(it)->value;
if(thread_id != it_thread) {
it_callback(_cookie, data, size);
}
}
// Handle thread callbacks
FuriStdglueWriteCallback* callback_ptr =
FuriStdglueCallbackDict_get(furi_stdglue->thread_outputs, (uint32_t)thread_id);
if(callback_ptr) {
(*callback_ptr)(_cookie, data, size);
}
furi_check(osMutexRelease(furi_stdglue->mutex) == osOK);
}
// Flush
if(data == 0) {
/*
* This means that we should flush internal buffers. Since we
@ -15,13 +60,20 @@ static ssize_t stdout_write(void* _cookie, const char* data, size_t size) {
*/
return 0;
}
// Debug uart
HAL_UART_Transmit(&DEBUG_UART, (uint8_t*)data, (uint16_t)size, HAL_MAX_DELAY);
// All data consumed
return size;
}
bool furi_stdglue_init() {
void furi_stdglue_init() {
furi_stdglue = furi_alloc(sizeof(FuriStdglue));
// Init outputs structures
furi_stdglue->mutex = osMutexNew(NULL);
furi_check(furi_stdglue->mutex);
FuriStdglueCallbackDict_init(furi_stdglue->global_outputs);
FuriStdglueCallbackDict_init(furi_stdglue->thread_outputs);
// Prepare and set stdout descriptor
FILE* fp = fopencookie(
NULL,
"w",
@ -31,8 +83,42 @@ bool furi_stdglue_init() {
.seek = NULL,
.close = NULL,
});
setvbuf(fp, NULL, _IONBF, 0);
setvbuf(fp, NULL, _IOLBF, 0);
stdout = fp;
return true;
}
bool furi_stdglue_set_global_stdout_callback(FuriStdglueWriteCallback callback) {
assert(furi_stdglue);
osThreadId_t thread_id = osThreadGetId();
if(thread_id) {
furi_check(osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK);
if(callback) {
FuriStdglueCallbackDict_set_at(
furi_stdglue->global_outputs, (uint32_t)thread_id, callback);
} else {
FuriStdglueCallbackDict_erase(furi_stdglue->global_outputs, (uint32_t)thread_id);
}
furi_check(osMutexRelease(furi_stdglue->mutex) == osOK);
return true;
} else {
return false;
}
}
bool furi_stdglue_set_thread_stdout_callback(FuriStdglueWriteCallback callback) {
assert(furi_stdglue);
osThreadId_t thread_id = osThreadGetId();
if(thread_id) {
furi_check(osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK);
if(callback) {
FuriStdglueCallbackDict_set_at(
furi_stdglue->thread_outputs, (uint32_t)thread_id, callback);
} else {
FuriStdglueCallbackDict_erase(furi_stdglue->thread_outputs, (uint32_t)thread_id);
}
furi_check(osMutexRelease(furi_stdglue->mutex) == osOK);
return true;
} else {
return false;
}
}

View File

@ -1,12 +1,36 @@
#pragma once
#include <stdbool.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
bool furi_stdglue_init();
/* 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 global STDOUT callback
* @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_global_stdout_callback(FuriStdglueWriteCallback callback);
/* 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
}

View File

@ -10,10 +10,7 @@ bool init_composer(ValueComposer* composer, void* value) {
// mutex without name,
// no attributes (unfortunatly robust mutex is not supported by FreeRTOS),
// with dynamic memory allocation
const osMutexAttr_t value_mutex_attr = {
.name = NULL, .attr_bits = 0, .cb_mem = NULL, .cb_size = 0U};
composer->mutex = osMutexNew(&value_mutex_attr);
composer->mutex = osMutexNew(NULL);
if(composer->mutex == NULL) return false;
if(!init_event(&composer->request)) return false;

View File

@ -6,10 +6,7 @@ bool init_mutex(ValueMutex* valuemutex, void* value, size_t size) {
// mutex without name,
// no attributes (unfortunatly robust mutex is not supported by FreeRTOS),
// with dynamic memory allocation
const osMutexAttr_t value_mutext_attr = {
.name = NULL, .attr_bits = 0, .cb_mem = NULL, .cb_size = 0U};
valuemutex->mutex = osMutexNew(&value_mutext_attr);
valuemutex->mutex = osMutexNew(NULL);
if(valuemutex->mutex == NULL) return false;
valuemutex->value = value;

View File

@ -16,6 +16,9 @@ typedef enum {
/* Initialize drivers */
void api_hal_power_init();
/* Check if deep sleep availble */
bool api_hal_power_deep_available();
/* Go to deep sleep */
void api_hal_power_deep_sleep();

View File

@ -25,7 +25,7 @@ size_t api_hal_vcp_rx(uint8_t* buffer, size_t size);
* @param buffer - pointer to buffer
* @param size - buffer size
*/
void api_hal_vcp_tx(uint8_t* buffer, size_t size);
void api_hal_vcp_tx(const uint8_t* buffer, size_t size);
#ifdef __cplusplus
}

View File

@ -58,12 +58,12 @@
/* USER CODE END 0 */
#endif
#define configENABLE_FPU 1
#define configENABLE_MPU 0
#define configENABLE_MPU 1
#define configUSE_PREEMPTION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ((TickType_t)1024)
@ -71,8 +71,8 @@
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)131072)
#define configMAX_TASK_NAME_LEN ( 16 )
#define configGENERATE_RUN_TIME_STATS 1
#define configUSE_TRACE_FACILITY 1
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
@ -83,6 +83,7 @@
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_TICKLESS_IDLE 2
#define configRECORD_STACK_HIGH_ADDRESS 1
#define configUSE_NEWLIB_REENTRANT 0
/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
/* Defaults to size_t for backward compatibility, but can be changed
if lengths will always be less than the number of bytes in a size_t. */
@ -106,7 +107,6 @@ to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
@ -142,15 +142,15 @@ PRIORITY THAN THIS! (higher priorities are lower numeric values. */
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); asm("bkpt 1"); for( ;; );}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
@ -163,14 +163,4 @@ standard names. */
/* #define xPortSysTickHandler SysTick_Handler */
/* USER CODE BEGIN 2 */
/* Definitions needed when configGENERATE_RUN_TIME_STATS is on */
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats
#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue
/* USER CODE END 2 */
/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
/* USER CODE END Defines */
#endif /* FREERTOS_CONFIG_H */

View File

@ -3,49 +3,23 @@
#include <task.h>
#include <main.h>
void systemd(void *argument);
osThreadId_t systemdHandle;
const osThreadAttr_t systemd_attributes = {
.name = "systemd",
.priority = (osPriority_t) osPriorityNormal,
.stack_size = 1024 * 4
.stack_size = 1024
};
void systemd(void *argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/* Hook prototypes */
void configureTimerForRunTimeStats(void);
unsigned long getRunTimeCounterValue(void);
void vApplicationIdleHook(void);
void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName);
__weak void configureTimerForRunTimeStats(void) {
}
__weak unsigned long getRunTimeCounterValue(void) {
return 0;
}
__weak void vApplicationIdleHook( void ) {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
}
__weak void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) {
void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) {
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
called if a stack overflow is detected. */
asm("bkpt 1");
while(1);
}
void MX_FREERTOS_Init(void) {
systemdHandle = osThreadNew(systemd, NULL, &systemd_attributes);
}

View File

@ -111,7 +111,7 @@ void HardFault_Handler(void)
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
__asm("bkpt 1");
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
@ -126,7 +126,7 @@ void MemManage_Handler(void)
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
__asm("bkpt 1");
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
@ -141,7 +141,7 @@ void BusFault_Handler(void)
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
__asm("bkpt 1");
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
@ -399,7 +399,6 @@ extern void HW_TS_RTC_Wakeup_Handler();
extern void HW_IPCC_Tx_Handler();
extern void HW_IPCC_Rx_Handler();
void RTC_WKUP_IRQHandler(void)
{
HW_TS_RTC_Wakeup_Handler();
@ -408,14 +407,11 @@ void RTC_WKUP_IRQHandler(void)
void IPCC_C1_TX_IRQHandler(void)
{
HW_IPCC_Tx_Handler();
return;
}
void IPCC_C1_RX_IRQHandler(void)
{
HW_IPCC_Rx_Handler();
return;
}
/* USER CODE END 1 */

View File

@ -1,5 +1,6 @@
#include <api-hal-power.h>
#include <api-hal-clock.h>
#include <api-hal-bt.h>
#include <stm32wbxx_ll_rcc.h>
#include <stm32wbxx_ll_pwr.h>
@ -22,6 +23,10 @@ void api_hal_power_init() {
bq25896_init();
}
bool api_hal_power_deep_available() {
return api_hal_bt_is_alive();
}
void api_hal_power_deep_sleep() {
while( LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));

View File

@ -69,7 +69,7 @@ static inline bool api_hal_timebase_timer_cmp_is_ok() {
}
static inline uint32_t api_hal_timebase_timer_get_cmp() {
return LL_LPTIM_GetCompare(API_HAL_TIMEBASE_TIMER);;
return LL_LPTIM_GetCompare(API_HAL_TIMEBASE_TIMER);
}
static inline void api_hal_timebase_timer_set_cmp(uint32_t value) {

View File

@ -96,9 +96,12 @@ static inline uint32_t api_hal_timebase_sleep(TickType_t expected_idle_ticks) {
const uint16_t expected_cnt = (before_tick + expected_idle_ticks - 2) * API_HAL_TIMEBASE_CLK_PER_TICK;
api_hal_timebase_timer_set_cmp(expected_cnt);
HAL_SuspendTick();
// Go to stop2 mode
api_hal_power_deep_sleep();
HAL_ResumeTick();
// Spin till we are in timer safe zone
while(!api_hal_timebase_timer_is_safe()) {}
@ -124,14 +127,15 @@ static inline uint32_t api_hal_timebase_sleep(TickType_t expected_idle_ticks) {
}
void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) {
if (!api_hal_power_deep_available() || api_hal_timebase.insomnia) {
return;
}
// Limit mount of ticks to maximum that timer can count
if (expected_idle_ticks > API_HAL_TIMEBASE_MAX_SLEEP) {
expected_idle_ticks = API_HAL_TIMEBASE_MAX_SLEEP;
}
if (api_hal_timebase.insomnia)
return;
// Stop IRQ handling, no one should disturb us till we finish
__disable_irq();

View File

@ -12,7 +12,7 @@ typedef struct {
volatile bool underrun;
} ApiHalVcp;
ApiHalVcp api_hal_vcp;
static ApiHalVcp* api_hal_vcp = NULL;
static const uint8_t ascii_soh = 0x01;
static const uint8_t ascii_eot = 0x04;
@ -24,19 +24,20 @@ void _api_hal_vcp_rx_callback(const uint8_t* buffer, size_t size);
void _api_hal_vcp_tx_complete(size_t size);
void api_hal_vcp_init() {
api_hal_vcp.rx_stream = xStreamBufferCreate(API_HAL_VCP_RX_BUFFER_SIZE, 1);
api_hal_vcp.tx_semaphore = osSemaphoreNew(1, 1, NULL);
api_hal_vcp.alive = false;
api_hal_vcp.underrun = false;
api_hal_vcp = furi_alloc(sizeof(ApiHalVcp));
api_hal_vcp->rx_stream = xStreamBufferCreate(API_HAL_VCP_RX_BUFFER_SIZE, 1);
api_hal_vcp->tx_semaphore = osSemaphoreNew(1, 1, NULL);
api_hal_vcp->alive = false;
api_hal_vcp->underrun = false;
}
void _api_hal_vcp_init() {
osSemaphoreRelease(api_hal_vcp.tx_semaphore);
osSemaphoreRelease(api_hal_vcp->tx_semaphore);
}
void _api_hal_vcp_deinit() {
api_hal_vcp.alive = false;
osSemaphoreRelease(api_hal_vcp.tx_semaphore);
api_hal_vcp->alive = false;
osSemaphoreRelease(api_hal_vcp->tx_semaphore);
}
void _api_hal_vcp_control_line(uint8_t state) {
@ -45,43 +46,46 @@ void _api_hal_vcp_control_line(uint8_t state) {
bool rts = state & 0b10;
if (rts) {
api_hal_vcp.alive = true;
api_hal_vcp->alive = true;
_api_hal_vcp_rx_callback(&ascii_soh, 1); // SOH
} else {
api_hal_vcp.alive = false;
api_hal_vcp->alive = false;
_api_hal_vcp_rx_callback(&ascii_eot, 1); // EOT
}
osSemaphoreRelease(api_hal_vcp.tx_semaphore);
osSemaphoreRelease(api_hal_vcp->tx_semaphore);
}
void _api_hal_vcp_rx_callback(const uint8_t* buffer, size_t size) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
size_t ret = xStreamBufferSendFromISR(api_hal_vcp.rx_stream, buffer, size, &xHigherPriorityTaskWoken);
size_t ret = xStreamBufferSendFromISR(api_hal_vcp->rx_stream, buffer, size, &xHigherPriorityTaskWoken);
if (ret != size) {
api_hal_vcp.underrun = true;
api_hal_vcp->underrun = true;
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void _api_hal_vcp_tx_complete(size_t size) {
osSemaphoreRelease(api_hal_vcp.tx_semaphore);
osSemaphoreRelease(api_hal_vcp->tx_semaphore);
}
size_t api_hal_vcp_rx(uint8_t* buffer, size_t size) {
return xStreamBufferReceive(api_hal_vcp.rx_stream, buffer, size, portMAX_DELAY);
furi_assert(api_hal_vcp);
return xStreamBufferReceive(api_hal_vcp->rx_stream, buffer, size, portMAX_DELAY);
}
void api_hal_vcp_tx(uint8_t* buffer, size_t size) {
while (size > 0 && api_hal_vcp.alive) {
furi_check(osSemaphoreAcquire(api_hal_vcp.tx_semaphore, osWaitForever) == osOK);
void api_hal_vcp_tx(const uint8_t* buffer, size_t size) {
furi_assert(api_hal_vcp);
while (size > 0 && api_hal_vcp->alive) {
furi_check(osSemaphoreAcquire(api_hal_vcp->tx_semaphore, osWaitForever) == osOK);
size_t batch_size = size;
if (batch_size > APP_TX_DATA_SIZE) {
batch_size = APP_TX_DATA_SIZE;
}
if (CDC_Transmit_FS(buffer, batch_size) == USBD_OK) {
if (CDC_Transmit_FS((uint8_t*)buffer, batch_size) == USBD_OK) {
size -= batch_size;
buffer += batch_size;
} else {

View File

@ -1,7 +1,6 @@
#include "main.h"
#include "app_common.h"
#include "dbg_trace.h"
#include "ble.h"
#include "tl.h"
@ -14,6 +13,8 @@
#include "dis_app.h"
#include "hrs_app.h"
#include <api-hal.h>
typedef struct _tSecurityParams {
uint8_t ioCapability;
uint8_t mitm_mode;
@ -214,10 +215,11 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
if (disconnection_complete_event->Connection_Handle == BleApplicationContext.BleApplicationContext_legacy.connectionHandle) {
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0;
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
APP_DBG_MSG("\r\n\r** DISCONNECTION EVENT WITH CLIENT \n");
APP_DBG_MSG("\r\n\r** DISCONNECTION EVENT WITH CLIENT \r\n");
}
/* restart advertising */
Adv_Request(APP_BLE_FAST_ADV);
api_hal_timebase_insomnia_exit();
}
break; /* EVT_DISCONN_COMPLETE */
@ -227,45 +229,46 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
switch (meta_evt->subevent)
{
case EVT_LE_CONN_UPDATE_COMPLETE:
APP_DBG_MSG("\r\n\r** CONNECTION UPDATE EVENT WITH CLIENT \n");
APP_DBG_MSG("\r\n\r** CONNECTION UPDATE EVENT WITH CLIENT \r\n");
/* USER CODE BEGIN EVT_LE_CONN_UPDATE_COMPLETE */
/* USER CODE END EVT_LE_CONN_UPDATE_COMPLETE */
break;
case EVT_LE_PHY_UPDATE_COMPLETE:
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE \n");
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE \r\n");
evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data;
if (evt_le_phy_update_complete->Status == 0)
{
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status ok \n");
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status ok \r\n");
}
else
{
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status nok \n");
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status nok \r\n");
}
ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY);
if (ret == BLE_STATUS_SUCCESS)
{
APP_DBG_MSG("Read_PHY success \n");
APP_DBG_MSG("Read_PHY success \r\n");
if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M))
{
APP_DBG_MSG("PHY Param TX= %d, RX= %d \n", TX_PHY, RX_PHY);
APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
}
else
{
APP_DBG_MSG("PHY Param TX= %d, RX= %d \n", TX_PHY, RX_PHY);
APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
}
}
else
{
APP_DBG_MSG("Read conf not succeess \n");
APP_DBG_MSG("Read conf not succeess \r\n");
}
break;
case EVT_LE_CONN_COMPLETE:
{
api_hal_timebase_insomnia_enter();
hci_le_connection_complete_event_rp0 *connection_complete_event;
/**
@ -275,7 +278,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id);
APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\n", connection_complete_event->Connection_Handle);
APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\r\n", connection_complete_event->Connection_Handle);
if (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_CONNECTING)
{
/* Connection as client */
@ -301,71 +304,71 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
aci_gap_pairing_complete_event_rp0 *pairing_complete;
case EVT_BLUE_GAP_LIMITED_DISCOVERABLE:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_LIMITED_DISCOVERABLE \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_LIMITED_DISCOVERABLE \r\n");
break; /* EVT_BLUE_GAP_LIMITED_DISCOVERABLE */
case EVT_BLUE_GAP_PASS_KEY_REQUEST:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PASS_KEY_REQUEST \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PASS_KEY_REQUEST \r\n");
aci_gap_pass_key_resp(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,123456);
APP_DBG_MSG("\r\n\r** aci_gap_pass_key_resp \n");
APP_DBG_MSG("\r\n\r** aci_gap_pass_key_resp \r\n");
break; /* EVT_BLUE_GAP_PASS_KEY_REQUEST */
case EVT_BLUE_GAP_AUTHORIZATION_REQUEST:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_AUTHORIZATION_REQUEST \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_AUTHORIZATION_REQUEST \r\n");
break; /* EVT_BLUE_GAP_AUTHORIZATION_REQUEST */
case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED \r\n");
break; /* EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED */
case EVT_BLUE_GAP_BOND_LOST:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_BOND_LOST \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_BOND_LOST \r\n");
aci_gap_allow_rebond(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
APP_DBG_MSG("\r\n\r** Send allow rebond \n");
APP_DBG_MSG("\r\n\r** Send allow rebond \r\n");
break; /* EVT_BLUE_GAP_BOND_LOST */
case EVT_BLUE_GAP_DEVICE_FOUND:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \r\n");
break; /* EVT_BLUE_GAP_DEVICE_FOUND */
case EVT_BLUE_GAP_ADDR_NOT_RESOLVED:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \r\n");
break; /* EVT_BLUE_GAP_DEVICE_FOUND */
case (EVT_BLUE_GAP_KEYPRESS_NOTIFICATION):
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_KEYPRESS_NOTIFICATION \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_KEYPRESS_NOTIFICATION \r\n");
break; /* EVT_BLUE_GAP_KEY_PRESS_NOTIFICATION */
case (EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE):
APP_DBG_MSG("numeric_value = %ld\n",
APP_DBG_MSG("numeric_value = %ld\r\n",
((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value);
APP_DBG_MSG("Hex_value = %lx\n",
APP_DBG_MSG("Hex_value = %lx\r\n",
((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value);
aci_gap_numeric_comparison_value_confirm_yesno(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, 1); /* CONFIRM_YES = 1 */
APP_DBG_MSG("\r\n\r** aci_gap_numeric_comparison_value_confirm_yesno-->YES \n");
APP_DBG_MSG("\r\n\r** aci_gap_numeric_comparison_value_confirm_yesno-->YES \r\n");
break;
case (EVT_BLUE_GAP_PAIRING_CMPLT):
{
pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data;
APP_DBG_MSG("BLE_CTRL_App_Notification: EVT_BLUE_GAP_PAIRING_CMPLT, pairing_complete->Status = %d\n",pairing_complete->Status);
APP_DBG_MSG("BLE_CTRL_App_Notification: EVT_BLUE_GAP_PAIRING_CMPLT, pairing_complete->Status = %d\r\n",pairing_complete->Status);
if (pairing_complete->Status == 0) {
APP_DBG_MSG("\r\n\r** Pairing OK \n");
APP_DBG_MSG("\r\n\r** Pairing OK \r\n");
} else {
APP_DBG_MSG("\r\n\r** Pairing KO \n");
APP_DBG_MSG("\r\n\r** Pairing KO \r\n");
}
}
break;
/* USER CODE END ecode */
case EVT_BLUE_GAP_PROCEDURE_COMPLETE:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PROCEDURE_COMPLETE \n");
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PROCEDURE_COMPLETE \r\n");
break;
}
break; /* EVT_VENDOR */
@ -385,9 +388,9 @@ void APP_BLE_Key_Button1_Action() {
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
ret = aci_gap_clear_security_db();
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("Successfully aci_gap_clear_security_db()\n");
APP_DBG_MSG("Successfully aci_gap_clear_security_db()\r\n");
} else {
APP_DBG_MSG("aci_gap_clear_security_db() Failed , result: %d \n", ret);
APP_DBG_MSG("aci_gap_clear_security_db() Failed , result: %d \r\n", ret);
}
}
@ -397,7 +400,7 @@ void APP_BLE_Key_Button2_Action() {
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("Successfully aci_gap_slave_security_req()");
} else {
APP_DBG_MSG("aci_gap_slave_security_req() Failed , result: %d \n", ret);
APP_DBG_MSG("aci_gap_slave_security_req() Failed , result: %d \r\n", ret);
}
}
@ -406,23 +409,23 @@ void APP_BLE_Key_Button3_Action() {
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY);
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("Read_PHY success \n");
APP_DBG_MSG("PHY Param TX= %d, RX= %d \n", TX_PHY, RX_PHY);
APP_DBG_MSG("Read_PHY success \r\n");
APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M)) {
APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \n", TX_1M, RX_1M);
APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_1M, RX_1M);
ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_1M,RX_1M,0);
} else {
APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \n", TX_2M_PREFERRED, RX_2M_PREFERRED);
APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_2M_PREFERRED, RX_2M_PREFERRED);
ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_2M_PREFERRED,RX_2M_PREFERRED,0);
}
} else {
APP_DBG_MSG("Read conf not succeess \n");
APP_DBG_MSG("Read conf not succeess \r\n");
}
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("set PHY cmd ok\n");
APP_DBG_MSG("set PHY cmd ok\r\n");
} else {
APP_DBG_MSG("set PHY cmd NOK\n");
APP_DBG_MSG("set PHY cmd NOK\r\n");
}
}
@ -538,7 +541,7 @@ static void Ble_Hci_Gap_Gatt_Init() {
if (aci_gatt_update_char_value(gap_service_handle, gap_dev_name_char_handle, 0, strlen(name), (uint8_t *) name))
{
BLE_DBG_SVCCTL_MSG("Device Name aci_gatt_update_char_value failed.\n");
BLE_DBG_SVCCTL_MSG("Device Name aci_gatt_update_char_value failed.\r\n");
}
}
@ -548,7 +551,7 @@ static void Ble_Hci_Gap_Gatt_Init() {
2,
(uint8_t *)&appearance))
{
BLE_DBG_SVCCTL_MSG("Appearance aci_gatt_update_char_value failed.\n");
BLE_DBG_SVCCTL_MSG("Appearance aci_gatt_update_char_value failed.\r\n");
}
/**
* Initialize Default PHY
@ -613,7 +616,7 @@ static void Adv_Request(APP_BLE_ConnStatus_t New_Status)
*/
HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id);
APP_DBG_MSG("First index in %d state \n", BleApplicationContext.Device_Connection_Status);
APP_DBG_MSG("First index in %d state \r\n", BleApplicationContext.Device_Connection_Status);
if ((New_Status == APP_BLE_LP_ADV)
&& ((BleApplicationContext.Device_Connection_Status == APP_BLE_FAST_ADV)
@ -623,11 +626,11 @@ static void Adv_Request(APP_BLE_ConnStatus_t New_Status)
ret = aci_gap_set_non_discoverable();
if (ret == BLE_STATUS_SUCCESS)
{
APP_DBG_MSG("Successfully Stopped Advertising \n");
APP_DBG_MSG("Successfully Stopped Advertising \r\n");
}
else
{
APP_DBG_MSG("Stop Advertising Failed , result: %d \n", ret);
APP_DBG_MSG("Stop Advertising Failed , result: %d \r\n", ret);
}
}
@ -650,17 +653,17 @@ static void Adv_Request(APP_BLE_ConnStatus_t New_Status)
ret = aci_gap_update_adv_data(sizeof(manuf_data), (uint8_t*) manuf_data);
if (ret == BLE_STATUS_SUCCESS) {
if (New_Status == APP_BLE_FAST_ADV) {
APP_DBG_MSG("Successfully Start Fast Advertising \n" );
APP_DBG_MSG("Successfully Start Fast Advertising \r\n" );
/* Start Timer to STOP ADV - TIMEOUT */
HW_TS_Start(BleApplicationContext.Advertising_mgr_timer_Id, INITIAL_ADV_TIMEOUT);
} else {
APP_DBG_MSG("Successfully Start Low Power Advertising \n");
APP_DBG_MSG("Successfully Start Low Power Advertising \r\n");
}
} else {
if (New_Status == APP_BLE_FAST_ADV) {
APP_DBG_MSG("Start Fast Advertising Failed , result: %d \n", ret);
APP_DBG_MSG("Start Fast Advertising Failed , result: %d \r\n", ret);
} else {
APP_DBG_MSG("Start Low Power Advertising Failed , result: %d \n", ret);
APP_DBG_MSG("Start Low Power Advertising Failed , result: %d \r\n", ret);
}
}
}

View File

@ -5,7 +5,7 @@
#include "hw_if.h"
#include "ble_bufsize.h"
#define CFG_TX_POWER (0x18) /* -0.15dBm */
#define CFG_TX_POWER (0x1F) /* +6dBm */
/**
* Define Advertising parameters
@ -21,7 +21,7 @@
*/
#define CFG_BONDING_MODE (1)
#define CFG_FIXED_PIN (111111)
#define CFG_USED_FIXED_PIN (0)
#define CFG_USED_FIXED_PIN (1)
#define CFG_ENCRYPTION_KEY_SIZE_MAX (16)
#define CFG_ENCRYPTION_KEY_SIZE_MIN (8)
@ -367,12 +367,12 @@ typedef enum
/**
* When set to 1, the traces are enabled in the BLE services
*/
#define CFG_DEBUG_BLE_TRACE 0
#define CFG_DEBUG_BLE_TRACE 1
/**
* Enable or Disable traces in application
*/
#define CFG_DEBUG_APP_TRACE 0
#define CFG_DEBUG_APP_TRACE 1
#if (CFG_DEBUG_APP_TRACE != 0)
#define APP_DBG_MSG PRINT_MESG_DBG

View File

@ -393,7 +393,7 @@ void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) )
/* USER CODE END DbgOutputTraces */
// HW_UART_Transmit_DMA(CFG_DEBUG_TRACE_UART, p_data, size, cb);
HAL_UART_Transmit(&DEBUG_UART, (uint8_t*)p_data, (uint16_t)size, HAL_MAX_DELAY);
cb();
/* USER CODE END DbgOutputTraces */
return;
}

View File

@ -40,14 +40,14 @@ extern UART_HandleTypeDef DEBUG_UART;
* Enable or Disable traces
* The raw data output is the hci binary packet format as specified by the BT specification *
*/
#define TL_SHCI_CMD_DBG_EN 1 /* Reports System commands sent to CPU2 and the command response */
#define TL_SHCI_CMD_DBG_EN 0 /* Reports System commands sent to CPU2 and the command response */
#define TL_SHCI_CMD_DBG_RAW_EN 0 /* Reports raw data System commands sent to CPU2 and the command response */
#define TL_SHCI_EVT_DBG_EN 1 /* Reports System Asynchronous Events received from CPU2 */
#define TL_SHCI_EVT_DBG_EN 0 /* Reports System Asynchronous Events received from CPU2 */
#define TL_SHCI_EVT_DBG_RAW_EN 0 /* Reports raw data System Asynchronous Events received from CPU2 */
#define TL_HCI_CMD_DBG_EN 1 /* Reports BLE command sent to CPU2 and the command response */
#define TL_HCI_CMD_DBG_EN 0 /* Reports BLE command sent to CPU2 and the command response */
#define TL_HCI_CMD_DBG_RAW_EN 0 /* Reports raw data BLE command sent to CPU2 and the command response */
#define TL_HCI_EVT_DBG_EN 1 /* Reports BLE Asynchronous Events received from CPU2 */
#define TL_HCI_EVT_DBG_EN 0 /* Reports BLE Asynchronous Events received from CPU2 */
#define TL_HCI_EVT_DBG_RAW_EN 0 /* Reports raw data BLE Asynchronous Events received from CPU2 */
#define TL_MM_DBG_EN 1 /* Reports the informations of the buffer released to CPU2 */

View File

@ -1,7 +1,5 @@
TOOLCHAIN = arm
OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "stm32wbx.cpu configure -rtos auto"
BOOT_ADDRESS = 0x08000000
FW_ADDRESS = 0x08008000
OS_OFFSET = 0x00008000
@ -16,13 +14,14 @@ FLASH_ADDRESS = 0x08000000
CFLAGS += -DNO_BOOTLOADER
endif
OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "stm32wbx.cpu configure -rtos auto" -c "init"
BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OFFSET=$(OS_OFFSET)
MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard
CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections
LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs
CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions
CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions
LDFLAGS += -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group
MXPROJECT_DIR = $(TARGET_DIR)

View File

@ -11,6 +11,10 @@ OBJECTS += $(addprefix $(OBJ_DIR)/, $(notdir $(CPP_SOURCES:.cpp=.o)))
# Generate dependencies
DEPS = $(OBJECTS:.o=.d)
ifdef DFU_SERIAL
DFU_OPTIONS += -S $(DFU_SERIAL)
endif
$(shell test -d $(OBJ_DIR) || mkdir -p $(OBJ_DIR))
BUILD_FLAGS_SHELL=\
@ -59,7 +63,7 @@ $(OBJ_DIR)/flash: $(OBJ_DIR)/$(PROJECT).bin
touch $@
$(OBJ_DIR)/upload: $(OBJ_DIR)/$(PROJECT).bin
dfu-util -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) -S $(DFU_SERIAL)
dfu-util -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS)
touch $@
$(ASSETS): $(ASSETS_SOURCES) $(ASSETS_COMPILLER)
@ -80,6 +84,9 @@ debug: flash
-ex "compare-sections" \
$(OBJ_DIR)/$(PROJECT).elf; \
openocd:
openocd $(OPENOCD_OPTS)
bm_debug: flash
set -m; blackmagic & echo $$! > $(OBJ_DIR)/agent.PID
arm-none-eabi-gdb \