From 3367bc6f68b4ff0f87863d5a773307e12b24370d Mon Sep 17 00:00:00 2001 From: Matvey Gerasimov <48400794+spherebread@users.noreply.github.com> Date: Fri, 7 Oct 2022 10:23:21 +0400 Subject: [PATCH 1/6] Documentation: AppManifests.md typo fix (#1836) --- documentation/AppManifests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/AppManifests.md b/documentation/AppManifests.md index 14c0ae3ac..4fec9d22c 100644 --- a/documentation/AppManifests.md +++ b/documentation/AppManifests.md @@ -47,7 +47,7 @@ Only 2 parameters are mandatory: ***appid*** and ***apptype***, others are optio The following parameters are used only for [FAPs](./AppsOnSDCard.md): * **sources**: list of strings, file name masks, used for gathering sources within app folder. Default value of `["*.c*"]` includes C and C++ source files. Application cannot use `"lib"` folder for their own source code, as it is reserved for **fap_private_libs**. -* **fap_version**: tuple, 2 numbers in form of (x,y): application version to be embedded within .fap file. Default value is (0,1), meanig version "0.1". +* **fap_version**: tuple, 2 numbers in form of (x,y): application version to be embedded within .fap file. Default value is (0,1), meaning version "0.1". * **fap_icon**: name of a .png file, 1-bit color depth, 10x10px, to be embedded within .fap file. * **fap_libs**: list of extra libraries to link application against. Provides access to extra functions that are not exported as a part of main firmware at expense of increased .fap file size and RAM consumption. * **fap_category**: string, may be empty. App subcategory, also works as path of FAP within apps folder in the file system. From d1843c009415bf5213777044734ec5e227e70ac6 Mon Sep 17 00:00:00 2001 From: Max Andreev Date: Fri, 7 Oct 2022 11:56:19 +0500 Subject: [PATCH 2/6] Disable PVS-Studio license check (#1840) --- .github/workflows/pvs_studio.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pvs_studio.yml b/.github/workflows/pvs_studio.yml index 7bd71de49..981575551 100644 --- a/.github/workflows/pvs_studio.yml +++ b/.github/workflows/pvs_studio.yml @@ -65,6 +65,7 @@ jobs: pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} pvs-studio-analyzer analyze \ @.pvsoptions \ + --disableLicenseExpirationCheck \ -j$(grep -c processor /proc/cpuinfo) \ -f build/f7-firmware-DC/compile_commands.json \ -o PVS-Studio.log From 38a82a1907008fda1d8aa655e66c80faf26e61ef Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Fri, 7 Oct 2022 22:27:11 +1000 Subject: [PATCH 3/6] [FL-2839] Furi stream buffer (#1834) * Core: stream buffer * stream buffer: API and usage * stream buffer: documentation * stream buffer: more documentation * Furi: fix spelling Co-authored-by: Aleksandr Kutuzov --- applications/debug/uart_echo/uart_echo.c | 13 +- applications/debug/unit_tests/rpc/rpc_test.c | 18 +-- applications/main/gpio/usb_uart_bridge.c | 17 +-- applications/main/subghz/subghz_cli.c | 18 +-- applications/services/cli/cli_commands.c | 9 +- applications/services/cli/cli_vcp.c | 32 ++-- applications/services/rpc/rpc.c | 21 ++- firmware/targets/f7/api_symbols.csv | 12 +- furi/core/stream_buffer.c | 77 ++++++++++ furi/core/stream_buffer.h | 152 +++++++++++++++++++ furi/furi.h | 33 ++-- lib/infrared/worker/infrared_worker.c | 38 +++-- lib/lfrfid/lfrfid_raw_worker.c | 21 +-- lib/lfrfid/lfrfid_worker_modes.c | 18 +-- lib/nfc/helpers/reader_analyzer.c | 17 +-- lib/one_wire/ibutton/ibutton_worker_modes.c | 12 +- lib/subghz/subghz_file_encoder_worker.c | 18 +-- lib/subghz/subghz_tx_rx_worker.c | 37 +++-- lib/subghz/subghz_worker.c | 18 +-- lib/toolbox/buffer_stream.c | 23 ++- lib/toolbox/buffer_stream.h | 7 +- 21 files changed, 403 insertions(+), 208 deletions(-) create mode 100644 furi/core/stream_buffer.c create mode 100644 furi/core/stream_buffer.h diff --git a/applications/debug/uart_echo/uart_echo.c b/applications/debug/uart_echo/uart_echo.c index 03b6a31a6..122862dd9 100644 --- a/applications/debug/uart_echo/uart_echo.c +++ b/applications/debug/uart_echo/uart_echo.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -20,7 +19,7 @@ typedef struct { ViewDispatcher* view_dispatcher; View* view; FuriThread* worker_thread; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* rx_stream; } UartEchoApp; typedef struct { @@ -92,13 +91,11 @@ static uint32_t uart_echo_exit(void* context) { static void uart_echo_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { furi_assert(context); - BaseType_t xHigherPriorityTaskWoken = pdFALSE; UartEchoApp* app = context; if(ev == UartIrqEventRXNE) { - xStreamBufferSendFromISR(app->rx_stream, &data, 1, &xHigherPriorityTaskWoken); + furi_stream_buffer_send(app->rx_stream, &data, 1, 0); furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventRx); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } @@ -158,7 +155,7 @@ static int32_t uart_echo_worker(void* context) { size_t length = 0; do { uint8_t data[64]; - length = xStreamBufferReceive(app->rx_stream, data, 64, 0); + length = furi_stream_buffer_receive(app->rx_stream, data, 64, 0); if(length > 0) { furi_hal_uart_tx(FuriHalUartIdUSART1, data, length); with_view_model( @@ -186,7 +183,7 @@ static int32_t uart_echo_worker(void* context) { static UartEchoApp* uart_echo_app_alloc() { UartEchoApp* app = malloc(sizeof(UartEchoApp)); - app->rx_stream = xStreamBufferCreate(2048, 1); + app->rx_stream = furi_stream_buffer_alloc(2048, 1); // Gui app->gui = furi_record_open(RECORD_GUI); @@ -260,7 +257,7 @@ static void uart_echo_app_free(UartEchoApp* app) { furi_record_close(RECORD_NOTIFICATION); app->gui = NULL; - vStreamBufferDelete(app->rx_stream); + furi_stream_buffer_free(app->rx_stream); // Free rest free(app); diff --git a/applications/debug/unit_tests/rpc/rpc_test.c b/applications/debug/unit_tests/rpc/rpc_test.c index 6ee2aed65..5b52df2fa 100644 --- a/applications/debug/unit_tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/rpc/rpc_test.c @@ -10,7 +10,6 @@ #include #include "../minunit.h" #include -#include #include #include #include @@ -34,7 +33,7 @@ static uint32_t command_id = 0; typedef struct { RpcSession* session; - StreamBufferHandle_t output_stream; + FuriStreamBuffer* output_stream; SemaphoreHandle_t close_session_semaphore; SemaphoreHandle_t terminate_semaphore; TickType_t timeout; @@ -90,7 +89,7 @@ static void test_rpc_setup(void) { } furi_check(rpc_session[0].session); - rpc_session[0].output_stream = xStreamBufferCreate(1000, 1); + rpc_session[0].output_stream = furi_stream_buffer_alloc(1000, 1); rpc_session_set_send_bytes_callback(rpc_session[0].session, output_bytes_callback); rpc_session[0].close_session_semaphore = xSemaphoreCreateBinary(); rpc_session[0].terminate_semaphore = xSemaphoreCreateBinary(); @@ -110,7 +109,7 @@ static void test_rpc_setup_second_session(void) { } furi_check(rpc_session[1].session); - rpc_session[1].output_stream = xStreamBufferCreate(1000, 1); + rpc_session[1].output_stream = furi_stream_buffer_alloc(1000, 1); rpc_session_set_send_bytes_callback(rpc_session[1].session, output_bytes_callback); rpc_session[1].close_session_semaphore = xSemaphoreCreateBinary(); rpc_session[1].terminate_semaphore = xSemaphoreCreateBinary(); @@ -126,7 +125,7 @@ static void test_rpc_teardown(void) { rpc_session_close(rpc_session[0].session); furi_check(xSemaphoreTake(rpc_session[0].terminate_semaphore, portMAX_DELAY)); furi_record_close(RECORD_RPC); - vStreamBufferDelete(rpc_session[0].output_stream); + furi_stream_buffer_free(rpc_session[0].output_stream); vSemaphoreDelete(rpc_session[0].close_session_semaphore); vSemaphoreDelete(rpc_session[0].terminate_semaphore); ++command_id; @@ -141,7 +140,7 @@ static void test_rpc_teardown_second_session(void) { xSemaphoreTake(rpc_session[1].terminate_semaphore, 0); rpc_session_close(rpc_session[1].session); furi_check(xSemaphoreTake(rpc_session[1].terminate_semaphore, portMAX_DELAY)); - vStreamBufferDelete(rpc_session[1].output_stream); + furi_stream_buffer_free(rpc_session[1].output_stream); vSemaphoreDelete(rpc_session[1].close_session_semaphore); vSemaphoreDelete(rpc_session[1].terminate_semaphore); ++command_id; @@ -268,8 +267,8 @@ static PB_CommandStatus test_rpc_storage_get_file_error(File* file) { static void output_bytes_callback(void* ctx, uint8_t* got_bytes, size_t got_size) { RpcSessionContext* callbacks_context = ctx; - size_t bytes_sent = - xStreamBufferSend(callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever); + size_t bytes_sent = furi_stream_buffer_send( + callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever); (void)bytes_sent; furi_check(bytes_sent == got_size); } @@ -534,7 +533,8 @@ static bool test_rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_ TickType_t now = xTaskGetTickCount(); int32_t time_left = session_context->timeout - now; time_left = MAX(time_left, 0); - bytes_received = xStreamBufferReceive(session_context->output_stream, buf, count, time_left); + bytes_received = + furi_stream_buffer_receive(session_context->output_stream, buf, count, time_left); return (count == bytes_received); } diff --git a/applications/main/gpio/usb_uart_bridge.c b/applications/main/gpio/usb_uart_bridge.c index 02f58ed10..6e0bce736 100644 --- a/applications/main/gpio/usb_uart_bridge.c +++ b/applications/main/gpio/usb_uart_bridge.c @@ -1,6 +1,5 @@ #include "usb_uart_bridge.h" #include "furi_hal.h" -#include #include #include "usb_cdc.h" #include "cli/cli_vcp.h" @@ -43,7 +42,7 @@ struct UsbUartBridge { FuriThread* thread; FuriThread* tx_thread; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* rx_stream; FuriMutex* usb_mutex; @@ -74,12 +73,10 @@ static int32_t usb_uart_tx_thread(void* context); static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { UsbUartBridge* usb_uart = (UsbUartBridge*)context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; if(ev == UartIrqEventRXNE) { - xStreamBufferSendFromISR(usb_uart->rx_stream, &data, 1, &xHigherPriorityTaskWoken); + furi_stream_buffer_send(usb_uart->rx_stream, &data, 1, 0); furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtRxDone); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } @@ -156,7 +153,7 @@ static int32_t usb_uart_worker(void* context) { memcpy(&usb_uart->cfg, &usb_uart->cfg_new, sizeof(UsbUartConfig)); - usb_uart->rx_stream = xStreamBufferCreate(USB_UART_RX_BUF_SIZE, 1); + usb_uart->rx_stream = furi_stream_buffer_alloc(USB_UART_RX_BUF_SIZE, 1); usb_uart->tx_sem = furi_semaphore_alloc(1, 1); usb_uart->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal); @@ -189,8 +186,8 @@ static int32_t usb_uart_worker(void* context) { furi_check((events & FuriFlagError) == 0); if(events & WorkerEvtStop) break; if(events & WorkerEvtRxDone) { - size_t len = - xStreamBufferReceive(usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0); + size_t len = furi_stream_buffer_receive( + usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0); if(len > 0) { if(furi_semaphore_acquire(usb_uart->tx_sem, 100) == FuriStatusOk) { usb_uart->st.rx_cnt += len; @@ -199,7 +196,7 @@ static int32_t usb_uart_worker(void* context) { furi_hal_cdc_send(usb_uart->cfg.vcp_ch, usb_uart->rx_buf, len); furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk); } else { - xStreamBufferReset(usb_uart->rx_stream); + furi_stream_buffer_reset(usb_uart->rx_stream); } } } @@ -270,7 +267,7 @@ static int32_t usb_uart_worker(void* context) { furi_thread_join(usb_uart->tx_thread); furi_thread_free(usb_uart->tx_thread); - vStreamBufferDelete(usb_uart->rx_stream); + furi_stream_buffer_free(usb_uart->rx_stream); furi_mutex_free(usb_uart->usb_mutex); furi_semaphore_free(usb_uart->tx_sem); diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index c6e196fb6..7fa0f4546 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -194,23 +193,21 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { typedef struct { volatile bool overrun; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; size_t packet_count; } SubGhzCliCommandRx; static void subghz_cli_command_rx_capture_callback(bool level, uint32_t duration, void* context) { SubGhzCliCommandRx* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; LevelDuration level_duration = level_duration_make(level, duration); if(instance->overrun) { instance->overrun = false; level_duration = level_duration_reset(); } - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); if(sizeof(LevelDuration) != ret) instance->overrun = true; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } static void subghz_cli_command_rx_callback( @@ -249,7 +246,8 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { // Allocate context and buffers SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx)); - instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); + instance->stream = + furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); furi_check(instance->stream); SubGhzEnvironment* environment = subghz_environment_alloc(); @@ -279,8 +277,8 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { printf("Listening at %lu. Press CTRL+C to stop\r\n", frequency); LevelDuration level_duration; while(!cli_cmd_interrupt_received(cli)) { - int ret = - xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 10); + int ret = furi_stream_buffer_receive( + instance->stream, &level_duration, sizeof(LevelDuration), 10); if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { printf("."); @@ -304,7 +302,7 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { // Cleanup subghz_receiver_free(receiver); subghz_environment_free(environment); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); free(instance); } diff --git a/applications/services/cli/cli_commands.c b/applications/services/cli/cli_commands.c index cee2ca98c..239434b7a 100644 --- a/applications/services/cli/cli_commands.c +++ b/applications/services/cli/cli_commands.c @@ -7,7 +7,6 @@ #include #include #include -#include // Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'` #define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d" @@ -140,7 +139,7 @@ void cli_command_date(Cli* cli, FuriString* args, void* context) { #define CLI_COMMAND_LOG_BUFFER_SIZE 64 void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* context) { - xStreamBufferSend(context, buffer, size, 0); + furi_stream_buffer_send(context, buffer, size, 0); } void cli_command_log_level_set_from_string(FuriString* level) { @@ -165,7 +164,7 @@ void cli_command_log_level_set_from_string(FuriString* level) { void cli_command_log(Cli* cli, FuriString* args, void* context) { UNUSED(context); - StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1); + FuriStreamBuffer* ring = furi_stream_buffer_alloc(CLI_COMMAND_LOG_RING_SIZE, 1); uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE]; FuriLogLevel previous_level = furi_log_get_level(); bool restore_log_level = false; @@ -179,7 +178,7 @@ void cli_command_log(Cli* cli, FuriString* args, void* context) { printf("Press CTRL+C to stop...\r\n"); while(!cli_cmd_interrupt_received(cli)) { - size_t ret = xStreamBufferReceive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50); + size_t ret = furi_stream_buffer_receive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50); cli_write(cli, buffer, ret); } @@ -190,7 +189,7 @@ void cli_command_log(Cli* cli, FuriString* args, void* context) { furi_log_set_level(previous_level); } - vStreamBufferDelete(ring); + furi_stream_buffer_free(ring); } void cli_command_vibro(Cli* cli, FuriString* args, void* context) { diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index f2893a48b..1e27e185b 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "cli_i.h" #define TAG "CliVcp" @@ -29,8 +28,8 @@ typedef enum { typedef struct { FuriThread* thread; - StreamBufferHandle_t tx_stream; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* tx_stream; + FuriStreamBuffer* rx_stream; volatile bool connected; volatile bool running; @@ -62,8 +61,8 @@ static const uint8_t ascii_eot = 0x04; static void cli_vcp_init() { if(vcp == NULL) { vcp = malloc(sizeof(CliVcp)); - vcp->tx_stream = xStreamBufferCreate(VCP_TX_BUF_SIZE, 1); - vcp->rx_stream = xStreamBufferCreate(VCP_RX_BUF_SIZE, 1); + vcp->tx_stream = furi_stream_buffer_alloc(VCP_TX_BUF_SIZE, 1); + vcp->rx_stream = furi_stream_buffer_alloc(VCP_RX_BUF_SIZE, 1); } furi_assert(vcp->thread == NULL); @@ -113,7 +112,7 @@ static int32_t vcp_worker(void* context) { #endif if(vcp->connected == false) { vcp->connected = true; - xStreamBufferSend(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); + furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); } } @@ -124,8 +123,8 @@ static int32_t vcp_worker(void* context) { #endif if(vcp->connected == true) { vcp->connected = false; - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); - xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); } } @@ -134,7 +133,7 @@ static int32_t vcp_worker(void* context) { #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "StreamRx"); #endif - if(xStreamBufferSpacesAvailable(vcp->rx_stream) >= USB_CDC_PKT_LEN) { + if(furi_stream_buffer_spaces_available(vcp->rx_stream) >= USB_CDC_PKT_LEN) { flags |= VcpEvtRx; missed_rx--; } @@ -142,14 +141,15 @@ static int32_t vcp_worker(void* context) { // New data received if(flags & VcpEvtRx) { - if(xStreamBufferSpacesAvailable(vcp->rx_stream) >= USB_CDC_PKT_LEN) { + if(furi_stream_buffer_spaces_available(vcp->rx_stream) >= USB_CDC_PKT_LEN) { int32_t len = furi_hal_cdc_receive(VCP_IF_NUM, vcp->data_buffer, USB_CDC_PKT_LEN); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "Rx %d", len); #endif if(len > 0) { furi_check( - xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) == + furi_stream_buffer_send( + vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) == (size_t)len); } } else { @@ -173,7 +173,7 @@ static int32_t vcp_worker(void* context) { // CDC write transfer done if(flags & VcpEvtTx) { size_t len = - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "Tx %d", len); #endif @@ -202,8 +202,8 @@ static int32_t vcp_worker(void* context) { furi_hal_usb_unlock(); furi_hal_usb_set_config(vcp->usb_if_prev, NULL); } - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); - xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); break; } } @@ -229,7 +229,7 @@ static size_t cli_vcp_rx(uint8_t* buffer, size_t size, uint32_t timeout) { size_t batch_size = size; if(batch_size > VCP_RX_BUF_SIZE) batch_size = VCP_RX_BUF_SIZE; - size_t len = xStreamBufferReceive(vcp->rx_stream, buffer, batch_size, timeout); + size_t len = furi_stream_buffer_receive(vcp->rx_stream, buffer, batch_size, timeout); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "rx %u ", batch_size); #endif @@ -262,7 +262,7 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) { size_t batch_size = size; if(batch_size > USB_CDC_PKT_LEN) batch_size = USB_CDC_PKT_LEN; - xStreamBufferSend(vcp->tx_stream, buffer, batch_size, FuriWaitForever); + furi_stream_buffer_send(vcp->tx_stream, buffer, batch_size, FuriWaitForever); furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamTx); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "tx %u", batch_size); diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index 4e8c29b44..06c05173c 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #define TAG "RpcSrv" @@ -61,7 +60,7 @@ struct RpcSession { FuriThread* thread; RpcHandlerDict_t handlers; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; PB_Main* decoded_message; bool terminate; void** system_contexts; @@ -151,7 +150,7 @@ size_t furi_assert(encoded_bytes); furi_assert(size > 0); - size_t bytes_sent = xStreamBufferSend(session->stream, encoded_bytes, size, timeout); + size_t bytes_sent = furi_stream_buffer_send(session->stream, encoded_bytes, size, timeout); furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtNewData); @@ -160,7 +159,7 @@ size_t size_t rpc_session_get_available_size(RpcSession* session) { furi_assert(session); - return xStreamBufferSpacesAvailable(session->stream); + return furi_stream_buffer_spaces_available(session->stream); } bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { @@ -174,9 +173,9 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { size_t bytes_received = 0; while(1) { - bytes_received += - xStreamBufferReceive(session->stream, buf + bytes_received, count - bytes_received, 0); - if(xStreamBufferIsEmpty(session->stream)) { + bytes_received += furi_stream_buffer_receive( + session->stream, buf + bytes_received, count - bytes_received, 0); + if(furi_stream_buffer_is_empty(session->stream)) { if(session->buffer_is_empty_callback) { session->buffer_is_empty_callback(session->context); } @@ -190,7 +189,7 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { } else { flags = furi_thread_flags_wait(RPC_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever); if(flags & RpcEvtDisconnect) { - if(xStreamBufferIsEmpty(session->stream)) { + if(furi_stream_buffer_is_empty(session->stream)) { session->terminate = true; istream->bytes_left = 0; bytes_received = 0; @@ -279,7 +278,7 @@ static int32_t rpc_session_worker(void* context) { } if(message_decode_failed) { - xStreamBufferReset(session->stream); + furi_stream_buffer_reset(session->stream); if(!session->terminate) { /* Protobuf can't determine start and end of message. * Handle this by adding varint at beginning @@ -329,7 +328,7 @@ static void rpc_session_free_callback(FuriThreadState thread_state, void* contex free(session->system_contexts); free(session->decoded_message); RpcHandlerDict_clear(session->handlers); - vStreamBufferDelete(session->stream); + furi_stream_buffer_free(session->stream); furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); if(session->terminated_callback) { @@ -348,7 +347,7 @@ RpcSession* rpc_session_open(Rpc* rpc) { RpcSession* session = malloc(sizeof(RpcSession)); session->callbacks_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - session->stream = xStreamBufferCreate(RPC_BUFFER_SIZE, 1); + session->stream = furi_stream_buffer_alloc(RPC_BUFFER_SIZE, 1); session->rpc = rpc; session->terminate = false; session->decode_error = false; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 4e1704d06..03bad58e6 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,2.0,, +Version,+,2.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1342,6 +1342,16 @@ Function,+,furi_semaphore_alloc,FuriSemaphore*,"uint32_t, uint32_t" Function,+,furi_semaphore_free,void,FuriSemaphore* Function,+,furi_semaphore_get_count,uint32_t,FuriSemaphore* Function,+,furi_semaphore_release,FuriStatus,FuriSemaphore* +Function,+,furi_stream_buffer_alloc,FuriStreamBuffer*,"size_t, size_t" +Function,+,furi_stream_buffer_bytes_available,size_t,FuriStreamBuffer* +Function,+,furi_stream_buffer_free,void,FuriStreamBuffer* +Function,+,furi_stream_buffer_is_empty,_Bool,FuriStreamBuffer* +Function,+,furi_stream_buffer_is_full,_Bool,FuriStreamBuffer* +Function,+,furi_stream_buffer_receive,size_t,"FuriStreamBuffer*, void*, size_t, uint32_t" +Function,+,furi_stream_buffer_reset,FuriStatus,FuriStreamBuffer* +Function,+,furi_stream_buffer_send,size_t,"FuriStreamBuffer*, const void*, size_t, uint32_t" +Function,+,furi_stream_buffer_spaces_available,size_t,FuriStreamBuffer* +Function,+,furi_stream_set_trigger_level,_Bool,"FuriStreamBuffer*, size_t" Function,+,furi_string_alloc,FuriString*, Function,+,furi_string_alloc_move,FuriString*,FuriString* Function,+,furi_string_alloc_printf,FuriString*,"const char[], ..." diff --git a/furi/core/stream_buffer.c b/furi/core/stream_buffer.c new file mode 100644 index 000000000..b9d0629fe --- /dev/null +++ b/furi/core/stream_buffer.c @@ -0,0 +1,77 @@ +#include "base.h" +#include "stream_buffer.h" +#include "common_defines.h" +#include +#include + +FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level) { + return xStreamBufferCreate(size, trigger_level); +}; + +void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer) { + vStreamBufferDelete(stream_buffer); +}; + +bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level) { + return xStreamBufferSetTriggerLevel(stream_buffer, trigger_level) == pdTRUE; +}; + +size_t furi_stream_buffer_send( + FuriStreamBuffer* stream_buffer, + const void* data, + size_t length, + uint32_t timeout) { + size_t ret; + + if(FURI_IS_IRQ_MODE() != 0U) { + BaseType_t yield; + ret = xStreamBufferSendFromISR(stream_buffer, data, length, &yield); + portYIELD_FROM_ISR(yield); + } else { + ret = xStreamBufferSend(stream_buffer, data, length, timeout); + } + + return ret; +}; + +size_t furi_stream_buffer_receive( + FuriStreamBuffer* stream_buffer, + void* data, + size_t length, + uint32_t timeout) { + size_t ret; + + if(FURI_IS_IRQ_MODE() != 0U) { + BaseType_t yield; + ret = xStreamBufferReceiveFromISR(stream_buffer, data, length, &yield); + portYIELD_FROM_ISR(yield); + } else { + ret = xStreamBufferReceive(stream_buffer, data, length, timeout); + } + + return ret; +} + +size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer) { + return xStreamBufferBytesAvailable(stream_buffer); +}; + +size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer) { + return xStreamBufferSpacesAvailable(stream_buffer); +}; + +bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer) { + return xStreamBufferIsFull(stream_buffer) == pdTRUE; +}; + +bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer) { + return (xStreamBufferIsEmpty(stream_buffer) == pdTRUE); +}; + +FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer) { + if(xStreamBufferReset(stream_buffer) == pdPASS) { + return FuriStatusOk; + } else { + return FuriStatusError; + } +} \ No newline at end of file diff --git a/furi/core/stream_buffer.h b/furi/core/stream_buffer.h new file mode 100644 index 000000000..d07f7e60b --- /dev/null +++ b/furi/core/stream_buffer.h @@ -0,0 +1,152 @@ +/** + * @file stream_buffer.h + * Furi stream buffer primitive. + * + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Stream buffer implementation assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). + */ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void FuriStreamBuffer; + +/** + * @brief Allocate stream buffer instance. + * Stream buffer implementation assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). + * + * @param size The total number of bytes the stream buffer will be able to hold at any one time. + * @param trigger_level The number of bytes that must be in the stream buffer + * before a task that is blocked on the stream buffer to wait for data is moved out of the blocked state. + * @return The stream buffer instance. + */ +FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level); + +/** + * @brief Free stream buffer instance + * + * @param stream_buffer The stream buffer instance. + */ +void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer); + +/** + * @brief Set trigger level for stream buffer. + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. + * + * @param stream_buffer The stream buffer instance + * @param trigger_level The new trigger level for the stream buffer. + * @return true if trigger level can be be updated (new trigger level was less than or equal to the stream buffer's length). + * @return false if trigger level can't be be updated (new trigger level was greater than the stream buffer's length). + */ +bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level); + +/** + * @brief Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * Wakes up task waiting for data to become available if called from ISR. + * + * @param stream_buffer The stream buffer instance. + * @param data A pointer to the data that is to be copied into the stream buffer. + * @param length The maximum number of bytes to copy from data into the stream buffer. + * @param timeout The maximum amount of time the task should remain in the + * Blocked state to wait for space to become available if the stream buffer is full. + * Will return immediately if timeout is zero. + * Setting timeout to FuriWaitForever will cause the task to wait indefinitely. + * Ignored if called from ISR. + * @return The number of bytes actually written to the stream buffer. + */ +size_t furi_stream_buffer_send( + FuriStreamBuffer* stream_buffer, + const void* data, + size_t length, + uint32_t timeout); + +/** + * @brief Receives bytes from a stream buffer. + * Wakes up task waiting for space to become available if called from ISR. + * + * @param stream_buffer The stream buffer instance. + * @param data A pointer to the buffer into which the received bytes will be + * copied. + * @param length The length of the buffer pointed to by the data parameter. + * @param timeout The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is empty. + * Will return immediately if timeout is zero. + * Setting timeout to FuriWaitForever will cause the task to wait indefinitely. + * Ignored if called from ISR. + * @return The number of bytes read from the stream buffer, if any. + */ +size_t furi_stream_buffer_receive( + FuriStreamBuffer* stream_buffer, + void* data, + size_t length, + uint32_t timeout); + +/** + * @brief Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param stream_buffer The stream buffer instance. + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + */ +size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param stream_buffer The stream buffer instance. + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + */ +size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see if it is full. + * + * @param stream_buffer stream buffer instance. + * @return true if the stream buffer is full. + * @return false if the stream buffer is not full. + */ +bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see if it is empty. + * + * @param stream_buffer The stream buffer instance. + * @return true if the stream buffer is empty. + * @return false if the stream buffer is not empty. + */ +bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer); + +/** + * @brief Resets a stream buffer to its initial, empty, state. Any data that was + * in the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream buffer. + * + * @param stream_buffer The stream buffer instance. + * @return FuriStatusOk if the stream buffer is reset. + * @return FuriStatusError if there was a task blocked waiting to send to or read + * from the stream buffer then the stream buffer is not reset. + */ +FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/furi/furi.h b/furi/furi.h index 306c9b949..3ce834227 100644 --- a/furi/furi.h +++ b/furi/furi.h @@ -2,22 +2,23 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "core/check.h" +#include "core/common_defines.h" +#include "core/event_flag.h" +#include "core/kernel.h" +#include "core/log.h" +#include "core/memmgr.h" +#include "core/memmgr_heap.h" +#include "core/message_queue.h" +#include "core/mutex.h" +#include "core/pubsub.h" +#include "core/record.h" +#include "core/semaphore.h" +#include "core/thread.h" +#include "core/timer.h" +#include "core/valuemutex.h" +#include "core/string.h" +#include "core/stream_buffer.h" #include diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index 2b4e3cdbb..86b19114c 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -9,7 +9,6 @@ #include #include -#include #define INFRARED_WORKER_RX_TIMEOUT INFRARED_RAW_RX_TIMING_DELAY_US @@ -50,7 +49,7 @@ struct InfraredWorkerSignal { struct InfraredWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; InfraredWorkerSignal signal; InfraredWorkerState state; @@ -100,15 +99,13 @@ static void infrared_worker_rx_timeout_callback(void* context) { static void infrared_worker_rx_callback(void* context, bool level, uint32_t duration) { InfraredWorker* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; furi_assert(duration != 0); LevelDuration level_duration = level_duration_make(level, duration); - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); uint32_t events = (ret == sizeof(LevelDuration)) ? INFRARED_WORKER_RX_RECEIVED : INFRARED_WORKER_OVERRUN; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); uint32_t flags_set = furi_thread_flags_set(furi_thread_get_id(instance->thread), events); furi_check(flags_set & events); @@ -179,7 +176,7 @@ static int32_t infrared_worker_rx_thread(void* thread_context) { if(instance->signal.timings_cnt == 0) notification_message(instance->notification, &sequence_display_backlight_on); while(sizeof(LevelDuration) == - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream, &level_duration, sizeof(LevelDuration), 0)) { if(!instance->rx.overrun) { bool level = level_duration_get_level(level_duration); @@ -232,7 +229,7 @@ InfraredWorker* infrared_worker_alloc() { size_t buffer_size = MAX(sizeof(InfraredWorkerTiming) * (MAX_TIMINGS_AMOUNT + 1), sizeof(LevelDuration) * MAX_TIMINGS_AMOUNT); - instance->stream = xStreamBufferCreate(buffer_size, sizeof(InfraredWorkerTiming)); + instance->stream = furi_stream_buffer_alloc(buffer_size, sizeof(InfraredWorkerTiming)); instance->infrared_decoder = infrared_alloc_decoder(); instance->infrared_encoder = infrared_alloc_encoder(); instance->blink_enable = false; @@ -249,7 +246,7 @@ void infrared_worker_free(InfraredWorker* instance) { furi_record_close(RECORD_NOTIFICATION); infrared_free_decoder(instance->infrared_decoder); infrared_free_encoder(instance->infrared_encoder); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); free(instance); @@ -259,7 +256,7 @@ void infrared_worker_rx_start(InfraredWorker* instance) { furi_assert(instance); furi_assert(instance->state == InfraredWorkerStateIdle); - xStreamBufferSetTriggerLevel(instance->stream, sizeof(LevelDuration)); + furi_stream_set_trigger_level(instance->stream, sizeof(LevelDuration)); furi_thread_set_callback(instance->thread, infrared_worker_rx_thread); furi_thread_start(instance->thread); @@ -285,9 +282,9 @@ void infrared_worker_rx_stop(InfraredWorker* instance) { furi_thread_flags_set(furi_thread_get_id(instance->thread), INFRARED_WORKER_EXIT); furi_thread_join(instance->thread); - BaseType_t xReturn = xStreamBufferReset(instance->stream); - furi_assert(xReturn == pdPASS); - (void)xReturn; + FuriStatus status = furi_stream_buffer_reset(instance->stream); + furi_assert(status == FuriStatusOk); + (void)status; instance->state = InfraredWorkerStateIdle; } @@ -325,7 +322,7 @@ void infrared_worker_tx_start(InfraredWorker* instance) { furi_assert(instance->tx.get_signal_callback); // size have to be greater than api hal infrared async tx buffer size - xStreamBufferSetTriggerLevel(instance->stream, sizeof(InfraredWorkerTiming)); + furi_stream_set_trigger_level(instance->stream, sizeof(InfraredWorkerTiming)); furi_thread_set_callback(instance->thread, infrared_worker_tx_thread); @@ -358,7 +355,7 @@ static FuriHalInfraredTxGetDataState FuriHalInfraredTxGetDataState state; if(sizeof(InfraredWorkerTiming) == - xStreamBufferReceiveFromISR(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0)) { + furi_stream_buffer_receive(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0)) { *level = timing.level; *duration = timing.duration; state = timing.state; @@ -420,7 +417,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) { InfraredWorkerTiming timing; InfraredStatus status = InfraredStatusError; - while(!xStreamBufferIsFull(instance->stream) && !instance->tx.need_reinitialization && + while(!furi_stream_buffer_is_full(instance->stream) && !instance->tx.need_reinitialization && new_data_available) { if(instance->signal.decoded) { status = infrared_encode(instance->infrared_encoder, &timing.duration, &timing.level); @@ -454,7 +451,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) { furi_assert(0); } uint32_t written_size = - xStreamBufferSend(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0); + furi_stream_buffer_send(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0); furi_assert(sizeof(InfraredWorkerTiming) == written_size); (void)written_size; } @@ -564,10 +561,9 @@ void infrared_worker_tx_stop(InfraredWorker* instance) { furi_hal_infrared_async_tx_set_signal_sent_isr_callback(NULL, NULL); instance->signal.timings_cnt = 0; - BaseType_t xReturn = pdFAIL; - xReturn = xStreamBufferReset(instance->stream); - furi_assert(xReturn == pdPASS); - (void)xReturn; + FuriStatus status = furi_stream_buffer_reset(instance->stream); + furi_assert(status == FuriStatusOk); + (void)status; instance->state = InfraredWorkerStateIdle; } diff --git a/lib/lfrfid/lfrfid_raw_worker.c b/lib/lfrfid/lfrfid_raw_worker.c index b277bbd34..9bab77db1 100644 --- a/lib/lfrfid/lfrfid_raw_worker.c +++ b/lib/lfrfid/lfrfid_raw_worker.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "lfrfid_raw_worker.h" #include "lfrfid_raw_file.h" #include "tools/varint_pair.h" @@ -16,7 +15,7 @@ // emulate mode typedef struct { size_t overrun_count; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; } RfidEmulateCtx; typedef struct { @@ -126,20 +125,13 @@ void lfrfid_raw_worker_stop(LFRFIDRawWorker* worker) { static void lfrfid_raw_worker_capture(bool level, uint32_t duration, void* context) { LFRFIDRawWorkerReadData* ctx = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - bool need_to_send = varint_pair_pack(ctx->pair, level, duration); if(need_to_send) { buffer_stream_send_from_isr( - ctx->stream, - varint_pair_get_data(ctx->pair), - varint_pair_get_size(ctx->pair), - &xHigherPriorityTaskWoken); + ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair)); varint_pair_reset(ctx->pair); } - - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } static int32_t lfrfid_raw_read_worker_thread(void* thread_context) { @@ -236,7 +228,7 @@ static void rfid_emulate_dma_isr(bool half, void* context) { RfidEmulateCtx* ctx = context; uint32_t flag = half ? HalfTransfer : TransferComplete; - size_t len = xStreamBufferSendFromISR(ctx->stream, &flag, sizeof(uint32_t), pdFALSE); + size_t len = furi_stream_buffer_send(ctx->stream, &flag, sizeof(uint32_t), 0); if(len != sizeof(uint32_t)) { ctx->overrun_count++; } @@ -251,7 +243,7 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { Storage* storage = furi_record_open(RECORD_STORAGE); data->ctx.overrun_count = 0; - data->ctx.stream = xStreamBufferCreate(sizeof(uint32_t), sizeof(uint32_t)); + data->ctx.stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t)); LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage); @@ -287,7 +279,8 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { uint32_t flag = 0; while(true) { - size_t size = xStreamBufferReceive(data->ctx.stream, &flag, sizeof(uint32_t), 100); + size_t size = + furi_stream_buffer_receive(data->ctx.stream, &flag, sizeof(uint32_t), 100); if(size == sizeof(uint32_t)) { size_t start = 0; @@ -348,7 +341,7 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { FURI_LOG_E(TAG_EMULATE, "overruns: %lu", data->ctx.overrun_count); } - vStreamBufferDelete(data->ctx.stream); + furi_stream_buffer_free(data->ctx.stream); lfrfid_raw_file_free(file); furi_record_close(RECORD_STORAGE); free(data); diff --git a/lib/lfrfid/lfrfid_worker_modes.c b/lib/lfrfid/lfrfid_worker_modes.c index 564470576..1fbae04c8 100644 --- a/lib/lfrfid/lfrfid_worker_modes.c +++ b/lib/lfrfid/lfrfid_worker_modes.c @@ -2,7 +2,6 @@ #include #include "lfrfid_worker_i.h" #include "tools/t5577.h" -#include #include #include #include "tools/varint_pair.h" @@ -81,17 +80,12 @@ static void lfrfid_worker_read_capture(bool level, uint32_t duration, void* cont furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, level); #endif - BaseType_t xHigherPriorityTaskWoken = pdFALSE; bool need_to_send = varint_pair_pack(ctx->pair, level, duration); if(need_to_send) { buffer_stream_send_from_isr( - ctx->stream, - varint_pair_get_data(ctx->pair), - varint_pair_get_size(ctx->pair), - &xHigherPriorityTaskWoken); + ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair)); varint_pair_reset(ctx->pair); } - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } typedef enum { @@ -407,14 +401,14 @@ typedef enum { } LFRFIDWorkerEmulateDMAEvent; static void lfrfid_worker_emulate_dma_isr(bool half, void* context) { - StreamBufferHandle_t stream = context; + FuriStreamBuffer* stream = context; uint32_t flag = half ? HalfTransfer : TransferComplete; - xStreamBufferSendFromISR(stream, &flag, sizeof(uint32_t), pdFALSE); + furi_stream_buffer_send(stream, &flag, sizeof(uint32_t), 0); } static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { LFRFIDWorkerEmulateBuffer* buffer = malloc(sizeof(LFRFIDWorkerEmulateBuffer)); - StreamBufferHandle_t stream = xStreamBufferCreate(sizeof(uint32_t), sizeof(uint32_t)); + FuriStreamBuffer* stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t)); LFRFIDProtocol protocol = worker->protocol; PulseGlue* pulse_glue = pulse_glue_alloc(); @@ -449,7 +443,7 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { while(true) { uint32_t flag = 0; - size_t size = xStreamBufferReceive(stream, &flag, sizeof(uint32_t), 100); + size_t size = furi_stream_buffer_receive(stream, &flag, sizeof(uint32_t), 100); #ifdef LFRFID_WORKER_READ_DEBUG_GPIO furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, true); @@ -497,7 +491,7 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { #endif free(buffer); - vStreamBufferDelete(stream); + furi_stream_buffer_free(stream); pulse_glue_free(pulse_glue); } diff --git a/lib/nfc/helpers/reader_analyzer.c b/lib/nfc/helpers/reader_analyzer.c index 680b8cef9..0ba657a2e 100644 --- a/lib/nfc/helpers/reader_analyzer.c +++ b/lib/nfc/helpers/reader_analyzer.c @@ -1,5 +1,4 @@ #include "reader_analyzer.h" -#include #include #include #include @@ -26,7 +25,7 @@ struct ReaderAnalyzer { FuriHalNfcDevData nfc_data; bool alive; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; FuriThread* thread; ReaderAnalyzerParseDataCallback callback; @@ -86,8 +85,8 @@ int32_t reader_analyzer_thread(void* context) { ReaderAnalyzer* reader_analyzer = context; uint8_t buffer[READER_ANALYZER_MAX_BUFF_SIZE] = {}; - while(reader_analyzer->alive || !xStreamBufferIsEmpty(reader_analyzer->stream)) { - size_t ret = xStreamBufferReceive( + while(reader_analyzer->alive || !furi_stream_buffer_is_empty(reader_analyzer->stream)) { + size_t ret = furi_stream_buffer_receive( reader_analyzer->stream, buffer, READER_ANALYZER_MAX_BUFF_SIZE, 50); if(ret) { reader_analyzer_parse(reader_analyzer, buffer, ret); @@ -103,7 +102,7 @@ ReaderAnalyzer* reader_analyzer_alloc() { instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic]; instance->alive = false; instance->stream = - xStreamBufferCreate(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader)); + furi_stream_buffer_alloc(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader)); instance->thread = furi_thread_alloc(); furi_thread_set_name(instance->thread, "ReaderAnalyzerWorker"); @@ -129,7 +128,7 @@ static void reader_analyzer_mfkey_callback(Mfkey32Event event, void* context) { void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode) { furi_assert(instance); - xStreamBufferReset(instance->stream); + furi_stream_buffer_reset(instance->stream); if(mode & ReaderAnalyzerModeDebugLog) { instance->debug_log = nfc_debug_log_alloc(); } @@ -171,7 +170,7 @@ void reader_analyzer_free(ReaderAnalyzer* instance) { reader_analyzer_stop(instance); furi_thread_free(instance->thread); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); free(instance); } @@ -215,12 +214,12 @@ static void reader_analyzer_write( ReaderAnalyzerHeader header = { .reader_to_tag = reader_to_tag, .crc_dropped = crc_dropped, .len = len}; size_t data_sent = 0; - data_sent = xStreamBufferSend( + data_sent = furi_stream_buffer_send( instance->stream, &header, sizeof(ReaderAnalyzerHeader), FuriWaitForever); if(data_sent != sizeof(ReaderAnalyzerHeader)) { FURI_LOG_W(TAG, "Sent %d out of %d bytes", data_sent, sizeof(ReaderAnalyzerHeader)); } - data_sent = xStreamBufferSend(instance->stream, data, len, FuriWaitForever); + data_sent = furi_stream_buffer_send(instance->stream, data, len, FuriWaitForever); if(data_sent != len) { FURI_LOG_W(TAG, "Sent %d out of %d bytes", data_sent, len); } diff --git a/lib/one_wire/ibutton/ibutton_worker_modes.c b/lib/one_wire/ibutton/ibutton_worker_modes.c index d585e27f4..691aea9ee 100644 --- a/lib/one_wire/ibutton/ibutton_worker_modes.c +++ b/lib/one_wire/ibutton/ibutton_worker_modes.c @@ -2,7 +2,6 @@ #include #include "ibutton_worker_i.h" #include "ibutton_key_command.h" -#include void ibutton_worker_mode_idle_start(iButtonWorker* worker); void ibutton_worker_mode_idle_tick(iButtonWorker* worker); @@ -65,7 +64,7 @@ void ibutton_worker_mode_idle_stop(iButtonWorker* worker) { typedef struct { uint32_t last_dwt_value; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; } iButtonReadContext; void ibutton_worker_comparator_callback(bool level, void* context) { @@ -75,7 +74,7 @@ void ibutton_worker_comparator_callback(bool level, void* context) { LevelDuration data = level_duration_make(level, current_dwt_value - read_context->last_dwt_value); - xStreamBufferSend(read_context->stream, &data, sizeof(LevelDuration), 0); + furi_stream_buffer_send(read_context->stream, &data, sizeof(LevelDuration), 0); read_context->last_dwt_value = current_dwt_value; } @@ -91,7 +90,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { iButtonReadContext read_context = { .last_dwt_value = DWT->CYCCNT, - .stream = xStreamBufferCreate(sizeof(LevelDuration) * 512, 1), + .stream = furi_stream_buffer_alloc(sizeof(LevelDuration) * 512, 1), }; furi_hal_rfid_comp_set_callback(ibutton_worker_comparator_callback, &read_context); @@ -100,7 +99,8 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { uint32_t tick_start = furi_get_tick(); while(true) { LevelDuration level; - size_t ret = xStreamBufferReceive(read_context.stream, &level, sizeof(LevelDuration), 100); + size_t ret = + furi_stream_buffer_receive(read_context.stream, &level, sizeof(LevelDuration), 100); if((furi_get_tick() - tick_start) > 100) { break; @@ -141,7 +141,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { furi_hal_rfid_comp_set_callback(NULL, NULL); furi_hal_rfid_pins_reset(); - vStreamBufferDelete(read_context.stream); + furi_stream_buffer_free(read_context.stream); return result; } diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index 1b8e99f19..29834b412 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -1,5 +1,4 @@ #include "subghz_file_encoder_worker.h" -#include #include #include @@ -11,7 +10,7 @@ struct SubGhzFileEncoderWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; Storage* storage; FlipperFormat* flipper_format; @@ -48,7 +47,7 @@ void subghz_file_encoder_worker_add_level_duration( if(res) { instance->level = !instance->level; - xStreamBufferSend(instance->stream, &duration, sizeof(int32_t), 100); + furi_stream_buffer_send(instance->stream, &duration, sizeof(int32_t), 100); } else { FURI_LOG_E(TAG, "Invalid level in the stream"); } @@ -83,10 +82,7 @@ LevelDuration subghz_file_encoder_worker_get_level_duration(void* context) { furi_assert(context); SubGhzFileEncoderWorker* instance = context; int32_t duration; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - int ret = xStreamBufferReceiveFromISR( - instance->stream, &duration, sizeof(int32_t), &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + int ret = furi_stream_buffer_receive(instance->stream, &duration, sizeof(int32_t), 0); if(ret == sizeof(int32_t)) { LevelDuration level_duration = {.level = LEVEL_DURATION_RESET}; if(duration < 0) { @@ -137,7 +133,7 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { } while(0); while(res && instance->worker_running) { - size_t stream_free_byte = xStreamBufferSpacesAvailable(instance->stream); + size_t stream_free_byte = furi_stream_buffer_spaces_available(instance->stream); if((stream_free_byte / sizeof(int32_t)) >= SUBGHZ_FILE_ENCODER_LOAD) { if(stream_read_line(stream, instance->str_data)) { furi_string_trim(instance->str_data); @@ -183,7 +179,7 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { furi_thread_set_stack_size(instance->thread, 2048); furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_file_encoder_worker_thread); - instance->stream = xStreamBufferCreate(sizeof(int32_t) * 2048, sizeof(int32_t)); + instance->stream = furi_stream_buffer_alloc(sizeof(int32_t) * 2048, sizeof(int32_t)); instance->storage = furi_record_open(RECORD_STORAGE); instance->flipper_format = flipper_format_file_alloc(instance->storage); @@ -199,7 +195,7 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { void subghz_file_encoder_worker_free(SubGhzFileEncoderWorker* instance) { furi_assert(instance); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); furi_string_free(instance->str_data); @@ -215,7 +211,7 @@ bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const c furi_assert(instance); furi_assert(!instance->worker_running); - xStreamBufferReset(instance->stream); + furi_stream_buffer_reset(instance->stream); furi_string_set(instance->file_path, file_path); instance->worker_running = true; furi_thread_start(instance->thread); diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c index 78a186931..37c0bfc5e 100644 --- a/lib/subghz/subghz_tx_rx_worker.c +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -1,6 +1,5 @@ #include "subghz_tx_rx_worker.h" -#include #include #define TAG "SubGhzTxRxWorker" @@ -13,8 +12,8 @@ struct SubGhzTxRxWorker { FuriThread* thread; - StreamBufferHandle_t stream_tx; - StreamBufferHandle_t stream_rx; + FuriStreamBuffer* stream_tx; + FuriStreamBuffer* stream_rx; volatile bool worker_running; volatile bool worker_stoping; @@ -30,9 +29,9 @@ struct SubGhzTxRxWorker { bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { furi_assert(instance); bool ret = false; - size_t stream_tx_free_byte = xStreamBufferSpacesAvailable(instance->stream_tx); + size_t stream_tx_free_byte = furi_stream_buffer_spaces_available(instance->stream_tx); if(size && (stream_tx_free_byte >= size)) { - if(xStreamBufferSend( + if(furi_stream_buffer_send( instance->stream_tx, data, size, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) == size) { ret = true; @@ -43,12 +42,12 @@ bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size_t subghz_tx_rx_worker_available(SubGhzTxRxWorker* instance) { furi_assert(instance); - return xStreamBufferBytesAvailable(instance->stream_rx); + return furi_stream_buffer_bytes_available(instance->stream_rx); } size_t subghz_tx_rx_worker_read(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { furi_assert(instance); - return xStreamBufferReceive(instance->stream_rx, data, size, 0); + return furi_stream_buffer_receive(instance->stream_rx, data, size, 0); } void subghz_tx_rx_worker_set_callback_have_read( @@ -148,11 +147,11 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { while(instance->worker_running) { //transmit - size_tx = xStreamBufferBytesAvailable(instance->stream_tx); + size_tx = furi_stream_buffer_bytes_available(instance->stream_tx); if(size_tx > 0 && !timeout_tx) { timeout_tx = 10; //20ms if(size_tx > SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE) { - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream_tx, &data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE, @@ -160,20 +159,20 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { subghz_tx_rx_worker_tx(instance, data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); } else { //todo checking that he managed to write all the data to the TX buffer - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream_tx, &data, size_tx, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); subghz_tx_rx_worker_tx(instance, data, size_tx); } } else { //recive if(subghz_tx_rx_worker_rx(instance, data, size_rx)) { - if(xStreamBufferSpacesAvailable(instance->stream_rx) >= size_rx[0]) { + if(furi_stream_buffer_spaces_available(instance->stream_rx) >= size_rx[0]) { if(instance->callback_have_read && - xStreamBufferBytesAvailable(instance->stream_rx) == 0) { + furi_stream_buffer_bytes_available(instance->stream_rx) == 0) { callback_rx = true; } //todo checking that he managed to write all the data to the RX buffer - xStreamBufferSend( + furi_stream_buffer_send( instance->stream_rx, &data, size_rx[0], @@ -208,9 +207,9 @@ SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_tx_rx_worker_thread); instance->stream_tx = - xStreamBufferCreate(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); instance->stream_rx = - xStreamBufferCreate(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); instance->status = SubGhzTxRxWorkerStatusIDLE; instance->worker_stoping = true; @@ -221,8 +220,8 @@ SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance) { furi_assert(instance); furi_assert(!instance->worker_running); - vStreamBufferDelete(instance->stream_tx); - vStreamBufferDelete(instance->stream_rx); + furi_stream_buffer_free(instance->stream_tx); + furi_stream_buffer_free(instance->stream_rx); furi_thread_free(instance->thread); free(instance); @@ -232,8 +231,8 @@ bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency) { furi_assert(instance); furi_assert(!instance->worker_running); bool res = false; - xStreamBufferReset(instance->stream_tx); - xStreamBufferReset(instance->stream_rx); + furi_stream_buffer_reset(instance->stream_tx); + furi_stream_buffer_reset(instance->stream_rx); instance->worker_running = true; diff --git a/lib/subghz/subghz_worker.c b/lib/subghz/subghz_worker.c index 58db8ea5d..61146c168 100644 --- a/lib/subghz/subghz_worker.c +++ b/lib/subghz/subghz_worker.c @@ -1,13 +1,12 @@ #include "subghz_worker.h" -#include #include #define TAG "SubGhzWorker" struct SubGhzWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; volatile bool running; volatile bool overrun; @@ -30,16 +29,14 @@ struct SubGhzWorker { void subghz_worker_rx_callback(bool level, uint32_t duration, void* context) { SubGhzWorker* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; LevelDuration level_duration = level_duration_make(level, duration); if(instance->overrun) { instance->overrun = false; level_duration = level_duration_reset(); } - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); if(sizeof(LevelDuration) != ret) instance->overrun = true; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /** Worker callback thread @@ -52,8 +49,8 @@ static int32_t subghz_worker_thread_callback(void* context) { LevelDuration level_duration; while(instance->running) { - int ret = - xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 10); + int ret = furi_stream_buffer_receive( + instance->stream, &level_duration, sizeof(LevelDuration), 10); if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { FURI_LOG_E(TAG, "Overrun buffer"); @@ -97,7 +94,8 @@ SubGhzWorker* subghz_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_worker_thread_callback); - instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); + instance->stream = + furi_stream_buffer_alloc(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); //setting filter instance->filter_running = true; @@ -109,7 +107,7 @@ SubGhzWorker* subghz_worker_alloc() { void subghz_worker_free(SubGhzWorker* instance) { furi_assert(instance); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); free(instance); diff --git a/lib/toolbox/buffer_stream.c b/lib/toolbox/buffer_stream.c index 66d210963..37b2514ef 100644 --- a/lib/toolbox/buffer_stream.c +++ b/lib/toolbox/buffer_stream.c @@ -1,5 +1,4 @@ #include "buffer_stream.h" -#include struct Buffer { volatile bool occupied; @@ -10,7 +9,7 @@ struct Buffer { struct BufferStream { size_t stream_overrun_count; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; size_t index; Buffer* buffers; @@ -54,7 +53,7 @@ BufferStream* buffer_stream_alloc(size_t buffer_size, size_t buffers_count) { buffer_stream->buffers[i].data = malloc(buffer_size); buffer_stream->buffers[i].max_data_size = buffer_size; } - buffer_stream->stream = xStreamBufferCreate( + buffer_stream->stream = furi_stream_buffer_alloc( sizeof(BufferStream*) * buffer_stream->max_buffers_count, sizeof(BufferStream*)); buffer_stream->stream_overrun_count = 0; buffer_stream->index = 0; @@ -66,7 +65,7 @@ void buffer_stream_free(BufferStream* buffer_stream) { for(size_t i = 0; i < buffer_stream->max_buffers_count; i++) { free(buffer_stream->buffers[i].data); } - vStreamBufferDelete(buffer_stream->stream); + furi_stream_buffer_free(buffer_stream->stream); free(buffer_stream->buffers); free(buffer_stream); } @@ -83,11 +82,7 @@ static inline int8_t buffer_stream_get_free_buffer(BufferStream* buffer_stream) return id; } -bool buffer_stream_send_from_isr( - BufferStream* buffer_stream, - const uint8_t* data, - size_t size, - BaseType_t* const task_woken) { +bool buffer_stream_send_from_isr(BufferStream* buffer_stream, const uint8_t* data, size_t size) { Buffer* buffer = &buffer_stream->buffers[buffer_stream->index]; bool result = true; @@ -96,7 +91,7 @@ bool buffer_stream_send_from_isr( // if buffer is full - send it buffer->occupied = true; // we always have space for buffer in stream - xStreamBufferSendFromISR(buffer_stream->stream, &buffer, sizeof(Buffer*), task_woken); + furi_stream_buffer_send(buffer_stream->stream, &buffer, sizeof(Buffer*), 0); // get new buffer from the pool int8_t index = buffer_stream_get_free_buffer(buffer_stream); @@ -119,7 +114,8 @@ bool buffer_stream_send_from_isr( Buffer* buffer_stream_receive(BufferStream* buffer_stream, TickType_t timeout) { Buffer* buffer; - size_t size = xStreamBufferReceive(buffer_stream->stream, &buffer, sizeof(Buffer*), timeout); + size_t size = + furi_stream_buffer_receive(buffer_stream->stream, &buffer, sizeof(Buffer*), timeout); if(size == sizeof(Buffer*)) { return buffer; @@ -134,9 +130,8 @@ size_t buffer_stream_get_overrun_count(BufferStream* buffer_stream) { void buffer_stream_reset(BufferStream* buffer_stream) { FURI_CRITICAL_ENTER(); - BaseType_t xReturn = xStreamBufferReset(buffer_stream->stream); - furi_assert(xReturn == pdPASS); - UNUSED(xReturn); + furi_stream_buffer_reset(buffer_stream->stream); + buffer_stream->stream_overrun_count = 0; for(size_t i = 0; i < buffer_stream->max_buffers_count; i++) { buffer_reset(&buffer_stream->buffers[i]); diff --git a/lib/toolbox/buffer_stream.h b/lib/toolbox/buffer_stream.h index d4c3cddf7..9db547753 100644 --- a/lib/toolbox/buffer_stream.h +++ b/lib/toolbox/buffer_stream.h @@ -59,14 +59,9 @@ void buffer_stream_free(BufferStream* buffer_stream); * @param buffer_stream * @param data * @param size - * @param task_woken * @return bool */ -bool buffer_stream_send_from_isr( - BufferStream* buffer_stream, - const uint8_t* data, - size_t size, - BaseType_t* const task_woken); +bool buffer_stream_send_from_isr(BufferStream* buffer_stream, const uint8_t* data, size_t size); /** * @brief Receive buffer from stream From 1f742b611a793e4b17d7036541ba48557cb5e766 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Fri, 7 Oct 2022 15:46:58 +0300 Subject: [PATCH 4/6] [FL-2651, FL-2863] App name in CLI loader command, RFID data edit fix #1835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/main/gpio/views/gpio_usb_uart.c | 4 +-- .../lfrfid/scenes/lfrfid_scene_save_data.c | 9 +++-- .../lfrfid/scenes/lfrfid_scene_save_success.c | 3 ++ applications/services/loader/loader.c | 33 +++++++++++++++++-- applications/services/storage/storage_cli.c | 6 ++-- .../storage_settings_scene_internal_info.c | 2 +- .../scenes/storage_settings_scene_sd_info.c | 2 +- 7 files changed, 44 insertions(+), 15 deletions(-) diff --git a/applications/main/gpio/views/gpio_usb_uart.c b/applications/main/gpio/views/gpio_usb_uart.c index d2d371b68..d190ecab0 100644 --- a/applications/main/gpio/views/gpio_usb_uart.c +++ b/applications/main/gpio/views/gpio_usb_uart.c @@ -54,7 +54,7 @@ static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 116, 24, AlignRight, AlignBottom, temp_str); } else { canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KB."); + canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KiB."); canvas_set_font(canvas, FontKeyboard); snprintf(temp_str, 18, "%lu", model->tx_cnt / 1024); canvas_draw_str_aligned(canvas, 111, 24, AlignRight, AlignBottom, temp_str); @@ -68,7 +68,7 @@ static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 116, 41, AlignRight, AlignBottom, temp_str); } else { canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KB."); + canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KiB."); canvas_set_font(canvas, FontKeyboard); snprintf(temp_str, 18, "%lu", model->rx_cnt / 1024); canvas_draw_str_aligned(canvas, 111, 41, AlignRight, AlignBottom, temp_str); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c index 2ca1bb433..6c5ea2f2d 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c @@ -9,14 +9,11 @@ void lfrfid_scene_save_data_on_enter(void* context) { bool need_restore = scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveData); - if(need_restore) { - protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size); - } else { + if(!need_restore) { protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size); + protocol_dict_get_data(app->dict, app->protocol_id, app->new_key_data, size); } - protocol_dict_get_data(app->dict, app->protocol_id, app->new_key_data, size); - byte_input_set_header_text(byte_input, "Enter the data in hex"); byte_input_set_result_callback( @@ -41,6 +38,8 @@ bool lfrfid_scene_save_data_on_event(void* context, SceneManagerEvent event) { } } else if(event.type == SceneManagerEventTypeBack) { scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 0); + size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); + protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size); } return consumed; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c index 830ef3368..e91ad04e3 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c @@ -5,6 +5,9 @@ void lfrfid_scene_save_success_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; + // Clear state of data enter scene + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveData, 0); + DOLPHIN_DEED(DolphinDeedRfidSave); popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index 51cddec70..bc456536c 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -61,6 +61,7 @@ static void loader_cli_print_usage() { printf("Cmd list:\r\n"); printf("\tlist\t - List available applications\r\n"); printf("\topen \t - Open application by name\r\n"); + printf("\tinfo\t - Show loader state\r\n"); } static FlipperApplication const* loader_find_application_by_name_in_list( @@ -98,10 +99,15 @@ const FlipperApplication* loader_find_application_by_name(const char* name) { return application; } -void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { +static void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); if(loader_is_locked(instance)) { - printf("Can't start, furi application is running"); + if(instance->application) { + furi_assert(instance->application->name); + printf("Can't start, %s application is running", instance->application->name); + } else { + printf("Can't start, furi application is running"); + } return; } @@ -137,7 +143,7 @@ void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { furi_string_free(application_name); } -void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) { +static void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); UNUSED(args); UNUSED(instance); @@ -159,6 +165,22 @@ void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) { } } +static void loader_cli_info(Cli* cli, FuriString* args, Loader* instance) { + UNUSED(cli); + UNUSED(args); + if(!loader_is_locked(instance)) { + printf("No application is running\r\n"); + } else { + printf("Running application: "); + if(instance->application) { + furi_assert(instance->application->name); + printf("%s\r\n", instance->application->name); + } else { + printf("unknown\r\n"); + } + } +} + static void loader_cli(Cli* cli, FuriString* args, void* _ctx) { furi_assert(_ctx); Loader* instance = _ctx; @@ -182,6 +204,11 @@ static void loader_cli(Cli* cli, FuriString* args, void* _ctx) { break; } + if(furi_string_cmp_str(cmd, "info") == 0) { + loader_cli_info(cli, args, instance); + break; + } + loader_cli_print_usage(); } while(false); diff --git a/applications/services/storage/storage_cli.c b/applications/services/storage/storage_cli.c index 5e72dce8e..880fb9700 100644 --- a/applications/services/storage/storage_cli.c +++ b/applications/services/storage/storage_cli.c @@ -52,7 +52,7 @@ static void storage_cli_info(Cli* cli, FuriString* path) { storage_cli_print_error(error); } else { printf( - "Label: %s\r\nType: LittleFS\r\n%luKB total\r\n%luKB free\r\n", + "Label: %s\r\nType: LittleFS\r\n%luKiB total\r\n%luKiB free\r\n", furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); @@ -65,7 +65,7 @@ static void storage_cli_info(Cli* cli, FuriString* path) { storage_cli_print_error(error); } else { printf( - "Label: %s\r\nType: %s\r\n%luKB total\r\n%luKB free\r\n", + "Label: %s\r\nType: %s\r\n%luKiB total\r\n%luKiB free\r\n", sd_info.label, sd_api_get_fs_type_text(sd_info.fs_type), sd_info.kb_total, @@ -364,7 +364,7 @@ static void storage_cli_stat(Cli* cli, FuriString* path) { storage_cli_print_error(error); } else { printf( - "Storage, %luKB total, %luKB free\r\n", + "Storage, %luKiB total, %luKiB free\r\n", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c b/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c index d2d4ecd8a..f205efc0a 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c @@ -27,7 +27,7 @@ void storage_settings_scene_internal_info_on_enter(void* context) { } else { furi_string_printf( app->text_string, - "Label: %s\nType: LittleFS\n%lu KB total\n%lu KB free", + "Label: %s\nType: LittleFS\n%lu KiB total\n%lu KiB free", furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c b/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c index f5d286c7f..ede610d0e 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c @@ -26,7 +26,7 @@ void storage_settings_scene_sd_info_on_enter(void* context) { } else { furi_string_printf( app->text_string, - "Label: %s\nType: %s\n%lu KB total\n%lu KB free", + "Label: %s\nType: %s\n%lu KiB total\n%lu KiB free", sd_info.label, sd_api_get_fs_type_text(sd_info.fs_type), sd_info.kb_total, From 4000f0cac51fa32006c7737ea8c34494bf4003f2 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Fri, 7 Oct 2022 23:35:15 +1000 Subject: [PATCH 5/6] [FL-2870] Printf function attributes (#1841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Furi strings: printf attribute * Logs: printf attribute * Plugins: adapt * Plugins: accommodate * Unit tests: accommodate Co-authored-by: あく --- .../debug/unit_tests/infrared/infrared_test.c | 10 +++---- applications/debug/unit_tests/nfc/nfc_test.c | 10 +++---- .../main/archive/helpers/archive_favorites.h | 4 +-- .../main/archive/helpers/archive_files.h | 6 ++-- applications/main/bad_usb/bad_usb_script.c | 6 ++-- .../main/bad_usb/views/bad_usb_view.c | 2 +- .../main/fap_loader/elf_cpp/elf_hashtable.cpp | 2 +- applications/main/infrared/infrared.c | 4 +-- applications/main/infrared/infrared_signal.c | 4 +-- .../scenes/nfc_scene_mf_classic_keys_list.c | 2 +- .../nfc_scene_mf_desfire_read_success.c | 4 +-- .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 4 +-- .../subghz_frequency_analyzer_worker.c | 8 +++--- applications/main/subghz/subghz_cli.c | 6 ++-- applications/main/subghz/subghz_i.c | 2 +- .../music_player/music_player_worker.c | 6 ++-- applications/services/bt/bt_service/bt.c | 4 +-- .../desktop/animations/animation_storage.c | 4 +-- .../services/dolphin/helpers/dolphin_state.c | 2 +- applications/services/gui/gui.c | 6 ++-- .../gui/modules/file_browser_worker.c | 9 +++--- applications/services/gui/view_dispatcher.c | 4 +-- applications/services/rpc/rpc_app.c | 18 ++++++------ applications/services/rpc/rpc_cli.c | 2 +- applications/services/rpc/rpc_debug.c | 4 +-- .../services/storage/storage_external_api.c | 28 +++++++++++++++---- .../services/storage/storages/storage_int.c | 14 +++++----- .../updater/util/update_task_worker_flasher.c | 8 +++--- firmware/targets/f7/ble_glue/gap.c | 4 +-- firmware/targets/f7/ble_glue/serial_service.c | 4 +-- .../targets/f7/furi_hal/furi_hal_console.h | 3 +- firmware/targets/f7/furi_hal/furi_hal_flash.c | 6 ++-- .../targets/f7/furi_hal/furi_hal_memory.c | 4 +-- firmware/targets/f7/furi_hal/furi_hal_power.c | 6 ++-- .../targets/f7/furi_hal/furi_hal_subghz.c | 2 +- furi/core/log.h | 3 +- furi/core/string.h | 9 ++++-- lib/lfrfid/lfrfid_raw_worker.c | 2 +- lib/lfrfid/protocols/protocol_gallagher.c | 2 +- lib/lfrfid/protocols/protocol_keri.c | 2 +- lib/lfrfid/protocols/protocol_paradox.c | 2 +- lib/lfrfid/protocols/protocol_pyramid.c | 2 +- lib/nfc/helpers/mf_classic_dict.c | 2 +- lib/nfc/helpers/mfkey32.c | 2 +- lib/nfc/nfc_worker.c | 3 +- lib/nfc/parsers/all_in_one.c | 2 +- lib/nfc/parsers/plantain_4k_parser.c | 2 +- lib/nfc/parsers/plantain_parser.c | 2 +- lib/nfc/parsers/two_cities.c | 2 +- lib/nfc/protocols/mifare_classic.c | 4 +-- lib/nfc/protocols/mifare_desfire.c | 8 +++--- lib/nfc/protocols/mifare_ultralight.c | 4 +-- lib/print/printf_tiny.h | 11 +++++--- lib/subghz/protocols/came_atomo.c | 2 +- lib/subghz/protocols/came_twee.c | 2 +- lib/subghz/protocols/doitrand.c | 2 +- lib/subghz/protocols/faac_slh.c | 2 +- lib/subghz/protocols/gate_tx.c | 2 +- lib/subghz/protocols/honeywell_wdb.c | 2 +- lib/subghz/protocols/ido.c | 2 +- lib/subghz/protocols/keeloq.c | 4 +-- lib/subghz/protocols/kia.c | 2 +- lib/subghz/protocols/magellen.c | 2 +- lib/subghz/protocols/marantec.c | 2 +- lib/subghz/protocols/megacode.c | 4 +-- lib/subghz/protocols/nice_flor_s.c | 2 +- lib/subghz/protocols/oregon2.c | 4 +-- lib/subghz/protocols/phoenix_v2.c | 2 +- lib/subghz/protocols/princeton.c | 2 +- lib/subghz/protocols/princeton_for_testing.c | 2 +- lib/subghz/protocols/raw.c | 2 +- lib/subghz/protocols/scher_khan.c | 2 +- lib/subghz/protocols/secplus_v1.c | 4 +-- lib/subghz/protocols/secplus_v2.c | 2 +- lib/subghz/protocols/somfy_keytis.c | 2 +- lib/subghz/protocols/somfy_telis.c | 2 +- lib/subghz/protocols/star_line.c | 4 +-- lib/toolbox/stream/stream.h | 9 ++++-- 78 files changed, 187 insertions(+), 156 deletions(-) diff --git a/applications/debug/unit_tests/infrared/infrared_test.c b/applications/debug/unit_tests/infrared/infrared_test.c index d861f266e..8879c8fc8 100644 --- a/applications/debug/unit_tests/infrared/infrared_test.c +++ b/applications/debug/unit_tests/infrared/infrared_test.c @@ -221,13 +221,13 @@ static void infrared_test_run_encoder(InfraredProtocol protocol, uint32_t test_i const char* protocol_name = infrared_get_protocol_name(protocol); mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); - furi_string_printf(buf, "encoder_input%d", test_index); + furi_string_printf(buf, "encoder_input%ld", test_index); mu_assert( infrared_test_load_messages( test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count), "Failed to load messages from file"); - furi_string_printf(buf, "encoder_expected%d", test_index); + furi_string_printf(buf, "encoder_expected%ld", test_index); mu_assert( infrared_test_load_raw_signal( test->ff, furi_string_get_cstr(buf), &expected_timings, &expected_timings_count), @@ -277,7 +277,7 @@ static void infrared_test_run_encoder_decoder(InfraredProtocol protocol, uint32_ const char* protocol_name = infrared_get_protocol_name(protocol); mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); - furi_string_printf(buf, "encoder_decoder_input%d", test_index); + furi_string_printf(buf, "encoder_decoder_input%ld", test_index); mu_assert( infrared_test_load_messages( test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count), @@ -336,13 +336,13 @@ static void infrared_test_run_decoder(InfraredProtocol protocol, uint32_t test_i infrared_test_prepare_file(infrared_get_protocol_name(protocol)), "Failed to prepare test file"); - furi_string_printf(buf, "decoder_input%d", test_index); + furi_string_printf(buf, "decoder_input%ld", test_index); mu_assert( infrared_test_load_raw_signal( test->ff, furi_string_get_cstr(buf), &timings, &timings_count), "Failed to load raw signal from file"); - furi_string_printf(buf, "decoder_expected%d", test_index); + furi_string_printf(buf, "decoder_expected%ld", test_index); mu_assert( infrared_test_load_messages( test->ff, furi_string_get_cstr(buf), &messages, &messages_count), diff --git a/applications/debug/unit_tests/nfc/nfc_test.c b/applications/debug/unit_tests/nfc/nfc_test.c index c1468c86f..f149508b0 100644 --- a/applications/debug/unit_tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/nfc/nfc_test.c @@ -112,7 +112,7 @@ static bool nfc_test_digital_signal_test_encode( // Check timings if(time > encode_max_time) { FURI_LOG_E( - TAG, "Encoding time: %d us while accepted value: %d us", time, encode_max_time); + TAG, "Encoding time: %ld us while accepted value: %ld us", time, encode_max_time); break; } @@ -132,7 +132,7 @@ static bool nfc_test_digital_signal_test_encode( ref_timings_sum += ref[i]; if(timings_diff > timing_tolerance) { FURI_LOG_E( - TAG, "Too big differece in %d timings. Ref: %d, DUT: %d", i, ref[i], dut[i]); + TAG, "Too big differece in %d timings. Ref: %ld, DUT: %ld", i, ref[i], dut[i]); timing_check_success = false; break; } @@ -143,16 +143,16 @@ static bool nfc_test_digital_signal_test_encode( if(sum_diff > timings_sum_tolerance) { FURI_LOG_E( TAG, - "Too big difference in timings sum. Ref: %d, DUT: %d", + "Too big difference in timings sum. Ref: %ld, DUT: %ld", ref_timings_sum, dut_timings_sum); break; } - FURI_LOG_I(TAG, "Encoding time: %d us. Acceptable time: %d us", time, encode_max_time); + FURI_LOG_I(TAG, "Encoding time: %ld us. Acceptable time: %ld us", time, encode_max_time); FURI_LOG_I( TAG, - "Timings sum difference: %d [1/64MHZ]. Acceptable difference: %d [1/64MHz]", + "Timings sum difference: %ld [1/64MHZ]. Acceptable difference: %ld [1/64MHz]", sum_diff, timings_sum_tolerance); success = true; diff --git a/applications/main/archive/helpers/archive_favorites.h b/applications/main/archive/helpers/archive_favorites.h index 29eedcdb6..db8943378 100644 --- a/applications/main/archive/helpers/archive_favorites.h +++ b/applications/main/archive/helpers/archive_favorites.h @@ -7,8 +7,8 @@ uint16_t archive_favorites_count(void* context); bool archive_favorites_read(void* context); -bool archive_favorites_delete(const char* format, ...); -bool archive_is_favorite(const char* format, ...); +bool archive_favorites_delete(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); +bool archive_is_favorite(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); bool archive_favorites_rename(const char* src, const char* dst); void archive_add_to_favorites(const char* file_path); void archive_favorites_save(void* context); diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index 2017a9574..1822befa3 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -86,5 +86,7 @@ ARRAY_DEF( void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder, bool is_app); bool archive_get_items(void* context, const char* path); -void archive_file_append(const char* path, const char* format, ...); -void archive_delete_file(void* context, const char* format, ...); +void archive_file_append(const char* path, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); +void archive_delete_file(void* context, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); diff --git a/applications/main/bad_usb/bad_usb_script.c b/applications/main/bad_usb/bad_usb_script.c index 4166642bd..1e3edf40f 100644 --- a/applications/main/bad_usb/bad_usb_script.c +++ b/applications/main/bad_usb/bad_usb_script.c @@ -323,7 +323,7 @@ static bool ducky_set_usb_id(BadUsbScript* bad_usb, const char* line) { } FURI_LOG_D( WORKER_TAG, - "set id: %04X:%04X mfr:%s product:%s", + "set id: %04lX:%04lX mfr:%s product:%s", bad_usb->hid_cfg.vid, bad_usb->hid_cfg.pid, bad_usb->hid_cfg.manuf, @@ -388,7 +388,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil return 0; } else if(delay_val < 0) { // Script error bad_usb->st.error_line = bad_usb->st.line_cur - 1; - FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur - 1); + FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur - 1); return SCRIPT_STATE_ERROR; } else { return (delay_val + bad_usb->defdelay); @@ -420,7 +420,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil delay_val = ducky_parse_line(bad_usb, bad_usb->line); if(delay_val < 0) { bad_usb->st.error_line = bad_usb->st.line_cur; - FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur); + FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur); return SCRIPT_STATE_ERROR; } else { return (delay_val + bad_usb->defdelay); diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index 4e025b99c..b6310193b 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -91,7 +91,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 22, &I_Percent_10x14); canvas_set_font(canvas, FontSecondary); - furi_string_printf(disp_str, "delay %us", model->state.delay_remain); + furi_string_printf(disp_str, "delay %lus", model->state.delay_remain); canvas_draw_str_aligned( canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); furi_string_reset(disp_str); diff --git a/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp b/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp index 17e2ba83f..f8adbf9d8 100644 --- a/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp +++ b/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp @@ -31,7 +31,7 @@ bool elf_resolve_from_hashtable(const char* name, Elf32_Addr* address) { auto find_res = std::lower_bound(elf_api_table.cbegin(), elf_api_table.cend(), key); if((find_res == elf_api_table.cend() || (find_res->hash != gnu_sym_hash))) { - FURI_LOG_W(TAG, "Cant find symbol '%s' (hash %x)!", name, gnu_sym_hash); + FURI_LOG_W(TAG, "Cant find symbol '%s' (hash %lx)!", name, gnu_sym_hash); result = false; } else { result = true; diff --git a/applications/main/infrared/infrared.c b/applications/main/infrared/infrared.c index a647b158e..f62db14c1 100644 --- a/applications/main/infrared/infrared.c +++ b/applications/main/infrared/infrared.c @@ -92,14 +92,14 @@ static void infrared_find_vacant_remote_name(FuriString* name, const char* path) uint32_t i = 1; do { furi_string_printf( - path_temp, "%s%u%s", furi_string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION); + path_temp, "%s%lu%s", furi_string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION); status = storage_common_stat(storage, furi_string_get_cstr(path_temp), NULL); } while(status == FSE_OK); furi_string_free(path_temp); if(status == FSE_NOT_EXIST) { - furi_string_cat_printf(name, "%u", i); + furi_string_cat_printf(name, "%lu", i); } } diff --git a/applications/main/infrared/infrared_signal.c b/applications/main/infrared/infrared_signal.c index 30459d60f..d399b9587 100644 --- a/applications/main/infrared/infrared_signal.c +++ b/applications/main/infrared/infrared_signal.c @@ -61,7 +61,7 @@ static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) { if((raw->frequency > INFRARED_MAX_FREQUENCY) || (raw->frequency < INFRARED_MIN_FREQUENCY)) { FURI_LOG_E( TAG, - "Frequency is out of range (%lX - %lX): %lX", + "Frequency is out of range (%X - %X): %lX", INFRARED_MIN_FREQUENCY, INFRARED_MAX_FREQUENCY, raw->frequency); @@ -74,7 +74,7 @@ static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) { } else if((raw->timings_size <= 0) || (raw->timings_size > MAX_TIMINGS_AMOUNT)) { FURI_LOG_E( TAG, - "Timings amount is out of range (0 - %lX): %lX", + "Timings amount is out of range (0 - %X): %X", MAX_TIMINGS_AMOUNT, raw->timings_size); return false; diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c index 5649ea870..19d2f556f 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c @@ -27,7 +27,7 @@ void nfc_scene_mf_classic_keys_list_prepare(Nfc* nfc, MfClassicDict* dict) { char* current_key = (char*)malloc(sizeof(char) * 13); strncpy(current_key, furi_string_get_cstr(temp_key), 12); MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); - FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); + FURI_LOG_D("ListKeys", "Key %ld: %s", index, current_key); submenu_add_item( submenu, current_key, index++, nfc_scene_mf_classic_keys_list_submenu_callback, nfc); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c index c5b8cfa20..2ab0355ca 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c @@ -28,11 +28,11 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) { uint32_t bytes_total = 1 << (data->version.sw_storage >> 1); uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - furi_string_cat_printf(temp_str, "\n%d", bytes_total); + furi_string_cat_printf(temp_str, "\n%ld", bytes_total); if(data->version.sw_storage & 1) { furi_string_push_back(temp_str, '+'); } - furi_string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); + furi_string_cat_printf(temp_str, " bytes, %ld bytes free\n", bytes_free); uint16_t n_apps = 0; uint16_t n_files = 0; diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index bb7d58f7c..8f33972e0 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -59,11 +59,11 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { MifareDesfireData* data = &dev_data->mf_df_data; uint32_t bytes_total = 1 << (data->version.sw_storage >> 1); uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - furi_string_cat_printf(temp_str, "\n%d", bytes_total); + furi_string_cat_printf(temp_str, "\n%ld", bytes_total); if(data->version.sw_storage & 1) { furi_string_push_back(temp_str, '+'); } - furi_string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); + furi_string_cat_printf(temp_str, " bytes, %ld bytes free\n", bytes_free); uint16_t n_apps = 0; uint16_t n_files = 0; diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c index 35abbddc1..0341990d8 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -149,7 +149,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { FURI_LOG_T( TAG, - "RSSI: avg %f, max %f at %u, min %f", + "RSSI: avg %f, max %f at %lu, min %f", (double)(rssi_avg / rssi_avg_samples), (double)frequency_rssi.rssi_coarse, frequency_rssi.frequency_coarse, @@ -180,7 +180,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { rssi = furi_hal_subghz_get_rssi(); - FURI_LOG_T(TAG, "#:%u:%f", frequency, (double)rssi); + FURI_LOG_T(TAG, "#:%lu:%f", frequency, (double)rssi); if(frequency_rssi.rssi_fine < rssi) { frequency_rssi.rssi_fine = rssi; @@ -193,7 +193,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { // Deliver results fine if(frequency_rssi.rssi_fine > SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD) { FURI_LOG_D( - TAG, "=:%u:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); + TAG, "=:%lu:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); instance->sample_hold_counter = 20; rssi_temp = frequency_rssi.rssi_fine; @@ -217,7 +217,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { (instance->sample_hold_counter < 10)) { FURI_LOG_D( TAG, - "~:%u:%f", + "~:%lu:%f", frequency_rssi.frequency_coarse, (double)frequency_rssi.rssi_coarse); diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index 7fa0f4546..a1474885e 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -151,8 +151,8 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { "Protocol: Princeton\n" "Bit: 24\n" "Key: 00 00 00 00 00 %02X %02X %02X\n" - "TE: %d\n" - "Repeat: %d\n", + "TE: %ld\n" + "Repeat: %ld\n", (uint8_t)((key >> 16) & 0xFF), (uint8_t)((key >> 8) & 0xFF), (uint8_t)(key & 0xFF), @@ -794,7 +794,7 @@ static bool subghz_on_system_start_istream_decode_band( FURI_LOG_I( "SubGhzOnStart", - "Add allowed band: start %dHz, stop %dHz, power_limit %ddBm, duty_cycle %d%%", + "Add allowed band: start %ldHz, stop %ldHz, power_limit %ddBm, duty_cycle %d%%", band.start, band.end, band.power_limit, diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index f2658c0e4..acf07bc14 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -60,7 +60,7 @@ void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, Furi subghz->txrx->preset->frequency / 10000 % 100); } if(modulation != NULL) { - furi_string_printf(modulation, "%0.2s", furi_string_get_cstr(subghz->txrx->preset->name)); + furi_string_printf(modulation, "%2s", furi_string_get_cstr(subghz->txrx->preset->name)); } } diff --git a/applications/plugins/music_player/music_player_worker.c b/applications/plugins/music_player/music_player_worker.c index af09f0535..99f0ce1e5 100644 --- a/applications/plugins/music_player/music_player_worker.c +++ b/applications/plugins/music_player/music_player_worker.c @@ -258,7 +258,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c if(!is_valid) { FURI_LOG_E( TAG, - "Invalid note: %u%c%c%u.%u", + "Invalid note: %lu%c%c%lu.%lu", duration, note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, @@ -281,7 +281,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c if(music_player_worker_add_note(instance, semitone, duration, dots)) { FURI_LOG_D( TAG, - "Added note: %c%c%u.%u = %u %u", + "Added note: %c%c%lu.%lu = %u %lu", note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, octave, @@ -291,7 +291,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c } else { FURI_LOG_E( TAG, - "Invalid note: %c%c%u.%u = %u %u", + "Invalid note: %c%c%lu.%lu = %u %lu", note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, octave, diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index 2bb083f27..aeb2beec9 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -77,7 +77,7 @@ static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) { notification_message(bt->notification, &sequence_display_backlight_on); FuriString* pin_str; dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64, 0, 0); - pin_str = furi_string_alloc_printf("Verify code\n%06d", pin); + pin_str = furi_string_alloc_printf("Verify code\n%06ld", pin); dialog_message_set_text( bt->dialog_message, furi_string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); dialog_message_set_buttons(bt->dialog_message, "Cancel", "OK", NULL); @@ -277,7 +277,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { static void bt_on_key_storage_change_callback(uint8_t* addr, uint16_t size, void* context) { furi_assert(context); Bt* bt = context; - FURI_LOG_I(TAG, "Changed addr start: %08lX, size changed: %d", addr, size); + FURI_LOG_I(TAG, "Changed addr start: %p, size changed: %d", addr, size); BtMessage message = {.type = BtMessageTypeKeysStorageUpdated}; furi_check( furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index 922d7dc85..0727fd6ae 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -304,7 +304,7 @@ static bool animation_storage_load_frames( if(file_info.size > max_filesize) { FURI_LOG_E( TAG, - "Filesize %d, max: %d (width %d, height %d)", + "Filesize %lld, max: %d (width %d, height %d)", file_info.size, max_filesize, width, @@ -329,7 +329,7 @@ static bool animation_storage_load_frames( if(!frames_ok) { FURI_LOG_E( TAG, - "Load \'%s\' failed, %dx%d, size: %d", + "Load \'%s\' failed, %dx%d, size: %lld", furi_string_get_cstr(filename), width, height, diff --git a/applications/services/dolphin/helpers/dolphin_state.c b/applications/services/dolphin/helpers/dolphin_state.c index 95e2f42f4..10cb85c28 100644 --- a/applications/services/dolphin/helpers/dolphin_state.c +++ b/applications/services/dolphin/helpers/dolphin_state.c @@ -171,7 +171,7 @@ void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { FURI_LOG_D( TAG, - "icounter %d, butthurt %d", + "icounter %ld, butthurt %ld", dolphin_state->data.icounter, dolphin_state->data.butthurt); } diff --git a/applications/services/gui/gui.c b/applications/services/gui/gui.c index 6b4b9a0a7..0535b32b8 100644 --- a/applications/services/gui/gui.c +++ b/applications/services/gui/gui.c @@ -260,7 +260,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { "non-complementary input, discarding key: %s type: %s, sequence: %p", input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); return; } @@ -290,7 +290,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { view_port, input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); view_port_input(gui->ongoing_input_view_port, input_event); } else { FURI_LOG_D( @@ -300,7 +300,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { view_port, input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); } gui_unlock(gui); diff --git a/applications/services/gui/modules/file_browser_worker.c b/applications/services/gui/modules/file_browser_worker.c index 319304f92..fdaf8273f 100644 --- a/applications/services/gui/modules/file_browser_worker.c +++ b/applications/services/gui/modules/file_browser_worker.c @@ -291,7 +291,7 @@ static int32_t browser_worker(void* context) { browser_folder_init(browser, path, filename, &items_cnt, &file_idx); FURI_LOG_D( TAG, - "Enter folder: %s items: %u idx: %d", + "Enter folder: %s items: %lu idx: %ld", furi_string_get_cstr(path), items_cnt, file_idx); @@ -313,7 +313,7 @@ static int32_t browser_worker(void* context) { } FURI_LOG_D( TAG, - "Exit to: %s items: %u idx: %d", + "Exit to: %s items: %lu idx: %ld", furi_string_get_cstr(path), items_cnt, file_idx); @@ -330,7 +330,7 @@ static int32_t browser_worker(void* context) { browser_folder_init(browser, path, filename, &items_cnt, &file_idx); FURI_LOG_D( TAG, - "Refresh folder: %s items: %u idx: %d", + "Refresh folder: %s items: %lu idx: %ld", furi_string_get_cstr(path), items_cnt, browser->item_sel_idx); @@ -340,7 +340,8 @@ static int32_t browser_worker(void* context) { } if(flags & WorkerEvtLoad) { - FURI_LOG_D(TAG, "Load offset: %u cnt: %u", browser->load_offset, browser->load_count); + FURI_LOG_D( + TAG, "Load offset: %lu cnt: %lu", browser->load_offset, browser->load_count); browser_folder_load(browser, path, browser->load_offset, browser->load_count); } diff --git a/applications/services/gui/view_dispatcher.c b/applications/services/gui/view_dispatcher.c index 307206c14..6e4ce8360 100644 --- a/applications/services/gui/view_dispatcher.c +++ b/applications/services/gui/view_dispatcher.c @@ -246,7 +246,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e "non-complementary input, discarding key: %s, type: %s, sequence: %p", input_get_key_name(event->key), input_get_type_name(event->type), - event->sequence); + (void*)event->sequence); return; } @@ -286,7 +286,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e view_dispatcher->current_view, input_get_key_name(event->key), input_get_type_name(event->type), - event->sequence); + (void*)event->sequence); view_input(view_dispatcher->ongoing_input_view, event); } } diff --git a/applications/services/rpc/rpc_app.c b/applications/services/rpc/rpc_app.c index b8b34170e..301055570 100644 --- a/applications/services/rpc/rpc_app.c +++ b/applications/services/rpc/rpc_app.c @@ -32,7 +32,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); - FURI_LOG_D(TAG, "StartProcess: id %d", request->command_id); + FURI_LOG_D(TAG, "StartProcess: id %ld", request->command_id); PB_CommandStatus result = PB_CommandStatus_ERROR_APP_CANT_START; @@ -63,7 +63,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) furi_record_close(RECORD_LOADER); - FURI_LOG_D(TAG, "StartProcess: response id %d, result %d", request->command_id, result); + FURI_LOG_D(TAG, "StartProcess: response id %ld, result %d", request->command_id, result); rpc_send_and_release_empty(session, request->command_id, result); } @@ -108,7 +108,7 @@ static void rpc_system_app_exit_request(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - FURI_LOG_D(TAG, "ExitRequest: id %d", request->command_id); + FURI_LOG_D(TAG, "ExitRequest: id %ld", request->command_id); furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); rpc_app->last_id = request->command_id; @@ -116,7 +116,7 @@ static void rpc_system_app_exit_request(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ExitRequest: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ExitRequest: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -132,7 +132,7 @@ static void rpc_system_app_load_file(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - FURI_LOG_D(TAG, "LoadFile: id %d", request->command_id); + FURI_LOG_D(TAG, "LoadFile: id %ld", request->command_id); furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); rpc_app->last_id = request->command_id; @@ -141,7 +141,7 @@ static void rpc_system_app_load_file(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "LoadFile: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "LoadFile: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -166,7 +166,7 @@ static void rpc_system_app_button_press(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ButtonPress: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ButtonPress: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -190,7 +190,7 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context) } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ButtonRelease: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ButtonRelease: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -243,7 +243,7 @@ void rpc_system_app_confirm(RpcAppSystem* rpc_app, RpcAppSystemEvent event, bool free(rpc_app->last_data); rpc_app->last_data = NULL; } - FURI_LOG_D(TAG, "AppConfirm: event %d last_id %d status %d", event, last_id, status); + FURI_LOG_D(TAG, "AppConfirm: event %d last_id %ld status %d", event, last_id, status); rpc_send_and_release_empty(session, last_id, status); break; default: diff --git a/applications/services/rpc/rpc_cli.c b/applications/services/rpc/rpc_cli.c index d03e2198c..82023e316 100644 --- a/applications/services/rpc/rpc_cli.c +++ b/applications/services/rpc/rpc_cli.c @@ -44,7 +44,7 @@ void rpc_cli_command_start_session(Cli* cli, FuriString* args, void* context) { Rpc* rpc = context; uint32_t mem_before = memmgr_get_free_heap(); - FURI_LOG_D(TAG, "Free memory %d", mem_before); + FURI_LOG_D(TAG, "Free memory %ld", mem_before); furi_hal_usb_lock(); RpcSession* rpc_session = rpc_session_open(rpc); diff --git a/applications/services/rpc/rpc_debug.c b/applications/services/rpc/rpc_debug.c index a060654d8..8eb81dece 100644 --- a/applications/services/rpc/rpc_debug.c +++ b/applications/services/rpc/rpc_debug.c @@ -158,9 +158,9 @@ void rpc_debug_print_message(const PB_Main* message) { case PB_Main_storage_info_response_tag: { furi_string_cat_printf(str, "\tinfo_response {\r\n"); furi_string_cat_printf( - str, "\t\ttotal_space: %lu\r\n", message->content.storage_info_response.total_space); + str, "\t\ttotal_space: %llu\r\n", message->content.storage_info_response.total_space); furi_string_cat_printf( - str, "\t\tfree_space: %lu\r\n", message->content.storage_info_response.free_space); + str, "\t\tfree_space: %llu\r\n", message->content.storage_info_response.free_space); break; } case PB_Main_storage_stat_request_tag: { diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index 379fc4ed1..c0c730fb7 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -119,7 +119,11 @@ bool storage_file_open( furi_event_flag_free(event); FURI_LOG_T( - TAG, "File %p - %p open (%s)", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE, path); + TAG, + "File %p - %p open (%s)", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE), + path); return result; } @@ -132,7 +136,11 @@ bool storage_file_close(File* file) { S_API_MESSAGE(StorageCommandFileClose); S_API_EPILOGUE; - FURI_LOG_T(TAG, "File %p - %p closed", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE); + FURI_LOG_T( + TAG, + "File %p - %p closed", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE)); file->type = FileTypeClosed; return S_RETURN_BOOL; @@ -291,7 +299,11 @@ bool storage_dir_open(File* file, const char* path) { furi_event_flag_free(event); FURI_LOG_T( - TAG, "Dir %p - %p open (%s)", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE, path); + TAG, + "Dir %p - %p open (%s)", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE), + path); return result; } @@ -303,7 +315,11 @@ bool storage_dir_close(File* file) { S_API_MESSAGE(StorageCommandDirClose); S_API_EPILOGUE; - FURI_LOG_T(TAG, "Dir %p - %p closed", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE); + FURI_LOG_T( + TAG, + "Dir %p - %p closed", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE)); file->type = FileTypeClosed; @@ -675,7 +691,7 @@ File* storage_file_alloc(Storage* storage) { file->type = FileTypeClosed; file->storage = storage; - FURI_LOG_T(TAG, "File/Dir %p alloc", (uint32_t)file - SRAM_BASE); + FURI_LOG_T(TAG, "File/Dir %p alloc", (void*)((uint32_t)file - SRAM_BASE)); return file; } @@ -697,7 +713,7 @@ void storage_file_free(File* file) { } } - FURI_LOG_T(TAG, "File/Dir %p free", (uint32_t)file - SRAM_BASE); + FURI_LOG_T(TAG, "File/Dir %p free", (void*)((uint32_t)file - SRAM_BASE)); free(file); } diff --git a/applications/services/storage/storages/storage_int.c b/applications/services/storage/storages/storage_int.c index ab0255014..4fa5d130c 100644 --- a/applications/services/storage/storages/storage_int.c +++ b/applications/services/storage/storages/storage_int.c @@ -77,12 +77,12 @@ static int storage_int_device_read( FURI_LOG_T( TAG, - "Device read: block %d, off %d, buffer: %p, size %d, translated address: %p", + "Device read: block %ld, off %ld, buffer: %p, size %ld, translated address: %p", block, off, buffer, size, - address); + (void*)address); memcpy(buffer, (void*)address, size); @@ -100,12 +100,12 @@ static int storage_int_device_prog( FURI_LOG_T( TAG, - "Device prog: block %d, off %d, buffer: %p, size %d, translated address: %p", + "Device prog: block %ld, off %ld, buffer: %p, size %ld, translated address: %p", block, off, buffer, size, - address); + (void*)address); int ret = 0; while(size > 0) { @@ -122,7 +122,7 @@ static int storage_int_device_erase(const struct lfs_config* c, lfs_block_t bloc LFSData* lfs_data = c->context; size_t page = lfs_data->start_page + block; - FURI_LOG_D(TAG, "Device erase: page %d, translated page: %x", block, page); + FURI_LOG_D(TAG, "Device erase: page %ld, translated page: %x", block, page); furi_hal_flash_erase(page); return 0; @@ -740,8 +740,8 @@ void storage_int_init(StorageData* storage) { LFSData* lfs_data = storage_int_lfs_data_alloc(); FURI_LOG_I( TAG, - "Config: start %p, read %d, write %d, page size: %d, page count: %d, cycles: %d", - lfs_data->start_address, + "Config: start %p, read %ld, write %ld, page size: %ld, page count: %ld, cycles: %ld", + (void*)lfs_data->start_address, lfs_data->config.read_size, lfs_data->config.prog_size, lfs_data->config.block_size, diff --git a/applications/system/updater/util/update_task_worker_flasher.c b/applications/system/updater/util/update_task_worker_flasher.c index b235d0018..7358a6334 100644 --- a/applications/system/updater/util/update_task_worker_flasher.c +++ b/applications/system/updater/util/update_task_worker_flasher.c @@ -271,7 +271,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { match = false; FURI_LOG_E( TAG, - "OB MISMATCH: #%d: real %08X != %08X (exp.), full %08X", + "OB MISMATCH: #%d: real %08lX != %08lX (exp.), full %08lX", idx, device_ob_value_masked, ref_value, @@ -289,7 +289,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { (manifest->ob_reference.obs[idx].values.base & manifest->ob_write_mask.obs[idx].values.base); - FURI_LOG_W(TAG, "Fixing up OB byte #%d to %08X", idx, patched_value); + FURI_LOG_W(TAG, "Fixing up OB byte #%d to %08lX", idx, patched_value); ob_dirty = true; bool is_fixed = furi_hal_flash_ob_set_word(idx, patched_value) && @@ -301,7 +301,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { * reference value */ FURI_LOG_W( TAG, - "OB #%d is FUBAR (fixed&masked %08X, not %08X)", + "OB #%d is FUBAR (fixed&masked %08lX, not %08lX)", idx, patched_value, ref_value); @@ -310,7 +310,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { } else { FURI_LOG_D( TAG, - "OB MATCH: #%d: real %08X == %08X (exp.)", + "OB MATCH: #%d: real %08lX == %08lX (exp.)", idx, device_ob_value_masked, ref_value); diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 62db30fee..aa8cd2c90 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -184,7 +184,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) { FURI_LOG_I(TAG, "Pass key request event. Pin: ******"); } else { - FURI_LOG_I(TAG, "Pass key request event. Pin: %06d", pin); + FURI_LOG_I(TAG, "Pass key request event. Pin: %06ld", pin); } GapEvent event = {.type = GapEventTypePinCodeShow, .data.pin_code = pin}; gap->on_event_cb(event, gap->context); @@ -227,7 +227,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: { uint32_t pin = ((aci_gap_numeric_comparison_value_event_rp0*)(blue_evt->data))->Numeric_Value; - FURI_LOG_I(TAG, "Verify numeric comparison: %06d", pin); + FURI_LOG_I(TAG, "Verify numeric comparison: %06ld", pin); GapEvent event = {.type = GapEventTypePinCodeVerify, .data.pin_code = pin}; bool result = gap->on_event_cb(event, gap->context); aci_gap_numeric_comparison_value_confirm_yesno(gap->service.connection_handle, result); diff --git a/firmware/targets/f7/ble_glue/serial_service.c b/firmware/targets/f7/ble_glue/serial_service.c index eb58ae0ec..536557cce 100644 --- a/firmware/targets/f7/ble_glue/serial_service.c +++ b/firmware/targets/f7/ble_glue/serial_service.c @@ -63,13 +63,13 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { .size = attribute_modified->Attr_Data_Length, }}; uint32_t buff_free_size = serial_svc->callback(event, serial_svc->context); - FURI_LOG_D(TAG, "Available buff size: %d", buff_free_size); + FURI_LOG_D(TAG, "Available buff size: %ld", buff_free_size); furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk); } ret = SVCCTL_EvtAckFlowEnable; } } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { - FURI_LOG_T(TAG, "Ack received", blecore_evt->ecode); + FURI_LOG_T(TAG, "Ack received"); if(serial_svc->callback) { SerialServiceEvent event = { .event = SerialServiceEventTypeDataSent, diff --git a/firmware/targets/f7/furi_hal/furi_hal_console.h b/firmware/targets/f7/furi_hal/furi_hal_console.h index 104515ce9..ce31a66b3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_console.h +++ b/firmware/targets/f7/furi_hal/furi_hal_console.h @@ -2,6 +2,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -27,7 +28,7 @@ void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size * @param format * @param ... */ -void furi_hal_console_printf(const char format[], ...); +void furi_hal_console_printf(const char format[], ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); void furi_hal_console_puts(const char* data); diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index f99cf8c3d..e49cd5f29 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -83,7 +83,7 @@ void furi_hal_flash_init() { // WRITE_REG(FLASH->SR, FLASH_SR_OPTVERR); /* Actually, reset all error flags on start */ if(READ_BIT(FLASH->SR, FURI_HAL_FLASH_SR_ERRORS)) { - FURI_LOG_E(TAG, "FLASH->SR 0x%08X", FLASH->SR); + FURI_LOG_E(TAG, "FLASH->SR 0x%08lX", FLASH->SR); WRITE_REG(FLASH->SR, FURI_HAL_FLASH_SR_ERRORS); } } @@ -514,10 +514,10 @@ bool furi_hal_flash_ob_set_word(size_t word_idx, const uint32_t value) { FURI_LOG_W( TAG, - "Setting OB reg %d for word %d (addr 0x%08X) to 0x%08X", + "Setting OB reg %d for word %d (addr 0x%08lX) to 0x%08lX", reg_def->ob_reg, word_idx, - reg_def->ob_register_address, + (uint32_t)reg_def->ob_register_address, value); /* 1. Clear OPTLOCK option lock bit with the clearing sequence */ diff --git a/firmware/targets/f7/furi_hal/furi_hal_memory.c b/firmware/targets/f7/furi_hal/furi_hal_memory.c index 43dc56f11..9cf2c3120 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_memory.c +++ b/firmware/targets/f7/furi_hal/furi_hal_memory.c @@ -55,9 +55,9 @@ void furi_hal_memory_init() { memory->region[SRAM_B].size = sram2b_unprotected_size; FURI_LOG_I( - TAG, "SRAM2A: 0x%p, %d", memory->region[SRAM_A].start, memory->region[SRAM_A].size); + TAG, "SRAM2A: 0x%p, %ld", memory->region[SRAM_A].start, memory->region[SRAM_A].size); FURI_LOG_I( - TAG, "SRAM2B: 0x%p, %d", memory->region[SRAM_B].start, memory->region[SRAM_B].size); + TAG, "SRAM2B: 0x%p, %ld", memory->region[SRAM_B].start, memory->region[SRAM_B].size); if((memory->region[SRAM_A].size > 0) || (memory->region[SRAM_B].size > 0)) { if((memory->region[SRAM_A].size > 0)) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index bc98f108d..86505c573 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -569,13 +569,13 @@ void furi_hal_power_info_get(FuriHalPowerInfoCallback out, void* context) { furi_string_printf(value, "%u", furi_hal_power_get_bat_health_pct()); out("battery_health", furi_string_get_cstr(value), false, context); - furi_string_printf(value, "%u", furi_hal_power_get_battery_remaining_capacity()); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_remaining_capacity()); out("capacity_remain", furi_string_get_cstr(value), false, context); - furi_string_printf(value, "%u", furi_hal_power_get_battery_full_capacity()); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_full_capacity()); out("capacity_full", furi_string_get_cstr(value), false, context); - furi_string_printf(value, "%u", furi_hal_power_get_battery_design_capacity()); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_design_capacity()); out("capacity_design", furi_string_get_cstr(value), true, context); furi_string_free(value); diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index b73d074fd..5eeb4e9a5 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -173,7 +173,7 @@ void furi_hal_subghz_load_custom_preset(uint8_t* preset_data) { i += 2; } for(uint8_t y = i; y < i + 10; y++) { - FURI_LOG_D(TAG, "PA[%lu]: %02X", y, preset_data[y]); + FURI_LOG_D(TAG, "PA[%u]: %02X", y, preset_data[y]); } } } diff --git a/furi/core/log.h b/furi/core/log.h index 30026fc44..cb8b3d9cc 100644 --- a/furi/core/log.h +++ b/furi/core/log.h @@ -51,7 +51,8 @@ void furi_log_init(); * @param format * @param ... */ -void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...); +void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); /** Set log level * diff --git a/furi/core/string.h b/furi/core/string.h index b6700c9ca..01b26cce1 100644 --- a/furi/core/string.h +++ b/furi/core/string.h @@ -57,7 +57,8 @@ FuriString* furi_string_alloc_set_str(const char cstr_source[]); * @param ... * @return FuriString* */ -FuriString* furi_string_alloc_printf(const char format[], ...); +FuriString* furi_string_alloc_printf(const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 1, 2))); /** * @brief Allocate new FuriString and printf to it. @@ -214,7 +215,8 @@ void furi_string_set_n(FuriString* string, const FuriString* source, size_t offs * @param ... * @return int */ -int furi_string_printf(FuriString* string, const char format[], ...); +int furi_string_printf(FuriString* string, const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * @brief Format in the string the given printf format @@ -259,7 +261,8 @@ void furi_string_cat_str(FuriString* string_1, const char cstring_2[]); * @param ... * @return int */ -int furi_string_cat_printf(FuriString* string, const char format[], ...); +int furi_string_cat_printf(FuriString* string, const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * @brief Append to the string the formatted string of the given printf format. diff --git a/lib/lfrfid/lfrfid_raw_worker.c b/lib/lfrfid/lfrfid_raw_worker.c index 9bab77db1..1547d20f9 100644 --- a/lib/lfrfid/lfrfid_raw_worker.c +++ b/lib/lfrfid/lfrfid_raw_worker.c @@ -338,7 +338,7 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { } if(data->ctx.overrun_count) { - FURI_LOG_E(TAG_EMULATE, "overruns: %lu", data->ctx.overrun_count); + FURI_LOG_E(TAG_EMULATE, "overruns: %u", data->ctx.overrun_count); } furi_stream_buffer_free(data->ctx.stream); diff --git a/lib/lfrfid/protocols/protocol_gallagher.c b/lib/lfrfid/protocols/protocol_gallagher.c index 460c23a39..4720d3a4d 100644 --- a/lib/lfrfid/protocols/protocol_gallagher.c +++ b/lib/lfrfid/protocols/protocol_gallagher.c @@ -276,7 +276,7 @@ void protocol_gallagher_render_data(ProtocolGallagher* protocol, FuriString* res uint32_t card_id = bit_lib_get_bits_32(protocol->data, 32, 32); furi_string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il); - furi_string_cat_printf(result, "FC: %u, C: %lu\r\n", fc, card_id); + furi_string_cat_printf(result, "FC: %lu, C: %lu\r\n", fc, card_id); }; const ProtocolBase protocol_gallagher = { diff --git a/lib/lfrfid/protocols/protocol_keri.c b/lib/lfrfid/protocols/protocol_keri.c index 099fd1680..f0a12863e 100644 --- a/lib/lfrfid/protocols/protocol_keri.c +++ b/lib/lfrfid/protocols/protocol_keri.c @@ -218,7 +218,7 @@ void protocol_keri_render_data(ProtocolKeri* protocol, FuriString* result) { uint32_t fc = 0; uint32_t cn = 0; protocol_keri_descramble(&fc, &cn, &data); - furi_string_printf(result, "Internal ID: %u\r\nFC: %u, Card: %u\r\n", internal_id, fc, cn); + furi_string_printf(result, "Internal ID: %lu\r\nFC: %lu, Card: %lu\r\n", internal_id, fc, cn); } bool protocol_keri_write_data(ProtocolKeri* protocol, void* data) { diff --git a/lib/lfrfid/protocols/protocol_paradox.c b/lib/lfrfid/protocols/protocol_paradox.c index 6a8e33ba4..7e029f1de 100644 --- a/lib/lfrfid/protocols/protocol_paradox.c +++ b/lib/lfrfid/protocols/protocol_paradox.c @@ -142,7 +142,7 @@ void protocol_paradox_render_data(ProtocolParadox* protocol, FuriString* result) uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16); furi_string_cat_printf(result, "Facility: %u\r\n", fc); - furi_string_cat_printf(result, "Card: %lu\r\n", card_id); + furi_string_cat_printf(result, "Card: %u\r\n", card_id); furi_string_cat_printf(result, "Data: "); for(size_t i = 0; i < PARADOX_DECODED_DATA_SIZE; i++) { furi_string_cat_printf(result, "%02X", decoded_data[i]); diff --git a/lib/lfrfid/protocols/protocol_pyramid.c b/lib/lfrfid/protocols/protocol_pyramid.c index 545744580..974bb6da6 100644 --- a/lib/lfrfid/protocols/protocol_pyramid.c +++ b/lib/lfrfid/protocols/protocol_pyramid.c @@ -243,7 +243,7 @@ void protocol_pyramid_render_data(ProtocolPyramid* protocol, FuriString* result) uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - furi_string_cat_printf(result, "Format: 26\r\n", format_length); + furi_string_cat_printf(result, "Format: %d\r\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 8); diff --git a/lib/nfc/helpers/mf_classic_dict.c b/lib/nfc/helpers/mf_classic_dict.c index 356f6f7c7..a842ed921 100644 --- a/lib/nfc/helpers/mf_classic_dict.c +++ b/lib/nfc/helpers/mf_classic_dict.c @@ -87,7 +87,7 @@ MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) { stream_rewind(dict->stream); dict_loaded = true; - FURI_LOG_I(TAG, "Loaded dictionary with %d keys", dict->total_keys); + FURI_LOG_I(TAG, "Loaded dictionary with %ld keys", dict->total_keys); } while(false); if(!dict_loaded) { diff --git a/lib/nfc/helpers/mfkey32.c b/lib/nfc/helpers/mfkey32.c index fa5713f27..47e7e9f6b 100644 --- a/lib/nfc/helpers/mfkey32.c +++ b/lib/nfc/helpers/mfkey32.c @@ -92,7 +92,7 @@ void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) { FuriString* str = furi_string_alloc_printf( - "Sec %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n", + "Sec %d key %c cuid %08lx nt0 %08lx nr0 %08lx ar0 %08lx nt1 %08lx nr1 %08lx ar1 %08lx\n", params->sector, params->key == MfClassicKeyA ? 'A' : 'B', params->cuid, diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index c61ad444c..732453465 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -522,7 +522,8 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { return; } - FURI_LOG_D(TAG, "Start Dictionary attack, Key Count %d", mf_classic_dict_get_total_keys(dict)); + FURI_LOG_D( + TAG, "Start Dictionary attack, Key Count %ld", mf_classic_dict_get_total_keys(dict)); for(size_t i = 0; i < total_sectors; i++) { FURI_LOG_I(TAG, "Sector %d", i); nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context); diff --git a/lib/nfc/parsers/all_in_one.c b/lib/nfc/parsers/all_in_one.c index f63fb7e6d..05cfe5764 100644 --- a/lib/nfc/parsers/all_in_one.c +++ b/lib/nfc/parsers/all_in_one.c @@ -108,6 +108,6 @@ bool all_in_one_parser_parse(NfcDeviceData* dev_data) { // Format string for rides count furi_string_printf( - dev_data->parsed_data, "\e#All-In-One\nNumber: %u\nRides left: %u", serial, ride_count); + dev_data->parsed_data, "\e#All-In-One\nNumber: %lu\nRides left: %u", serial, ride_count); return true; } \ No newline at end of file diff --git a/lib/nfc/parsers/plantain_4k_parser.c b/lib/nfc/parsers/plantain_4k_parser.c index eddebac23..348b5a64c 100644 --- a/lib/nfc/parsers/plantain_4k_parser.c +++ b/lib/nfc/parsers/plantain_4k_parser.c @@ -132,7 +132,7 @@ bool plantain_4k_parser_parse(NfcDeviceData* dev_data) { furi_string_printf( dev_data->parsed_data, - "\e#Plantain\nN:%s\nBalance:%d\n", + "\e#Plantain\nN:%s\nBalance:%ld\n", furi_string_get_cstr(card_number_str), balance); furi_string_free(card_number_str); diff --git a/lib/nfc/parsers/plantain_parser.c b/lib/nfc/parsers/plantain_parser.c index ac7a90b24..5328b5c4f 100644 --- a/lib/nfc/parsers/plantain_parser.c +++ b/lib/nfc/parsers/plantain_parser.c @@ -105,7 +105,7 @@ bool plantain_parser_parse(NfcDeviceData* dev_data) { furi_string_printf( dev_data->parsed_data, - "\e#Plantain\nN:%s\nBalance:%d\n", + "\e#Plantain\nN:%s\nBalance:%ld\n", furi_string_get_cstr(card_number_str), balance); furi_string_free(card_number_str); diff --git a/lib/nfc/parsers/two_cities.c b/lib/nfc/parsers/two_cities.c index f5e31d51b..2c6184a71 100644 --- a/lib/nfc/parsers/two_cities.c +++ b/lib/nfc/parsers/two_cities.c @@ -149,7 +149,7 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) { furi_string_printf( dev_data->parsed_data, - "\e#Troika+Plantain\nPN: %s\nPB: %d rur.\nTN: %d\nTB: %d rur.\n", + "\e#Troika+Plantain\nPN: %s\nPB: %ld rur.\nTN: %ld\nTB: %d rur.\n", furi_string_get_cstr(card_number_str), balance, troika_number, diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c index 3b5343932..783202451 100644 --- a/lib/nfc/protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -847,7 +847,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ FURI_LOG_D( TAG, - "%08x key%c block %d nt/nr/ar: %08x %08x %08x", + "%08lx key%c block %d nt/nr/ar: %08lx %08lx %08lx", emulator->cuid, access_key == MfClassicKeyA ? 'A' : 'B', sector_trailer_block, @@ -858,7 +858,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ crypto1_word(&emulator->crypto, nr, 1); uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0); if(cardRr != prng_successor(nonce, 64)) { - FURI_LOG_T(TAG, "Wrong AUTH! %08X != %08X", cardRr, prng_successor(nonce, 64)); + FURI_LOG_T(TAG, "Wrong AUTH! %08lX != %08lX", cardRr, prng_successor(nonce, 64)); // Don't send NACK, as the tag doesn't send it command_processed = true; break; diff --git a/lib/nfc/protocols/mifare_desfire.c b/lib/nfc/protocols/mifare_desfire.c index 9dd37f1ee..b2247bf20 100644 --- a/lib/nfc/protocols/mifare_desfire.c +++ b/lib/nfc/protocols/mifare_desfire.c @@ -108,7 +108,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, FuriString* out) { } void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, FuriString* out) { - furi_string_cat_printf(out, "freeMem %d\n", free_mem->bytes); + furi_string_cat_printf(out, "freeMem %ld\n", free_mem->bytes); } void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, FuriString* out) { @@ -191,10 +191,10 @@ void mf_df_cat_file(MifareDesfireFile* file, FuriString* out) { case MifareDesfireFileTypeValue: size = 4; furi_string_cat_printf( - out, "lo %d hi %d\n", file->settings.value.lo_limit, file->settings.value.hi_limit); + out, "lo %ld hi %ld\n", file->settings.value.lo_limit, file->settings.value.hi_limit); furi_string_cat_printf( out, - "limit %d enabled %d\n", + "limit %ld enabled %d\n", file->settings.value.limited_credit_value, file->settings.value.limited_credit_enabled); break; @@ -203,7 +203,7 @@ void mf_df_cat_file(MifareDesfireFile* file, FuriString* out) { size = file->settings.record.size; num = file->settings.record.cur; furi_string_cat_printf(out, "size %d\n", size); - furi_string_cat_printf(out, "num %d max %d\n", num, file->settings.record.max); + furi_string_cat_printf(out, "num %d max %ld\n", num, file->settings.record.max); break; } uint8_t* data = file->contents; diff --git a/lib/nfc/protocols/mifare_ultralight.c b/lib/nfc/protocols/mifare_ultralight.c index ffabe88ab..a8d1f5548 100644 --- a/lib/nfc/protocols/mifare_ultralight.c +++ b/lib/nfc/protocols/mifare_ultralight.c @@ -193,7 +193,7 @@ bool mf_ultralight_authenticate(FuriHalNfcTxRxContext* tx_rx, uint32_t key, uint *pack = (tx_rx->rx_data[1] << 8) | tx_rx->rx_data[0]; } - FURI_LOG_I(TAG, "Auth success. Password: %08X. PACK: %04X", key, *pack); + FURI_LOG_I(TAG, "Auth success. Password: %08lX. PACK: %04X", key, *pack); authenticated = true; } while(false); @@ -1050,7 +1050,7 @@ static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, FuriString* if(mirror_conf == MfUltralightMirrorUidCounter) furi_string_cat(str, uid_printed ? "x" : " "); - furi_string_cat_printf(str, "%06X", emulator->data.counter[2]); + furi_string_cat_printf(str, "%06lX", emulator->data.counter[2]); } } } diff --git a/lib/print/printf_tiny.h b/lib/print/printf_tiny.h index 8f292819e..58f6a673b 100644 --- a/lib/print/printf_tiny.h +++ b/lib/print/printf_tiny.h @@ -34,6 +34,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -54,7 +55,7 @@ void _putchar(char character); * \param format A string that specifies the format of the output * \return The number of characters that are written into the array, not counting the terminating null character */ -int printf_(const char* format, ...); +int printf_(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); /** * Tiny sprintf implementation @@ -63,7 +64,7 @@ int printf_(const char* format, ...); * \param format A string that specifies the format of the output * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character */ -int sprintf_(char* buffer, const char* format, ...); +int sprintf_(char* buffer, const char* format, ...) _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Tiny snprintf/vsnprintf implementation @@ -75,7 +76,8 @@ int sprintf_(char* buffer, const char* format, ...); * null character. A value equal or larger than count indicates truncation. Only when the returned value * is non-negative and less than count, the string has been completely written. */ -int snprintf_(char* buffer, size_t count, const char* format, ...); +int snprintf_(char* buffer, size_t count, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); /** @@ -94,7 +96,8 @@ int vprintf_(const char* format, va_list va); * \param format A string that specifies the format of the output * \return The number of characters that are sent to the output function, not counting the terminating null character */ -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); #ifdef __cplusplus } diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 1349d976e..8c2a542c2 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -338,7 +338,7 @@ void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* ou "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%03X\r\n", + "Cnt:0x%03lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index 65667be21..3d5029ec9 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -457,7 +457,7 @@ void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* out output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" - "Btn:%lX\r\n" + "Btn:%X\r\n" "DIP:" DIP_PATTERN "\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/doitrand.c b/lib/subghz/protocols/doitrand.c index eeab2576e..5c3402144 100644 --- a/lib/subghz/protocols/doitrand.c +++ b/lib/subghz/protocols/doitrand.c @@ -345,7 +345,7 @@ void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* outp output, "%s %dbit\r\n" "Key:%02lX%08lX\r\n" - "Btn:%lX\r\n" + "Btn:%X\r\n" "DIP:" DIP_PATTERN "\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 75f8d4e97..b54435902 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -222,7 +222,7 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp "Key:%lX%08lX\r\n" "Fix:%08lX \r\n" "Hop:%08lX \r\n" - "Sn:%07lX Btn:%lX\r\n", + "Sn:%07lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index 73a509261..5cf3a8714 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -325,7 +325,7 @@ void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* outpu output, "%s %dbit\r\n" "Key:%06lX\r\n" - "Sn:%05lX Btn:%lX\r\n", + "Sn:%05lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data & 0xFFFFFF), diff --git a/lib/subghz/protocols/honeywell_wdb.c b/lib/subghz/protocols/honeywell_wdb.c index 326e79f83..3cd62698d 100644 --- a/lib/subghz/protocols/honeywell_wdb.c +++ b/lib/subghz/protocols/honeywell_wdb.c @@ -385,7 +385,7 @@ void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* "Key:0x%lX%08lX\r\n" "Sn:0x%05lX\r\n" "DT:%s Al:%s\r\n" - "SK:%01lX R:%01lX LBat:%01lX\r\n", + "SK:%01X R:%01X LBat:%01X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)((instance->generic.data >> 32) & 0xFFFFFFFF), diff --git a/lib/subghz/protocols/ido.c b/lib/subghz/protocols/ido.c index a0332f9e5..6cc60bde8 100644 --- a/lib/subghz/protocols/ido.c +++ b/lib/subghz/protocols/ido.c @@ -221,7 +221,7 @@ void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) { "Key:0x%lX%08lX\r\n" "Fix:%06lX \r\n" "Hop:%06lX \r\n" - "Sn:%05lX Btn:%lX\r\n", + "Sn:%05lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 2865309ee..039d97a6a 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -700,8 +700,8 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04X\r\n" - "Hop:0x%08lX Btn:%01lX\r\n" + "Fix:0x%08lX Cnt:%04lX\r\n" + "Hop:0x%08lX Btn:%01X\r\n" "MF:%s\r\n" "Sn:0x%07lX \r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index aad26f16a..d46838661 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -268,7 +268,7 @@ void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) { output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Sn:%07lX Btn:%lX Cnt:%04X\r\n", + "Sn:%07lX Btn:%X Cnt:%04lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, code_found_hi, diff --git a/lib/subghz/protocols/magellen.c b/lib/subghz/protocols/magellen.c index 0c801c08e..160ec4a2c 100644 --- a/lib/subghz/protocols/magellen.c +++ b/lib/subghz/protocols/magellen.c @@ -432,7 +432,7 @@ void subghz_protocol_decoder_magellen_get_string(void* context, FuriString* outp output, "%s %dbit\r\n" "Key:0x%08lX\r\n" - "Sn:%03d%03d, Event:0x%02X\r\n" + "Sn:%03ld%03ld, Event:0x%02X\r\n" "Stat:", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index 1c3997b97..a72238a41 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -383,7 +383,7 @@ void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* outp "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Btn:%lX\r\n", + "Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c index 40f22cfdb..baa8188d3 100644 --- a/lib/subghz/protocols/megacode.c +++ b/lib/subghz/protocols/megacode.c @@ -417,8 +417,8 @@ void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* outp output, "%s %dbit\r\n" "Key:0x%06lX\r\n" - "Sn:0x%04lX - %d\r\n" - "Facility:%X Btn:%X\r\n", + "Sn:0x%04lX - %ld\r\n" + "Facility:%lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)instance->generic.data, diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index ffd94811f..d567ddf2c 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -368,7 +368,7 @@ void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* o "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" "Sn:%05lX\r\n" - "Cnt:%04X Btn:%02lX\r\n", + "Cnt:%04lX Btn:%02X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, code_found_hi, diff --git a/lib/subghz/protocols/oregon2.c b/lib/subghz/protocols/oregon2.c index 48435502f..561df819f 100644 --- a/lib/subghz/protocols/oregon2.c +++ b/lib/subghz/protocols/oregon2.c @@ -253,7 +253,7 @@ static void val = ((var_data >> 4) & 0xF) * 10 + ((var_data >> 8) & 0xF); furi_string_cat_printf( output, - "Temp: %s%d.%d C\r\n", + "Temp: %s%ld.%ld C\r\n", (var_data & 0xF) ? "-" : "+", val, (uint32_t)(var_data >> 12) & 0xF); @@ -286,7 +286,7 @@ void subghz_protocol_decoder_oregon2_get_string(void* context, FuriString* outpu furi_string_cat_printf( output, "%s\r\n" - "ID: 0x%04lX, ch: %d%s, rc: 0x%02lX\r\n", + "ID: 0x%04lX, ch: %ld%s, rc: 0x%02lX\r\n", instance->generic.protocol_name, (uint32_t)sensor_id, (uint32_t)(instance->generic.data >> 12) & 0xF, diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index e97df9b65..019c3ec25 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -329,7 +329,7 @@ void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* ou "%s %dbit\r\n" "Key:%02lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Btn:%lX\r\n", + "Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32) & 0xFFFFFFFF, diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index c981de1b8..370f33fb0 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -364,7 +364,7 @@ void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* out "Key:0x%08lX\r\n" "Yek:0x%08lX\r\n" "Sn:0x%05lX Btn:%01X\r\n" - "Te:%dus\r\n", + "Te:%ldus\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data & 0xFFFFFF), diff --git a/lib/subghz/protocols/princeton_for_testing.c b/lib/subghz/protocols/princeton_for_testing.c index 43078d2e2..0987e0ad6 100644 --- a/lib/subghz/protocols/princeton_for_testing.c +++ b/lib/subghz/protocols/princeton_for_testing.c @@ -94,7 +94,7 @@ void subghz_encoder_princeton_for_testing_print_log(void* context) { ((float)instance->time_high / (instance->time_high + instance->time_low)) * 100; FURI_LOG_I( TAG "Encoder", - "Radio tx_time=%dus ON=%dus, OFF=%dus, DutyCycle=%d,%d%%", + "Radio tx_time=%ldus ON=%ldus, OFF=%ldus, DutyCycle=%ld,%ld%%", instance->time_high + instance->time_low, instance->time_high, instance->time_low, diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 48c3ff4df..fd234502a 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -115,7 +115,7 @@ bool subghz_protocol_raw_save_to_file_init( // Open file if(!flipper_format_file_open_always( instance->flipper_file, furi_string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Unable to open file for write: %s", temp_str); + FURI_LOG_E(TAG, "Unable to open file for write: %s", furi_string_get_cstr(temp_str)); break; } diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index 617efbbab..837dcf058 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -274,7 +274,7 @@ void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* ou output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" - "Sn:%07lX Btn:%lX Cnt:%04X\r\n" + "Sn:%07lX Btn:%X Cnt:%04lX\r\n" "Pt: %s\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index 885615b6e..cfe6bdee5 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -606,7 +606,7 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* ou furi_string_cat_printf( output, "Sn:0x%08lX\r\n" - "Cnt:0x%03X\r\n" + "Cnt:0x%03lX\r\n" "Sw_id:0x%X\r\n", instance->generic.serial, instance->generic.cnt, @@ -625,7 +625,7 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* ou furi_string_cat_printf( output, "Sn:0x%08lX\r\n" - "Cnt:0x%03X\r\n" + "Cnt:0x%03lX\r\n" "Sw_id:0x%X\r\n", instance->generic.serial, instance->generic.cnt, diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 3c9b966a9..73bb7802b 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -821,7 +821,7 @@ void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* ou "Pk1:0x%lX%08lX\r\n" "Pk2:0x%lX%08lX\r\n" "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%03X\r\n", + "Cnt:0x%03lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index e1b750749..cf627ef37 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -437,7 +437,7 @@ void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* "%s %db\r\n" "%lX%08lX%06lX\r\n" "Sn:0x%06lX \r\n" - "Cnt:0x%04X\r\n" + "Cnt:0x%04lX\r\n" "Btn:%s\r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 1dfdf0c43..6e375bb38 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -374,7 +374,7 @@ void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* o "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%06lX \r\n" - "Cnt:0x%04X\r\n" + "Cnt:0x%04lX\r\n" "Btn:%s\r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index a8b0dad73..4b89bd2bf 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -373,8 +373,8 @@ void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* out output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04X\r\n" - "Hop:0x%08lX Btn:%02lX\r\n" + "Fix:0x%08lX Cnt:%04lX\r\n" + "Hop:0x%08lX Btn:%02X\r\n" "MF:%s\r\n" "Sn:0x%07lX \r\n", instance->generic.protocol_name, diff --git a/lib/toolbox/stream/stream.h b/lib/toolbox/stream/stream.h index 1ffb40445..fc3855102 100644 --- a/lib/toolbox/stream/stream.h +++ b/lib/toolbox/stream/stream.h @@ -143,7 +143,8 @@ size_t stream_write_cstring(Stream* stream, const char* string); * @param ... * @return size_t how many bytes was written */ -size_t stream_write_format(Stream* stream, const char* format, ...); +size_t stream_write_format(Stream* stream, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Write formatted string to the stream, va_list version @@ -200,7 +201,8 @@ bool stream_insert_cstring(Stream* stream, const char* string); * @return true if the operation was successful * @return false on error */ -bool stream_insert_format(Stream* stream, const char* format, ...); +bool stream_insert_format(Stream* stream, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Insert formatted string to the stream, va_list version @@ -251,7 +253,8 @@ bool stream_delete_and_insert_cstring(Stream* stream, size_t delete_size, const * @return true if the operation was successful * @return false on error */ -bool stream_delete_and_insert_format(Stream* stream, size_t delete_size, const char* format, ...); +bool stream_delete_and_insert_format(Stream* stream, size_t delete_size, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); /** * Delete N chars from the stream and insert formatted string to the stream, va_list version From 1a1f711897ad3080e903092d93e56d9cd63fa3d7 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Fri, 7 Oct 2022 16:58:36 +0300 Subject: [PATCH 6/6] Signal Generator app: UI update (#1829) * Signal Generator: UI update * icons renamed Co-authored-by: Aleksandr Kutuzov --- .../scenes/signal_gen_scene_mco.c | 19 +++++++++++++++--- .../scenes/signal_gen_scene_start.c | 4 ++-- .../signal_generator/views/signal_gen_pwm.c | 16 +++++++-------- assets/icons/Interface/SmallArrowDown_3x5.png | Bin 0 -> 3592 bytes assets/icons/Interface/SmallArrowUp_3x5.png | Bin 0 -> 7976 bytes firmware/targets/f7/api_symbols.csv | 4 +++- 6 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 assets/icons/Interface/SmallArrowDown_3x5.png create mode 100644 assets/icons/Interface/SmallArrowUp_3x5.png diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c index 632b08c75..0855cde0a 100644 --- a/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c @@ -1,12 +1,17 @@ #include "../signal_gen_app_i.h" typedef enum { + LineIndexPin, LineIndexSource, LineIndexDivision, } LineIndex; +static const char* const mco_pin_names[] = { + "13(Tx)", +}; + static const char* const mco_source_names[] = { - "32768", + "32768Hz", "64MHz", "~100K", "~200K", @@ -81,14 +86,22 @@ void signal_gen_scene_mco_on_enter(void* context) { VariableItem* item; + item = variable_item_list_add(var_item_list, "GPIO Pin", COUNT_OF(mco_pin_names), NULL, NULL); + variable_item_set_current_value_index(item, 0); + variable_item_set_current_value_text(item, mco_pin_names[0]); + item = variable_item_list_add( - var_item_list, "Source", COUNT_OF(mco_source_names), mco_source_list_change_callback, app); + var_item_list, + "Frequency", + COUNT_OF(mco_source_names), + mco_source_list_change_callback, + app); variable_item_set_current_value_index(item, 0); variable_item_set_current_value_text(item, mco_source_names[0]); item = variable_item_list_add( var_item_list, - "Division", + "Freq. divider", COUNT_OF(mco_divisor_names), mco_divisor_list_change_callback, app); diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c index 91f6081d8..3c7b9cc32 100644 --- a/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c @@ -16,10 +16,10 @@ void signal_gen_scene_start_on_enter(void* context) { Submenu* submenu = app->submenu; submenu_add_item( - submenu, "PWM", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app); + submenu, "PWM Generator", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app); submenu_add_item( submenu, - "Clock Output", + "Clock Generator", SubmenuIndexClockOutput, signal_gen_scene_start_submenu_callback, app); diff --git a/applications/plugins/signal_generator/views/signal_gen_pwm.c b/applications/plugins/signal_generator/views/signal_gen_pwm.c index 00b4ef267..4afed01a6 100644 --- a/applications/plugins/signal_generator/views/signal_gen_pwm.c +++ b/applications/plugins/signal_generator/views/signal_gen_pwm.c @@ -9,7 +9,7 @@ typedef enum { LineIndexTotalCount } LineIndex; -static const char* const pwm_ch_names[] = {"TIM1(2)", "LPTIM2(4)"}; +static const char* const pwm_ch_names[] = {"2(A7)", "4(A4)"}; struct SignalGenPwm { View* view; @@ -31,8 +31,8 @@ typedef struct { #define ITEM_H 64 / 3 #define ITEM_W 128 -#define VALUE_X 95 -#define VALUE_W 55 +#define VALUE_X 100 +#define VALUE_W 45 #define FREQ_VALUE_X 62 #define FREQ_MAX 1000000UL @@ -126,11 +126,11 @@ static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) { for(uint8_t line = 0; line < LineIndexTotalCount; line++) { if(line == LineIndexChannel) { - line_label = "PWM Channel"; + line_label = "GPIO Pin"; } else if(line == LineIndexFrequency) { line_label = "Frequency"; } else if(line == LineIndexDuty) { - line_label = "Duty Cycle"; + line_label = "Pulse width"; } canvas_set_color(canvas, ColorBlack); @@ -162,9 +162,9 @@ static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontSecondary); if(model->edit_mode) { - uint8_t icon_x = (FREQ_VALUE_X - 1) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6; - canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_4x7); - canvas_draw_icon(canvas, icon_x, text_y + 4, &I_SmallArrowDown_4x7); + uint8_t icon_x = (FREQ_VALUE_X) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6; + canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_3x5); + canvas_draw_icon(canvas, icon_x, text_y + 5, &I_SmallArrowDown_3x5); } } else if(line == LineIndexDuty) { snprintf(val_text, sizeof(val_text), "%d%%", model->duty); diff --git a/assets/icons/Interface/SmallArrowDown_3x5.png b/assets/icons/Interface/SmallArrowDown_3x5.png new file mode 100644 index 0000000000000000000000000000000000000000..1912e5d246268d75a20984bdc8b996d503f3d166 GIT binary patch literal 3592 zcmaJ^c|26>|35C-x5^UI9YaXWW@{#6nHgKQFf!6&%x2Oo#?)9!BwM;9Wo@KIb`_J-tPDJ$FJ{sopYY&`JB)D{aK&a>p5|Uoo!_#RV4uckg>PJ zxe3N?f=5_fSnxjm$+!goB(3RK>|uK>7R2VTsPxkm00?nD~hiA(w8Os#U?fGBt+hg zz1*@k9(vcmw`%2M+s2bV^XZ~Rep!cDjkt7*ouR97xO6^d&-V9`O%09XlMu@YNi8-Y zFJ4C02wc|`0#?J!%=Uw8#9jbGLETc~K#fyo4QzMJrrc*t`Z1yKOF}i=qyrA(;R=9d zNCM_QU}+;1&QH^J2eL%~pH`CZ1aQ~@@X@*Ou^R~Iucn6z0p8a&6os;r0MJfKEDrEH z2o!Z3xoiy(V1NSEp#cf>8vrnSPpTd8@F`H!E-zIIh)V-7*Vw3ifJi9d)2yi(1YAl7 z6l@ke&HmV5B0sGs$W(f%S%ntTI>KArAVAF16S7CQ-ClXWf(h{#VumH8E;wBU5n&|v ze(?Sn!b0U5xq_WSf#8XS&Zm{>QAm}Mf zxb6r@z-3%nMC5?uFxU3I+S|2B{xGJ$CTu=t3_Lt#E)<$%kawIU{MA86p1`g7umS)J zm8{x#y5hp&ev#uHyv=!wb=&N{KseR@S^xl?z-dA7EoBx>;sAilj?jB(rM6VNOTR{R zckQ;}TB+|oCYLZ;4RsiKj3haHH^*mR(M61IblXF9Js;>hOLe0fSHI|Fwk)L1i+`6(J#F)hxb~s4*BT2kQkYsEJce{)S zdDy8hpgF%FV~*K8PdeBPATEB7uCj$+k0^CTzmtA~t;jP~y<~Go>MfZI&q!3t&V0*x ztct#3a(nu1p`YAfqB*t+R`Y3>m|??d7^JZt^XP!SL^7%M5x7XYuu=8lks{&BxMfnu zBc8~P2N;MBHO#M{p!K_uJ)xc54}JACxea5WeJErvpyTb9k)%eEXjbyL=Jw z7=oR?X77%~olyDESZsr-){ZzVLZ{;DFZPe_;k$Np*>o}8G-velGmY$2HIrWtlKo4? zkk|D=`{ZuPVt=^-Ku`dek=3`pSaJrkKEYfoch+Yt98cq zQ|c$-C7!fQv|?maEKOG>bC=jInhI~%gEYtcD&6raO?a3o{7c$&x?DQTgP>QgcTO>> zMe@d>8`?M2^q~0sg8K!d1yUZ19AHz3Lt7U9k6Dvmc$DsA>dBkyOfp^fmlt3Zu_N7&mA?Y8yCrRwV(R#%q>4_nyFE6)*~nd?Hy)eNnqV|C8t-b0YHMgaIDK}S z%W!k5xWDiILC1rRO>J-5?zHu$8)u^7eTeDI>CC>&v8O&qgO2K#=aoOB*q2Toz3(+w zUd4<$iuB4McpN=mW>d^B-rHMQT$#H)x57EuxiG7jR{!vi^4I10PgNdH^@|RblrzfD z6KTH6w5P91>gSTHlg~dt|JyoROeSVPwov`3dRX9NjsofkYBZz$=A6a(S4$}~P#U2_ zzN6o8qI_rTz6LtqJ+s@ErcA2{j9iS3k8`-#3Q0AGWU4ieG*?d^;w}dq9}nqT=4X~= z*3IS(J(x3@qtC?*-+E(oYhRX^Vc^^PX6$>{sZI;2TQ^|-V?|*uSeFRelW9#T37X_t z-1qQl4zFN^IInE})tqx{!hFKabQCe_b@GjA&C}+mtuFPftdmh=*bADQ@N544YO%)3bXt2- zJ6$&FaM-8bw_?PP#Q6F!X`QH;D9>n%1a>SzwG*Cd%{wZ|N4YAk$Wmk)~c^OESWA1;#AJy&C6Dy@rJgG0+;#!a?g<1RC zX5W;x3|%$7Ie%+&c1PWg@oVKd(GH#l>V%KgMW>LZW&y!Nk`s#C_D3HPEi!v{xm=IY z<5D>5nOYK7tsUazA913#d>l2%@|I00Nd1^9%aj=yd@M6|!_pfKwY3k5Z zn2d!Cn@snNHE&<<=Pqx|J9|HmhJ3dj`c>|xk(pQUp+)>_`rypP?qu3R#})n!{`oM- zpTj;wcgjPjN$q2&Iu2dfUYA6t0FT__!z+UfbsGvfj3B;zypv)M*+ zw@Xvy&B~0Dievs2b0O7FLa8e=YFVc3BTLo6e<*GC_GBT^Bh`x`td&0qjUjkA?TfaR2=9g;O=W?8VMu+ZEBM$c~Mq$1%v)l;rgS&|8a`obQpwX zaVQ{D2;6`KgTX+iNC<^YMEDv~i6ngx0)~J?;ey-L0B(vx7^2`v(BBtWV30$mqTFyc zf14Am&|p6zoJIbf9{LX zPx=1Fl7H@t@lUZ(fiuvp+Wwzf{}2fpXlwdU^9mOKv_FL@=y{Hyx%oF${u^n* BDRuw= literal 0 HcmV?d00001 diff --git a/assets/icons/Interface/SmallArrowUp_3x5.png b/assets/icons/Interface/SmallArrowUp_3x5.png new file mode 100644 index 0000000000000000000000000000000000000000..9c6242078d3bcc9a93eb55b6b5f358720ee6662c GIT binary patch literal 7976 zcmeHMc{r49+qV<4gh-`nda|TpHilscGqxyu)`u~RCT1}+3?<2uH6@8`MGviHX_37w zZMKjtDzZnGtV!ORdbZs}_>>X6B1VR>OL zF0RdHrdS)`$`72p+`Paqe(6XV7ncC{aXUx04W0vHFzIB94++E$WRO6l01BClE1+l6 z(aHaVmgv_Jm0=;i5-wdaR5=Qj^5Jm8g`IEAc9fOryTo8GgAEFV(*}l5t);FA3O>zN zQ+(yhT+s52j!;!--(}Lxne}~lZchfJZ&7DglWbi6e9*T`$K$K!+U%=e+3DtNH%P9# z*;m!_ng3%LNH4Vj>D>H5+OBEw^f_7SX1B&`)REeXzRxko@AiF}{DkIHKFb$)I#57Z zVNqhqQTa}+k=ts?ip270UWv)W?b;#tb8uhdo+?$VA4Y}H&zdjGGvY_Wr$cNjA9MzD zRzh2A!WnK?=o$mZ^=3@gvLxLgBT@xqBkI()vKuhox**zkQQhhww17LM;5sQiRJGq} z!HIF}Ze>_we;Hj%N5&IGlcrehy=GR^pJf{vpP(e-Jlup|q)4dsJ{E~6IRw9C^+ZTG z^a~j&pl9dn%k8w#y?87pNf56r75*ysYeZWGdir+T9rY;9Ct~ew22k~yF!|U=eovuL zL;uiJ&FbXOGoXhJa?-h*i#@|$KQzJ~oWr}|rFKHqvM{|-M4uW*EH3iC)Ws|=;h@~} z%89b%-8|=oL-*N5iZgh5FK!W6ehv#4rCsc7O##O*I35a`+oNzgTAC@rur=g&f+=>L z!$xd=Ep20=GW3&~t(ivT4%Ulq(sR`U`%PQ+nr)R#0^5ffTc+CE-9HL(2FNX*qN4R?@rjaTh2E3UMNPWe2tDuvCxsPT`p)Ci zi?lT6>;k_xVdz2SHl1?D@>TI^y||lqmOg*;$v8C{;A4ccNZ%dy;t3M#6JPjczr&!k zYUUfCVG9$Nz8&_h3N6qMf!j@*d+t1@M?a*dd4oi-gq`|){awDe*fGhs$~y%@DlXd; zYF{zY-x{d)MZPn}bg_NeeaXB1s^e>?g0HIV6dD zQeUg=!9gA?nC}q2-5w#eP+=l^tm~m?eDd&Vi>Lvt&cfYxEBh`eZ}xhhpZCit`<3 zu3XKn6Q%?{h!e_bs1tPSI>4BSaZD{(?s%%p;9Q9+kQOvrK;}Wnb~bKYm7@DA-<#vuhr8vPZ2nO0E8po8GGSLhjJuxGZOl*hqQRln6)}(d9IpFNF|LgK zT}!>bc>esK-teP?$Szbvp6Le@+HFl+Eyc@{i4)>ot!KEdXhQu}gucy8%hoQmqXMS+ zqd?CY5`&qg1J`}AU%O&O2l=GKUq;6x@h&jVu?K<~w|2&0Zt$NJucN(A<=^Ek1Jk#Y z#kzdF(U(xMFWpq4+_)aq?eW6Xl{{)7qBr8HDD6fFyml2^d}67Wo>H7#3Fi+@H{}$- z2c=ydWFmGeL`-w9T{x39)%y!(`5`5CtW_w>_tsfAH5si^=(+AY?@os zA=JJ5xP9u!HU1^^mrL7^-@7Pi)E!Zc%bQPH4bRZIUkOi)^(=X`QaaH2rYbbpUZTNA z+Ukpb6L|gw?GA&%#U%`-7#Ufa85#Y0GXQP@=^2+ec6OaxBbzHY$Fmxt(kez%6`Mg7 zsGF@=e9ATtWnM7^vT%1ck0cJuCu0x_7Kl3oE(FI!gm^qwI1jp7>mhAz9f&A$U=Iyd zBqzVy<#p2gO2s0^YwBc2DcAY()ko!QN8u1;X2`CAA@g%_F}Z{lZqaEj-Ucp@A~=G_ z5K|Lks;5Akvq+Fy0t~Lq!Wu z8rQZjNyBQCVV`k=(uL(IQnKCC#m!)y*vlF9gjmO*VNrj1mj(>@ZR*~^D7hI~U+b;O ziI4#oaEFCVt}pJZ!;Z9iJeem196iY+rfOE33s#(|G3>>bOLOf|nNf{ji{Ve-aeB#y zHn#0i5Y6*KNdC*#YiZp*@X@#F6L#?jJfv%hInZUFQkUb-0*T2Y)dLy&2aR1_N^d;t zAV28nFdnWayUUDM(Y{$mpC~iE8>+u3nmvEAa5c&OIEE|E$(rgPR9H8~f0cmXnq92w zLW=W%RK{Ias*fyYMUU(?13fE1z@9fXX$~_T>jy%=Wvz`(qvl>O#?_5|Qx@;bNUWC5 z6&@WZEo`-IiwHVS7D%ki+P)eXwdVWY{YniqJh8f;6_6dpcy-Y?Fgn}+bC)YOD#K)C z_M5HL8oukwJ*`f#wY(npu{*Hy@>h8VJM}`cCAhb+4&38ieT6y|q$N>RF7!IO?$O%* z(Ram9NCSHl)0VWGAV0-5ZJ90Jx>(!109@4N|U{EOVz&9%)Y5qEcXbJHxhRZFAH~98N-pWGX*z`pK z&F>bHZy45sIVznR8XWnyM#v)cW&!-p=Co?jF8+nEn)gWzaJhU_m`ML5L&jBnSJ<0= zk!imrOz;8{Lh1m@KB3AQ&w`) z{5X?sSrgW8Zwx7KJ*IJN=Phabv*^%cCi7Qm*~Zq08;6g=oi|ZK9vH1$-SaAX)Q2ru zx}`6QX5?=8&iLH5cOFnVd1FCB*i1bZe*xwV%}H5JacBr^0Fgxzv2~s@1pEGQilVED6)Uzcl+I2v{Q)WhMM%ee_ zQv6RwtxAs)JWUN-{af*^fvuQURruvQmi~$+iTs0;gNn1bS;DN#rkL=;@N;}Fo)y@$ z*s|L5wIXKazg+qyc5vTw-RI`d6EE;yXtN1Wp{k%%a@)~2B)YufaN>dPH2gZ;!^=i+SyH{S5H4)M7;mj%%Cnbm{tk?e7~r*luqZ_qD@JrvE$?0)|ye+oXyl~VB*ar$}LLR7%yTQ!o8TMSgrV7<9wsju*UGi{m-^$Zv6;BLwVu;$N8ZdoxK4f7?eu2T#G$TL zGM#wE^Hh5<^JbGxQ|p-=g4np2MI<^>(xjA-{=wj>q>_eGu5Cq|l-Fjj2drzK!(%fK z7QKWe%jW0i2X$(8YNK=>-lvW9NpjQ|Jr{$;x1AeOc&%^_^BN{*WZV!wi!>0BIH;qX^;S8|u}D5$kL*SmB`3h|ue z;qdDTw{CLYIY)phYAKf}E>WVKOoL77%6pNTb4N$hpq&Lp1%faAl0}j^kq6H_4M#;Z z<4Q~}n#5sKvH54q6>{Y2&W^{`8%LU;jGObP9Scv?1;p7~ST|%Op;cK9KfC3W?DKnl z+3~p}dE&Vi+ZEgUszkiu02#y5e5(}f{#Eql+53_6>5~ol9*2E*Xbq)D^F@ZwhCjzf z*1AR8njJDrGHY{1(KHrGMI0t|*45nOMgPT!_Nev_q^q-Qk4mPfdPHYp{)Nm$y%hX; z>x;0W9@_k;*N7nfV1nYsNAP0X12U@?^PBu4(ju-o#XD&@(Ti(}4-cD;Of$bQ=UESj z4h;qlpDYu&f98I!jyvQO;oGQl@_oOLSN&!_mUepIQFqm^eC%D5a5ns`%Jx(Hpb%yC zfC?2)+ap=b{xeSs8-Gqqi~T8P30LDX@vxnSqYlv~-;oQcQx6W;O$>PN&E1={cbBeqlz9E}qUsjw?(o~4C-m)a{b!hf zhfTNhD}FAkoRt{1>d3mjxqoxTJ9s7an4Qml%GZDtPQak)vxH2=wA|cl<|Z#w`^osv z?S&}>R3&RIzqsy3PJU8{GjqodS%p&zCwmt;hn6x%^`2{W&xUn~ukn5#E&{ix= zY@V8W*^Rtcd1u?_w%|t9mtPB5y4N$7iYW4W(X^#$Yo?o4GKaPhRKGkX5-nR_N+{dq z8dn~0TdCyw+J$#Hs>v92_X)o-45zOD#n^5CBZu7xt{+QiCo3wNZ{3|#x_zbROWw*G zK_3A$z3c6$yem4u{~2ZUiREHiGJUzXH26gKGG!=y9NYHG z^5B?C^Udwe4!YY1zIXP29Z>pMa#5ToM4OY1>Rm>$lxm|M?;?8Ln zXw(Z%Tp$PMFXcUXvu8?f>i9d8@+&FL-$GWc=B=j)ok~@Q#bsN!ZvDp3oAUXqpsQ;- z7nc~00(?ktw6s7I=u|a4k?u)S3!nlImB68^AHcv9yh&`3C&`OK!+@vCs=y!$5d%J= zVF|Tl7?F-rOph~3w#N_I5srHkw25GSJz?DdGyp&)vGJe)st=8Y4#0pnaM3_}U91iU zZK$xlF2kQxgbeTjl+6HU<0|Mw_z(?6^23lR6!{MlL z5NdR$mpV*aTU#9pSBJwPfChvWNMqvzAT-vVb%^g6SQ3lCq%hbNIt{driT9-Yu`ysU zFb?|FKPto0@;7)I>jw(}AL;>khB{0Qs!pY<|IvcQ#`yyvKOFi?3zi-5Jx1Mz#G?B# z2_&39iN@aZX9ye8?=k%!AOQ700T2nlIl%B^`fTt)B&d^oNK{}h7T`AQPd=NNSz7&O zvCg3vh055l0#@r!nrsUBKX|r2vcbn6BLU2R!~M%RHk1J^OG`ACPVifI&kTzJ0}?eN zg@}eDu*Pr$Lli;_ss)4Lu-Z5%(nuSNGQeqQ8DkBQe=s+rvDkPTf%L061u#dD5d^X) z837@Zw4e|qLfaFftqCVX2%ZEjJe~}PdTMI?0pc)|0;DqD=dV10X}~lz@hA-llBfxT zAhn2ih_(h%3!aX*78IIa!0)Pd6e`JmFgsJ}sSbcq?`88r)^?&E&2TfQKlL7>6%%oE{=wPvdB1aSd zbB$>Hk2L}?wr>BI%zUpg_65L;PJnC{K%32 z<`f{%Ka>0|e*dBCAG-b)1Aj~TpX~aFuD`{=-%|c3yZ+zk68`<&kVFHX&N#rEU;c7n zC-BxNU}a&41FmapYdPIl`hXU<=Rp%JR}}wFQ=qenVd})<;u4WsKe@S5)8zo6Alu9m zCpaw3Cn>kR_cTri5Q&*#4eW$E2_=tP9#;c@fOl}?9|Uf;07kgXaEGw@h905+0