diff --git a/applications/main/gpio/usb_uart_bridge.c b/applications/main/gpio/usb_uart_bridge.c index 77cd02f63..3e1cefb93 100644 --- a/applications/main/gpio/usb_uart_bridge.c +++ b/applications/main/gpio/usb_uart_bridge.c @@ -60,6 +60,8 @@ struct UsbUartBridge { FuriApiLock cfg_lock; + CliVcp* cli_vcp; + uint8_t rx_buf[USB_CDC_PKT_LEN]; }; @@ -105,15 +107,11 @@ static void usb_uart_on_irq_rx_dma_cb( static void usb_uart_vcp_init(UsbUartBridge* usb_uart, uint8_t vcp_ch) { furi_hal_usb_unlock(); if(vcp_ch == 0) { - CliVcp* cli_vcp = furi_record_open(RECORD_CLI_VCP); - cli_vcp_disable(cli_vcp); - furi_record_close(RECORD_CLI_VCP); + cli_vcp_disable(usb_uart->cli_vcp); furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true); } else { furi_check(furi_hal_usb_set_config(&usb_cdc_dual, NULL) == true); - CliVcp* cli_vcp = furi_record_open(RECORD_CLI_VCP); - cli_vcp_enable(cli_vcp); - furi_record_close(RECORD_CLI_VCP); + cli_vcp_enable(usb_uart->cli_vcp); } furi_hal_cdc_set_callbacks(vcp_ch, (CdcCallbacks*)&cdc_cb, usb_uart); } @@ -122,9 +120,7 @@ static void usb_uart_vcp_deinit(UsbUartBridge* usb_uart, uint8_t vcp_ch) { UNUSED(usb_uart); furi_hal_cdc_set_callbacks(vcp_ch, NULL, NULL); if(vcp_ch != 0) { - CliVcp* cli_vcp = furi_record_open(RECORD_CLI_VCP); - cli_vcp_disable(cli_vcp); - furi_record_close(RECORD_CLI_VCP); + cli_vcp_disable(usb_uart->cli_vcp); } } @@ -176,6 +172,8 @@ static int32_t usb_uart_worker(void* context) { memcpy(&usb_uart->cfg, &usb_uart->cfg_new, sizeof(UsbUartConfig)); + usb_uart->cli_vcp = furi_record_open(RECORD_CLI_VCP); + usb_uart->rx_stream = furi_stream_buffer_alloc(USB_UART_RX_BUF_SIZE, 1); usb_uart->tx_sem = furi_semaphore_alloc(1, 1); @@ -308,8 +306,8 @@ static int32_t usb_uart_worker(void* context) { furi_hal_usb_unlock(); furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true); - CliVcp* cli_vcp = furi_record_open(RECORD_CLI_VCP); - cli_vcp_enable(cli_vcp); + cli_vcp_enable(usb_uart->cli_vcp); + furi_record_close(RECORD_CLI_VCP); return 0; diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index def1949e2..cea4de248 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "cli_main_shell.h" #include "cli_main_commands.h" @@ -26,6 +27,7 @@ typedef struct { CliVcpMessageTypeEnable, CliVcpMessageTypeDisable, } type; + FuriApiLock api_lock; union {}; } CliVcpMessage; @@ -182,6 +184,8 @@ static void cli_vcp_message_received(FuriEventLoopObject* object, void* context) furi_hal_usb_set_config(cli_vcp->previous_interface, NULL); break; } + + api_lock_unlock(message.api_lock); } /** @@ -300,16 +304,24 @@ int32_t cli_vcp_srv(void* p) { // Public API // ========== +static void cli_vcp_synchronous_request(CliVcp* cli_vcp, CliVcpMessage* message) { + message->api_lock = api_lock_alloc_locked(); + furi_message_queue_put(cli_vcp->message_queue, message, FuriWaitForever); + api_lock_wait_unlock_and_free(message->api_lock); +} + void cli_vcp_enable(CliVcp* cli_vcp) { + furi_check(cli_vcp); CliVcpMessage message = { .type = CliVcpMessageTypeEnable, }; - furi_message_queue_put(cli_vcp->message_queue, &message, FuriWaitForever); + cli_vcp_synchronous_request(cli_vcp, &message); } void cli_vcp_disable(CliVcp* cli_vcp) { + furi_check(cli_vcp); CliVcpMessage message = { .type = CliVcpMessageTypeDisable, }; - furi_message_queue_put(cli_vcp->message_queue, &message, FuriWaitForever); + cli_vcp_synchronous_request(cli_vcp, &message); }