Răsfoiți Sursa

component/bt : modify alarm APIs to be safely accessible from multiple tasks

Tian Hao 9 ani în urmă
părinte
comite
e384c7c014

+ 5 - 0
components/bt/bluedroid/btc/core/btc_main.c

@@ -16,6 +16,7 @@
 #include "btc_main.h"
 #include "future.h"
 #include "esp_err.h"
+#include "alarm.h"
 
 static future_t *main_future[BTC_MAIN_FUTURE_NUM];
 
@@ -60,6 +61,8 @@ void btc_init_callback(void)
 
 static void btc_init_bluetooth(void)
 {
+    osi_alarm_create_mux();
+    osi_alarm_init();
     bte_main_boot_entry(btc_init_callback);
 }
 
@@ -67,6 +70,8 @@ static void btc_init_bluetooth(void)
 static void btc_deinit_bluetooth(void)
 {
     bte_main_shutdown();
+    osi_alarm_deinit();
+    osi_alarm_delete_mux();
     future_ready(*btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE), FUTURE_SUCCESS);
 }
 

+ 0 - 2
components/bt/bluedroid/main/bte_main.c

@@ -144,8 +144,6 @@ int bte_main_boot_entry(bluedroid_init_done_cb_t cb)
     //data_dispatcher_register_default(hci->event_dispatcher, btu_hci_msg_queue);
     hci->set_data_queue(btu_hci_msg_queue);
 
-    osi_alarm_init();
-
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
     //bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE);
 #endif

+ 147 - 32
components/bt/bluedroid/osi/alarm.c

@@ -36,11 +36,73 @@
 #define BT_ALARM_FREE_WAIT_TICKS    100
 #define BT_ALARM_CHG_PERIOD_WAIT_TICKS  100
 
+enum {
+    ALARM_STATE_IDLE,
+    ALARM_STATE_OPEN,
+};
+
+static osi_mutex_t alarm_mutex;
+static int alarm_state;
+
 static struct alarm_t alarm_cbs[ALARM_CBS_NUM];
 
+static int alarm_free(osi_alarm_t *alarm);
+
+int osi_alarm_create_mux(void)
+{
+    if (alarm_state != ALARM_STATE_IDLE) {
+        LOG_WARN("%s, invalid state %d\n", __func__, alarm_state);
+        return -1;
+    }
+    osi_mutex_new(&alarm_mutex);
+    return 0;
+}
+
+int osi_alarm_delete_mux(void)
+{
+    if (alarm_state != ALARM_STATE_IDLE) {
+        LOG_WARN("%s, invalid state %d\n", __func__, alarm_state);
+        return -1;
+    }
+    osi_mutex_free(&alarm_mutex);
+    return 0;
+}
+    
 void osi_alarm_init(void)
 {
-    memset(&alarm_cbs[0], 0x00, sizeof(alarm_cbs));
+    assert(alarm_mutex != NULL);
+    
+    osi_mutex_lock(&alarm_mutex);
+    if (alarm_state != ALARM_STATE_IDLE) {
+        LOG_WARN("%s, invalid state %d\n", __func__, alarm_state);
+        goto end;
+    }
+    memset(alarm_cbs, 0x00, sizeof(alarm_cbs));
+    alarm_state = ALARM_STATE_OPEN;
+    
+end:
+    osi_mutex_unlock(&alarm_mutex);
+}
+
+void osi_alarm_deinit(void)
+{
+    assert(alarm_mutex != NULL);
+    
+    osi_mutex_lock(&alarm_mutex);
+    if (alarm_state != ALARM_STATE_OPEN) {
+        LOG_WARN("%s, invalid state %d\n", __func__, alarm_state);
+        goto end;
+    }
+    
+    for (int i = 0; i < ALARM_CBS_NUM; i++) {
+        if (alarm_cbs[i].alarm_hdl != NULL) {
+            alarm_free(&alarm_cbs[i]);
+        }
+    }
+    alarm_state = ALARM_STATE_IDLE;
+
+end:
+    osi_mutex_unlock(&alarm_mutex);
 }
 
 static struct alarm_t *alarm_cbs_lookfor_available(void)
@@ -75,88 +137,141 @@ static void alarm_cb_handler(TimerHandle_t xTimer)
 
 osi_alarm_t *osi_alarm_new(char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire)
 {
-    struct alarm_t *timer_id;
-    TimerHandle_t t;
-
-    if (timer_expire == 0) {
-        timer_expire = 1000;
+    assert(alarm_mutex != NULL);
+
+    struct alarm_t *timer_id = NULL;
+    
+    osi_mutex_lock(&alarm_mutex);
+    if (alarm_state != ALARM_STATE_OPEN) {
+        LOG_ERROR("%s, invalid state %d\n", __func__, alarm_state);
+        timer_id = NULL;
+        goto end;
     }
-
-    /* TODO mutex lock */
+    
     timer_id = alarm_cbs_lookfor_available();
+
     if (!timer_id) {
-        LOG_ERROR("%s full\n", __func__);
-        return NULL;
+        LOG_ERROR("%s alarm_cbs exhausted\n", __func__);
+        timer_id = NULL;
+        goto end;
+    }
+
+    if (timer_expire == 0) {
+        timer_expire = 1000;
     }
 
-    t = xTimerCreate(alarm_name, timer_expire / portTICK_PERIOD_MS, pdFALSE, timer_id, alarm_cb_handler);
+    TimerHandle_t t = xTimerCreate(alarm_name, timer_expire / portTICK_PERIOD_MS, pdFALSE, timer_id, alarm_cb_handler);
     if (!t) {
-        LOG_ERROR("%s error\n", __func__);
-        return NULL;
+        LOG_ERROR("%s failed to create timer\n", __func__);
+        timer_id = NULL;
+        goto end;
     }
 
     timer_id->alarm_hdl = t;
     timer_id->cb = callback;
     timer_id->cb_data = data;
-    /* TODO mutex unlock */
 
+end:
+    osi_mutex_unlock(&alarm_mutex);
     return timer_id;
 }
 
-int osi_alarm_free(osi_alarm_t *alarm)
+static int alarm_free(osi_alarm_t *alarm)
 {
-    if (!alarm) {
+    if (!alarm || alarm->alarm_hdl == NULL) {
         LOG_ERROR("%s null\n", __func__);
         return -1;
     }
 
     if (xTimerDelete(alarm->alarm_hdl, BT_ALARM_FREE_WAIT_TICKS) != pdPASS) {
-        LOG_ERROR("%s error\n", __func__);
+        LOG_ERROR("%s alarm delete error\n", __func__);
         return -2;
     }
+    
+    memset(alarm, 0, sizeof(osi_alarm_t));
+    return 0;
+}
 
-    /* TODO mutex lock */
-    memset(alarm, 0x00, sizeof(osi_alarm_t));
-    /* TODO mutex unlock */
+int osi_alarm_free(osi_alarm_t *alarm)
+{
+    assert(alarm_mutex != NULL);
+    
+    int ret = 0;
+    osi_mutex_lock(&alarm_mutex);
+    if (alarm_state != ALARM_STATE_OPEN) {
+        LOG_ERROR("%s, invalid state %d\n", __func__, alarm_state);
+        ret = -3;
+        goto end;
+    }
+    alarm_free(alarm);
 
-    return 0;
+end:
+    osi_mutex_unlock(&alarm_mutex);
+    return ret;
 }
 
 
 int osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
 {
-    if (!alarm) {
+    assert(alarm_mutex != NULL);
+    
+    int ret = 0;
+    osi_mutex_lock(&alarm_mutex);
+    if (alarm_state != ALARM_STATE_OPEN) {
+        LOG_ERROR("%s, invalid state %d\n", __func__, alarm_state);
+        ret = -3;
+        goto end;
+    }
+    
+    if (!alarm || alarm->alarm_hdl == NULL) {
         LOG_ERROR("%s null\n", __func__);
-        return -1;
+        ret = -1;
+        goto end;
     }
-
+    
     if (xTimerChangePeriod(alarm->alarm_hdl, timeout / portTICK_PERIOD_MS, BT_ALARM_CHG_PERIOD_WAIT_TICKS) != pdPASS) {
         LOG_ERROR("%s chg period error\n", __func__);
-        return -2;
+        ret = -2;
+        goto end;
     }
 
     if (xTimerStart(alarm->alarm_hdl, BT_ALARM_START_WAIT_TICKS) != pdPASS) {
         LOG_ERROR("%s start error\n", __func__);
-        return -3;
+        ret = -2;
+        goto end;
     }
 
-    return 0;
+end:
+    osi_mutex_unlock(&alarm_mutex);
+    return ret;
 }
 
 
 int osi_alarm_cancel(osi_alarm_t *alarm)
 {
-    if (!alarm) {
+    int ret = 0;
+    osi_mutex_lock(&alarm_mutex);
+    if (alarm_state != ALARM_STATE_OPEN) {
+        LOG_ERROR("%s, invalid state %d\n", __func__, alarm_state);
+        ret = -3;
+        goto end;
+    }
+    
+    if (!alarm || alarm->alarm_hdl == NULL) {
         LOG_ERROR("%s null\n", __func__);
-        return -1;
+        ret = -1;
+        goto end;
     }
 
     if (xTimerStop(alarm->alarm_hdl, BT_ALARM_STOP_WAIT_TICKS) != pdPASS) {
-        LOG_ERROR("%s error\n", __func__);
-        return -2;
+        LOG_ERROR("%s failed to stop timer\n", __func__);
+        ret = -2;
+        goto end;
     }
 
-    return 0;
+end:
+    osi_mutex_unlock(&alarm_mutex);
+    return ret;
 }
 
 static uint32_t alarm_current_tick(void)

+ 3 - 0
components/bt/bluedroid/osi/include/alarm.h

@@ -35,7 +35,10 @@ typedef struct alarm_t {
     void *cb_data;
 } osi_alarm_t;
 
+int osi_alarm_create_mux(void);
+int osi_alarm_delete_mux(void);
 void osi_alarm_init(void);
+void osi_alarm_deinit(void);
 
 // Creates a new alarm object. The returned object must be freed by calling
 // |alarm_free|. Returns NULL on failure.