Sfoglia il codice sorgente

single static pointer to an active instance

this addresses the `furi_hal_serial_control_is_busy` bug
jblanked 9 mesi fa
parent
commit
cba8bb5e6c
1 ha cambiato i file con 35 aggiunte e 66 eliminazioni
  1. 35 66
      flipper_http/flipper_http.c

+ 35 - 66
flipper_http/flipper_http.c

@@ -153,22 +153,26 @@ static void get_timeout_timer_callback(void *context)
 }
 
 static void flipper_http_rx_callback(const char *line, void *context); // forward declaration
+// Instead of two globals, we use a single static pointer to the active instance.
+static FlipperHTTP *active_fhttp = NULL;
 
-// UART initialization function
-/**
- * @brief      Initialize UART.
- * @return     FlipperHTTP context if the UART was initialized successfully, NULL otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
 FlipperHTTP *flipper_http_alloc()
 {
-    FlipperHTTP *fhttp = (FlipperHTTP *)malloc(sizeof(FlipperHTTP));
+    // If an active instance already exists, free it first.
+    if (active_fhttp != NULL)
+    {
+        FURI_LOG_E(HTTP_TAG, "Existing UART instance detected, freeing previous instance.");
+        flipper_http_free(active_fhttp);
+        active_fhttp = NULL;
+    }
+
+    FlipperHTTP *fhttp = malloc(sizeof(FlipperHTTP));
     if (!fhttp)
     {
         FURI_LOG_E(HTTP_TAG, "Failed to allocate FlipperHTTP.");
         return NULL;
     }
-    memset(fhttp, 0, sizeof(FlipperHTTP)); // Initialize allocated memory to zero
+    memset(fhttp, 0, sizeof(FlipperHTTP));
 
     fhttp->flipper_http_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
     if (!fhttp->flipper_http_stream)
@@ -189,7 +193,7 @@ FlipperHTTP *flipper_http_alloc()
 
     furi_thread_set_name(fhttp->rx_thread, "FlipperHTTP_RxThread");
     furi_thread_set_stack_size(fhttp->rx_thread, 1024);
-    furi_thread_set_context(fhttp->rx_thread, fhttp); // Corrected context
+    furi_thread_set_context(fhttp->rx_thread, fhttp);
     furi_thread_set_callback(fhttp->rx_thread, flipper_http_worker);
 
     fhttp->handle_rx_line_cb = flipper_http_rx_callback;
@@ -198,24 +202,11 @@ FlipperHTTP *flipper_http_alloc()
     furi_thread_start(fhttp->rx_thread);
     fhttp->rx_thread_id = furi_thread_get_id(fhttp->rx_thread);
 
-    // Handle when the UART control is busy to avoid furi_check failed
-    if (furi_hal_serial_control_is_busy(UART_CH))
-    {
-        FURI_LOG_E(HTTP_TAG, "UART control is busy.");
-        // Cleanup resources
-        furi_thread_flags_set(fhttp->rx_thread_id, WorkerEvtStop);
-        furi_thread_join(fhttp->rx_thread);
-        furi_thread_free(fhttp->rx_thread);
-        furi_stream_buffer_free(fhttp->flipper_http_stream);
-        free(fhttp);
-        return NULL;
-    }
-
+    // Acquire UART control
     fhttp->serial_handle = furi_hal_serial_control_acquire(UART_CH);
     if (!fhttp->serial_handle)
     {
         FURI_LOG_E(HTTP_TAG, "Failed to acquire UART control - handle is NULL");
-        // Cleanup resources
         furi_thread_flags_set(fhttp->rx_thread_id, WorkerEvtStop);
         furi_thread_join(fhttp->rx_thread);
         furi_thread_free(fhttp->rx_thread);
@@ -224,29 +215,17 @@ FlipperHTTP *flipper_http_alloc()
         return NULL;
     }
 
-    // Initialize UART with acquired handle
+    // Initialize and enable UART
     furi_hal_serial_init(fhttp->serial_handle, BAUDRATE);
-
-    // Enable RX direction
     furi_hal_serial_enable_direction(fhttp->serial_handle, FuriHalSerialDirectionRx);
-
-    // Start asynchronous RX with the corrected callback and context
-    furi_hal_serial_async_rx_start(fhttp->serial_handle, _flipper_http_rx_callback, fhttp, false); // Corrected context
-
-    // Wait for the TX to complete to ensure UART is ready
+    furi_hal_serial_async_rx_start(fhttp->serial_handle, _flipper_http_rx_callback, fhttp, false);
     furi_hal_serial_tx_wait_complete(fhttp->serial_handle);
 
-    // Allocate the timer for handling timeouts
-    fhttp->get_timeout_timer = furi_timer_alloc(
-        get_timeout_timer_callback, // Callback function
-        FuriTimerTypeOnce,          // One-shot timer
-        fhttp                       // Corrected context
-    );
-
+    // Allocate the timeout timer
+    fhttp->get_timeout_timer = furi_timer_alloc(get_timeout_timer_callback, FuriTimerTypeOnce, fhttp);
     if (!fhttp->get_timeout_timer)
     {
         FURI_LOG_E(HTTP_TAG, "Failed to allocate HTTP request timeout timer.");
-        // Cleanup resources
         furi_hal_serial_async_rx_stop(fhttp->serial_handle);
         furi_hal_serial_disable_direction(fhttp->serial_handle, FuriHalSerialDirectionRx);
         furi_hal_serial_control_release(fhttp->serial_handle);
@@ -258,15 +237,12 @@ FlipperHTTP *flipper_http_alloc()
         free(fhttp);
         return NULL;
     }
-
-    // Set the timer thread priority if needed
     furi_timer_set_thread_priority(FuriTimerThreadPriorityElevated);
 
-    fhttp->last_response = (char *)malloc(RX_BUF_SIZE);
+    fhttp->last_response = malloc(RX_BUF_SIZE);
     if (!fhttp->last_response)
     {
         FURI_LOG_E(HTTP_TAG, "Failed to allocate memory for last_response.");
-        // Cleanup resources
         furi_timer_free(fhttp->get_timeout_timer);
         furi_hal_serial_async_rx_stop(fhttp->serial_handle);
         furi_hal_serial_disable_direction(fhttp->serial_handle, FuriHalSerialDirectionRx);
@@ -279,21 +255,15 @@ FlipperHTTP *flipper_http_alloc()
         free(fhttp);
         return NULL;
     }
-    memset(fhttp->last_response, 0, RX_BUF_SIZE); // Initialize last_response
-
+    memset(fhttp->last_response, 0, RX_BUF_SIZE);
     fhttp->state = IDLE;
 
-    // FURI_LOG_I(HTTP_TAG, "UART initialized successfully.");
+    // Track the active instance globally.
+    active_fhttp = fhttp;
+
     return fhttp;
 }
 
-// Deinitialize UART
-/**
- * @brief      Deinitialize UART.
- * @return     void
- * @param fhttp The FlipperHTTP context
- * @note       This function will stop the asynchronous RX, release the serial handle, and free the resources.
- */
 void flipper_http_free(FlipperHTTP *fhttp)
 {
     if (!fhttp)
@@ -306,43 +276,42 @@ void flipper_http_free(FlipperHTTP *fhttp)
         FURI_LOG_E(HTTP_TAG, "UART handle is NULL. Already deinitialized?");
         return;
     }
-    // Stop asynchronous RX
+    // Stop asynchronous RX and clean up UART
     furi_hal_serial_async_rx_stop(fhttp->serial_handle);
-
-    // Release and deinitialize the serial handle
     furi_hal_serial_disable_direction(fhttp->serial_handle, FuriHalSerialDirectionRx);
-    furi_hal_serial_control_release(fhttp->serial_handle);
     furi_hal_serial_deinit(fhttp->serial_handle);
+    furi_hal_serial_control_release(fhttp->serial_handle);
 
-    // Signal the worker thread to stop
+    // Signal and free the worker thread
     furi_thread_flags_set(fhttp->rx_thread_id, WorkerEvtStop);
-    // Wait for the thread to finish
     furi_thread_join(fhttp->rx_thread);
-    // Free the thread resources
     furi_thread_free(fhttp->rx_thread);
 
     // Free the stream buffer
     furi_stream_buffer_free(fhttp->flipper_http_stream);
 
-    // Free the timer
+    // Free the timer, if allocated
     if (fhttp->get_timeout_timer)
     {
         furi_timer_free(fhttp->get_timeout_timer);
         fhttp->get_timeout_timer = NULL;
     }
 
-    // Free the last response
+    // Free the last_response buffer
     if (fhttp->last_response)
     {
         free(fhttp->last_response);
         fhttp->last_response = NULL;
     }
 
-    // Free the FlipperHTTP context
-    free(fhttp);
-    fhttp = NULL;
+    // If this instance is the active instance, clear the static pointer.
+    if (active_fhttp == fhttp)
+    {
+        free(active_fhttp);
+        active_fhttp = NULL;
+    }
 
-    // FURI_LOG_I("FlipperHTTP", "UART deinitialized successfully.");
+    free(fhttp);
 }
 
 /**