component/bt : modify OSI thread of bluedroid

abstract of OSI thread to make bluedroid more compatible with different OS.
This commit is contained in:
baohongde 2018-09-14 17:24:25 +08:00
parent 28e0a17e0a
commit faf23df19a
15 changed files with 581 additions and 444 deletions

View File

@ -189,6 +189,7 @@ if(CONFIG_BT_ENABLED)
"bluedroid/osi/mutex.c" "bluedroid/osi/mutex.c"
"bluedroid/osi/osi.c" "bluedroid/osi/osi.c"
"bluedroid/osi/semaphore.c" "bluedroid/osi/semaphore.c"
"bluedroid/osi/thread.c"
"bluedroid/stack/a2dp/a2d_api.c" "bluedroid/stack/a2dp/a2d_api.c"
"bluedroid/stack/a2dp/a2d_sbc.c" "bluedroid/stack/a2dp/a2d_sbc.c"
"bluedroid/stack/avct/avct_api.c" "bluedroid/stack/avct/avct_api.c"

View File

@ -29,6 +29,7 @@
#include "osi/alarm.h" #include "osi/alarm.h"
#include "osi/thread.h" #include "osi/thread.h"
#include "stack/btm_api.h" #include "stack/btm_api.h"
#include "stack/btu.h"
#include "bta/bta_api.h" #include "bta/bta_api.h"
#include "bta/bta_sys.h" #include "bta/bta_sys.h"
#include "bta_sys_int.h" #include "bta_sys_int.h"
@ -571,7 +572,7 @@ void bta_sys_sendmsg(void *p_msg)
// there is a procedure in progress that can schedule a task via this // there is a procedure in progress that can schedule a task via this
// message queue. This causes |btu_bta_msg_queue| to get cleaned up before // message queue. This causes |btu_bta_msg_queue| to get cleaned up before
// it gets used here; hence we check for NULL before using it. // it gets used here; hence we check for NULL before using it.
if (btu_task_post(SIG_BTU_BTA_MSG, p_msg, TASK_POST_BLOCKING) != TASK_POST_SUCCESS) { if (btu_task_post(SIG_BTU_BTA_MSG, p_msg, OSI_THREAD_BLOCKING) == false) {
osi_free(p_msg); osi_free(p_msg);
} }
} }
@ -591,7 +592,7 @@ void bta_alarm_cb(void *data)
assert(data != NULL); assert(data != NULL);
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data; TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
btu_task_post(SIG_BTU_BTA_ALARM, p_tle, TASK_POST_BLOCKING); btu_task_post(SIG_BTU_BTA_ALARM, p_tle, OSI_THREAD_BLOCKING);
} }
void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms) void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms)

View File

@ -47,9 +47,13 @@
#endif /* #if BTC_HF_CLIENT_INCLUDED */ #endif /* #if BTC_HF_CLIENT_INCLUDED */
#endif /* #if CONFIG_BT_CLASSIC_ENABLED */ #endif /* #if CONFIG_BT_CLASSIC_ENABLED */
#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTC_TASK_STACK_SIZE (CONFIG_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
#define BTC_TASK_NAME "btcT"
#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6)
#define BTC_TASK_QUEUE_LEN 60
static xTaskHandle xBtcTaskHandle = NULL; static osi_thread_t *btc_thread;
static xQueueHandle xBtcQueue = 0;
static btc_func_t profile_tab[BTC_PID_NUM] = { static btc_func_t profile_tab[BTC_PID_NUM] = {
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL }, [BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
@ -96,38 +100,40 @@ static btc_func_t profile_tab[BTC_PID_NUM] = {
** **
** Description Process profile Task Thread. ** Description Process profile Task Thread.
******************************************************************************/ ******************************************************************************/
static void btc_task(void *arg) static void btc_thread_handler(void *arg)
{ {
btc_msg_t msg; btc_msg_t *msg = (btc_msg_t *)arg;
for (;;) { BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, msg->arg);
if (pdTRUE == xQueueReceive(xBtcQueue, &msg, (portTickType)portMAX_DELAY)) { switch (msg->sig) {
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
switch (msg.sig) {
case BTC_SIG_API_CALL: case BTC_SIG_API_CALL:
profile_tab[msg.pid].btc_call(&msg); profile_tab[msg->pid].btc_call(msg);
break; break;
case BTC_SIG_API_CB: case BTC_SIG_API_CB:
profile_tab[msg.pid].btc_cb(&msg); profile_tab[msg->pid].btc_cb(msg);
break; break;
default: default:
break; break;
} }
if (msg.arg) {
osi_free(msg.arg); if (msg->arg) {
} osi_free(msg->arg);
}
} }
osi_free(msg);
} }
static bt_status_t btc_task_post(btc_msg_t *msg, task_post_t timeout) static bt_status_t btc_task_post(btc_msg_t *msg, osi_thread_blocking_t blocking)
{ {
if (msg == NULL) { btc_msg_t *lmsg;
return BT_STATUS_PARM_INVALID;
lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t));
if (lmsg == NULL) {
return BT_STATUS_NOMEM;
} }
if (xQueueSend(xBtcQueue, msg, timeout) != pdTRUE) { memcpy(lmsg, msg, sizeof(btc_msg_t));
BTC_TRACE_ERROR("Btc Post failed\n");
if (osi_thread_post(btc_thread, btc_thread_handler, lmsg, 0, blocking) == false) {
return BT_STATUS_BUSY; return BT_STATUS_BUSY;
} }
@ -159,17 +165,18 @@ bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg
lmsg.arg = NULL; lmsg.arg = NULL;
} }
return btc_task_post(&lmsg, TASK_POST_BLOCKING); return btc_task_post(&lmsg, OSI_THREAD_BLOCKING);
} }
int btc_init(void) int btc_init(void)
{ {
xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_LEN, sizeof(btc_msg_t)); btc_thread = osi_thread_create("BTC_TASK", BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 1);
xTaskCreatePinnedToCore(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle, BTC_TASK_PINNED_TO_CORE); if (btc_thread == NULL) {
if (xBtcTaskHandle == NULL || xBtcQueue == 0){
return BT_STATUS_NOMEM; return BT_STATUS_NOMEM;
} }
btc_gap_callback_init(); btc_gap_callback_init();
#if SCAN_QUEUE_CONGEST_CHECK #if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_init(); btc_adv_list_init();
@ -180,20 +187,18 @@ int btc_init(void)
void btc_deinit(void) void btc_deinit(void)
{ {
vTaskDelete(xBtcTaskHandle); osi_thread_free(btc_thread);
vQueueDelete(xBtcQueue); btc_thread = NULL;
#if SCAN_QUEUE_CONGEST_CHECK #if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_deinit(); btc_adv_list_deinit();
#endif #endif
xBtcTaskHandle = NULL;
xBtcQueue = 0;
} }
bool btc_check_queue_is_congest(void) bool btc_check_queue_is_congest(void)
{ {
UBaseType_t wait_size = uxQueueMessagesWaiting(xBtcQueue); if (osi_thread_queue_wait_size(btc_thread, 0) >= QUEUE_CONGEST_SIZE) {
if(wait_size >= QUEUE_CONGEST_SIZE) {
return true; return true;
} }
return false; return false;
} }

View File

@ -45,6 +45,13 @@
#if (BTC_AV_SINK_INCLUDED == TRUE) #if (BTC_AV_SINK_INCLUDED == TRUE)
/* Macro */
#define BTC_A2DP_SINK_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTC_A2DP_SINK_TASK_STACK_SIZE (CONFIG_A2DP_SINK_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
#define BTC_A2DP_SINK_TASK_NAME "BtA2dSinkT"
#define BTC_A2DP_SINK_TASK_PRIO (configMAX_PRIORITIES - 3)
/***************************************************************************** /*****************************************************************************
** Constants ** Constants
*****************************************************************************/ *****************************************************************************/
@ -64,10 +71,6 @@ enum {
BTC_A2DP_SINK_STATE_SHUTTING_DOWN = 2 BTC_A2DP_SINK_STATE_SHUTTING_DOWN = 2
}; };
enum {
BTC_A2DP_SINK_DATA_EVT = 0,
};
/* /*
* CONGESTION COMPENSATION CTRL :: * CONGESTION COMPENSATION CTRL ::
* *
@ -90,6 +93,11 @@ enum {
/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */ /* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18) #define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18)
typedef struct {
uint32_t sig;
void *param;
} a2dp_sink_task_evt_t;
typedef struct { typedef struct {
UINT16 num_frames_to_be_processed; UINT16 num_frames_to_be_processed;
UINT16 len; UINT16 len;
@ -115,18 +123,15 @@ static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg);
static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg); static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg);
static void btc_a2dp_sink_handle_clear_track(void); static void btc_a2dp_sink_handle_clear_track(void);
static BOOLEAN btc_a2dp_sink_clear_track(void); static BOOLEAN btc_a2dp_sink_clear_track(void);
static void btc_a2dp_sink_task_handler(void *arg);
static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context); static void btc_a2dp_sink_ctrl_handler(void *arg);
static void btc_a2dp_sink_data_ready(void *context);
static tBTC_A2DP_SINK_CB btc_aa_snk_cb; static tBTC_A2DP_SINK_CB btc_aa_snk_cb;
static int btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF; static int btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF;
static future_t *btc_a2dp_sink_future = NULL; static future_t *btc_a2dp_sink_future = NULL;
static xTaskHandle btc_aa_snk_task_hdl = NULL; static osi_thread_t *btc_aa_snk_task_hdl = NULL;
static QueueHandle_t btc_aa_snk_data_queue = NULL;
static QueueHandle_t btc_aa_snk_ctrl_queue = NULL;
static QueueSetHandle_t btc_aa_snk_queue_set;
static esp_a2d_sink_data_cb_t bt_aa_snk_data_cb = NULL; static esp_a2d_sink_data_cb_t bt_aa_snk_data_cb = NULL;
void btc_a2dp_sink_reg_data_cb(esp_a2d_sink_data_cb_t callback) void btc_a2dp_sink_reg_data_cb(esp_a2d_sink_data_cb_t callback)
@ -174,26 +179,28 @@ static inline void btc_a2d_cb_to_app(esp_a2d_cb_event_t event, esp_a2d_cb_param_
** BTC ADAPTATION ** BTC ADAPTATION
*****************************************************************************/ *****************************************************************************/
static void btc_a2dp_sink_ctrl_post(uint32_t sig, void *par) static bool btc_a2dp_sink_ctrl_post(uint32_t sig, void *param)
{ {
BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t)); a2dp_sink_task_evt_t *evt = (a2dp_sink_task_evt_t *)osi_malloc(sizeof(a2dp_sink_task_evt_t));
if (evt == NULL) { if (evt == NULL) {
return; return false;
} }
evt->sig = sig; evt->sig = sig;
evt->par = par; evt->param = param;
if (xQueueSend(btc_aa_snk_ctrl_queue, &evt, portMAX_DELAY) != pdTRUE) { return osi_thread_post(btc_aa_snk_task_hdl, btc_a2dp_sink_ctrl_handler, evt, 0, OSI_THREAD_BLOCKING);
APPL_TRACE_WARNING("btc_aa_snk_ctrl_queue failed, sig 0x%x\n", sig);
}
} }
static void btc_a2dp_sink_ctrl_handler(BtTaskEvt_t *e) static void btc_a2dp_sink_ctrl_handler(void *arg)
{ {
a2dp_sink_task_evt_t *e = (a2dp_sink_task_evt_t *)arg;
if (e == NULL) { if (e == NULL) {
return; return;
} }
switch (e->sig) { switch (e->sig) {
case BTC_MEDIA_TASK_SINK_INIT: case BTC_MEDIA_TASK_SINK_INIT:
btc_a2dp_sink_thread_init(NULL); btc_a2dp_sink_thread_init(NULL);
@ -202,7 +209,7 @@ static void btc_a2dp_sink_ctrl_handler(BtTaskEvt_t *e)
btc_a2dp_sink_thread_cleanup(NULL); btc_a2dp_sink_thread_cleanup(NULL);
break; break;
case BTC_MEDIA_AUDIO_SINK_CFG_UPDATE: case BTC_MEDIA_AUDIO_SINK_CFG_UPDATE:
btc_a2dp_sink_handle_decoder_reset(e->par); btc_a2dp_sink_handle_decoder_reset(e->param);
break; break;
case BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK: case BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK:
btc_a2dp_sink_handle_clear_track(); btc_a2dp_sink_handle_clear_track();
@ -213,29 +220,12 @@ static void btc_a2dp_sink_ctrl_handler(BtTaskEvt_t *e)
default: default:
APPL_TRACE_WARNING("media task unhandled evt: 0x%x\n", e->sig); APPL_TRACE_WARNING("media task unhandled evt: 0x%x\n", e->sig);
} }
if (e->par != NULL) {
osi_free(e->par);
}
}
static void btc_a2dp_sink_task_handler(void *arg) if (e->param != NULL) {
{ osi_free(e->param);
QueueSetMemberHandle_t xActivatedMember;
BtTaskEvt_t *e = NULL;
for (;;) {
xActivatedMember = xQueueSelectFromSet(btc_aa_snk_queue_set, portMAX_DELAY);
if (xActivatedMember == btc_aa_snk_data_queue) {
int32_t data_evt;
xQueueReceive(xActivatedMember, &data_evt, 0);
if (data_evt == BTC_A2DP_SINK_DATA_EVT) {
btc_a2dp_sink_data_ready(NULL);
} }
} else if (xActivatedMember == btc_aa_snk_ctrl_queue) {
xQueueReceive(xActivatedMember, &e, 0);
btc_a2dp_sink_ctrl_handler(e);
osi_free(e); osi_free(e);
}
}
} }
bool btc_a2dp_sink_startup(void) bool btc_a2dp_sink_startup(void)
@ -257,26 +247,14 @@ bool btc_a2dp_sink_startup(void)
} }
#endif /* BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE */ #endif /* BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE */
btc_aa_snk_queue_set = xQueueCreateSet(BTC_A2DP_SINK_TASK_QUEUE_SET_LEN); btc_aa_snk_task_hdl = osi_thread_create(BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, BTC_A2DP_SINK_TASK_PRIO, BTC_A2DP_SINK_TASK_PINNED_TO_CORE, 2);
configASSERT(btc_aa_snk_queue_set);
btc_aa_snk_data_queue = xQueueCreate(BTC_A2DP_SINK_DATA_QUEUE_LEN, sizeof(int32_t));
configASSERT(btc_aa_snk_data_queue);
xQueueAddToSet(btc_aa_snk_data_queue, btc_aa_snk_queue_set);
btc_aa_snk_ctrl_queue = xQueueCreate(BTC_A2DP_SINK_CTRL_QUEUE_LEN, sizeof(void *));
configASSERT(btc_aa_snk_ctrl_queue);
xQueueAddToSet(btc_aa_snk_ctrl_queue, btc_aa_snk_queue_set);
if (!btc_aa_snk_data_queue || !btc_aa_snk_ctrl_queue || !btc_aa_snk_queue_set ) {
goto error_exit;
}
xTaskCreatePinnedToCore(btc_a2dp_sink_task_handler, BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, NULL, BTC_A2DP_SINK_TASK_PRIO, &btc_aa_snk_task_hdl, BTC_A2DP_SINK_TASK_PINNED_TO_CORE);
if (btc_aa_snk_task_hdl == NULL) { if (btc_aa_snk_task_hdl == NULL) {
goto error_exit; goto error_exit;
} }
btc_a2dp_sink_ctrl_post(BTC_MEDIA_TASK_SINK_INIT, NULL); if (btc_a2dp_sink_ctrl_post(BTC_MEDIA_TASK_SINK_INIT, NULL) == false) {
goto error_exit;
}
APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##\n"); APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##\n");
@ -284,24 +262,11 @@ bool btc_a2dp_sink_startup(void)
error_exit:; error_exit:;
APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__); APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
if (btc_aa_snk_task_hdl != NULL) { if (btc_aa_snk_task_hdl != NULL) {
vTaskDelete(btc_aa_snk_task_hdl); osi_thread_free(btc_aa_snk_task_hdl);
btc_aa_snk_task_hdl = NULL; btc_aa_snk_task_hdl = NULL;
} }
if (btc_aa_snk_data_queue) {
vQueueDelete(btc_aa_snk_data_queue);
btc_aa_snk_data_queue = NULL;
}
if (btc_aa_snk_ctrl_queue) {
vQueueDelete(btc_aa_snk_ctrl_queue);
btc_aa_snk_ctrl_queue = NULL;
}
if (btc_aa_snk_queue_set) {
vQueueDelete(btc_aa_snk_queue_set);
btc_aa_snk_queue_set = NULL;
}
#if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE) #if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE)
if (btc_sbc_decoder_context_ptr) { if (btc_sbc_decoder_context_ptr) {
osi_free(btc_sbc_decoder_context_ptr); osi_free(btc_sbc_decoder_context_ptr);
@ -332,18 +297,9 @@ void btc_a2dp_sink_shutdown(void)
future_await(btc_a2dp_sink_future); future_await(btc_a2dp_sink_future);
btc_a2dp_sink_future = NULL; btc_a2dp_sink_future = NULL;
vTaskDelete(btc_aa_snk_task_hdl); osi_thread_free(btc_aa_snk_task_hdl);
btc_aa_snk_task_hdl = NULL; btc_aa_snk_task_hdl = NULL;
vQueueDelete(btc_aa_snk_data_queue);
btc_aa_snk_data_queue = NULL;
vQueueDelete(btc_aa_snk_ctrl_queue);
btc_aa_snk_ctrl_queue = NULL;
vQueueDelete(btc_aa_snk_queue_set);
btc_aa_snk_queue_set = NULL;
#if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE) #if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE)
osi_free(btc_sbc_decoder_context_ptr); osi_free(btc_sbc_decoder_context_ptr);
btc_sbc_decoder_context_ptr = NULL; btc_sbc_decoder_context_ptr = NULL;
@ -397,11 +353,9 @@ void btc_a2dp_sink_on_suspended(tBTA_AV_SUSPEND *p_av)
return; return;
} }
static void btc_a2dp_sink_data_post(int32_t data_type) static void btc_a2dp_sink_data_post(void)
{ {
if (xQueueSend(btc_aa_snk_data_queue, &data_type, 0) != pdTRUE) { osi_thread_post(btc_aa_snk_task_hdl, btc_a2dp_sink_data_ready, NULL, 1, OSI_THREAD_BLOCKING);
APPL_TRACE_DEBUG("Media data Q filled\n");
}
} }
/******************************************************************************* /*******************************************************************************
@ -415,8 +369,7 @@ static void btc_a2dp_sink_data_post(int32_t data_type)
*******************************************************************************/ *******************************************************************************/
static BOOLEAN btc_a2dp_sink_clear_track(void) static BOOLEAN btc_a2dp_sink_clear_track(void)
{ {
btc_a2dp_sink_ctrl_post(BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK, NULL); return btc_a2dp_sink_ctrl_post(BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK, NULL);
return TRUE;
} }
/* when true media task discards any rx frames */ /* when true media task discards any rx frames */
@ -685,8 +638,7 @@ BOOLEAN btc_a2dp_sink_rx_flush_req(void)
return TRUE; return TRUE;
} }
btc_a2dp_sink_ctrl_post(BTC_MEDIA_FLUSH_AA_RX, NULL); return btc_a2dp_sink_ctrl_post(BTC_MEDIA_FLUSH_AA_RX, NULL);
return TRUE;
} }
/******************************************************************************* /*******************************************************************************
@ -777,7 +729,7 @@ UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_pkt)
p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f; p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed); APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
fixed_queue_enqueue(btc_aa_snk_cb.RxSbcQ, p_msg); fixed_queue_enqueue(btc_aa_snk_cb.RxSbcQ, p_msg);
btc_a2dp_sink_data_post(BTC_A2DP_SINK_DATA_EVT); btc_a2dp_sink_data_post();
} else { } else {
/* let caller deal with a failed allocation */ /* let caller deal with a failed allocation */
APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - "); APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - ");

View File

@ -50,6 +50,13 @@
#if BTC_AV_SRC_INCLUDED #if BTC_AV_SRC_INCLUDED
/* Macro */
#define BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTC_A2DP_SOURCE_TASK_STACK_SIZE (CONFIG_A2DP_SOURCE_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
#define BTC_A2DP_SOURCE_TASK_NAME "BtA2dSourceT"
#define BTC_A2DP_SOURCE_TASK_PRIO (configMAX_PRIORITIES - 3)
/***************************************************************************** /*****************************************************************************
** Constants ** Constants
*****************************************************************************/ *****************************************************************************/
@ -72,9 +79,6 @@ enum {
BTC_A2DP_SOURCE_STATE_SHUTTING_DOWN = 2 BTC_A2DP_SOURCE_STATE_SHUTTING_DOWN = 2
}; };
enum {
BTC_A2DP_SOURCE_DATA_EVT = 1,
};
/* Media task tick in milliseconds, must be set to multiple of /* Media task tick in milliseconds, must be set to multiple of
(1000/TICKS_PER_SEC) */ (1000/TICKS_PER_SEC) */
@ -127,6 +131,11 @@ enum {
#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ (5) #define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ (5)
#define MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ (27) // 18 for 20ms tick #define MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ (27) // 18 for 20ms tick
typedef struct {
uint32_t sig;
void *param;
} a2dp_src_task_evt_t;
typedef struct { typedef struct {
UINT16 num_frames_to_be_processed; UINT16 num_frames_to_be_processed;
UINT16 len; UINT16 len;
@ -174,15 +183,12 @@ static void btc_a2dp_source_aa_tx_flush(void);
static void btc_a2dp_source_prep_2_send(UINT8 nb_frame); static void btc_a2dp_source_prep_2_send(UINT8 nb_frame);
static void btc_a2dp_source_handle_timer(UNUSED_ATTR void *context); static void btc_a2dp_source_handle_timer(UNUSED_ATTR void *context);
static void btc_a2dp_source_encoder_init(void); static void btc_a2dp_source_encoder_init(void);
static void btc_a2dp_source_ctrl_handler(void *arg);
static tBTC_A2DP_SOURCE_CB btc_aa_src_cb; static tBTC_A2DP_SOURCE_CB btc_aa_src_cb;
static int btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_OFF; static int btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_OFF;
static future_t *btc_a2dp_source_future = NULL; static future_t *btc_a2dp_source_future = NULL;
static xTaskHandle btc_aa_src_task_hdl = NULL; static osi_thread_t *btc_aa_src_task_hdl = NULL;
static QueueHandle_t btc_aa_src_data_queue = NULL;
static QueueHandle_t btc_aa_src_ctrl_queue = NULL;
static QueueSetHandle_t btc_aa_src_queue_set;
static esp_a2d_source_data_cb_t btc_aa_src_data_cb = NULL; static esp_a2d_source_data_cb_t btc_aa_src_data_cb = NULL;
static UINT64 last_frame_us = 0; static UINT64 last_frame_us = 0;
@ -234,26 +240,28 @@ bool btc_a2dp_source_is_task_shutting_down(void)
return btc_a2dp_source_state == BTC_A2DP_SOURCE_STATE_SHUTTING_DOWN; return btc_a2dp_source_state == BTC_A2DP_SOURCE_STATE_SHUTTING_DOWN;
} }
static void btc_a2dp_source_ctrl_post(uint32_t sig, void *par) static void btc_a2dp_source_ctrl_post(uint32_t sig, void *param)
{ {
BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t)); a2dp_src_task_evt_t *evt = (a2dp_src_task_evt_t *)osi_malloc(sizeof(a2dp_src_task_evt_t));
if (evt == NULL) { if (evt == NULL) {
return; return;
} }
evt->sig = sig; evt->sig = sig;
evt->par = par; evt->param = param;
if (xQueueSend(btc_aa_src_ctrl_queue, &evt, portMAX_DELAY) != pdTRUE) { osi_thread_post(btc_aa_src_task_hdl, btc_a2dp_source_ctrl_handler, evt, 0, OSI_THREAD_BLOCKING);
APPL_TRACE_WARNING("btc_aa_src_ctrl_queue failed, sig 0x%x\n", sig);
}
} }
static void btc_a2dp_source_ctrl_handler(BtTaskEvt_t *e) static void btc_a2dp_source_ctrl_handler(void *arg)
{ {
a2dp_src_task_evt_t *e = (a2dp_src_task_evt_t *)arg;
if (e == NULL) { if (e == NULL) {
return; return;
} }
switch (e->sig) { switch (e->sig) {
case BTC_MEDIA_TASK_INIT: case BTC_MEDIA_TASK_INIT:
btc_a2dp_source_thread_init(NULL); btc_a2dp_source_thread_init(NULL);
@ -268,13 +276,13 @@ static void btc_a2dp_source_ctrl_handler(BtTaskEvt_t *e)
btc_a2dp_source_aa_stop_tx(); btc_a2dp_source_aa_stop_tx();
break; break;
case BTC_MEDIA_SBC_ENC_INIT: case BTC_MEDIA_SBC_ENC_INIT:
btc_a2dp_source_enc_init(e->par); btc_a2dp_source_enc_init(e->param);
break; break;
case BTC_MEDIA_SBC_ENC_UPDATE: case BTC_MEDIA_SBC_ENC_UPDATE:
btc_a2dp_source_enc_update(e->par); btc_a2dp_source_enc_update(e->param);
break; break;
case BTC_MEDIA_AUDIO_FEEDING_INIT: case BTC_MEDIA_AUDIO_FEEDING_INIT:
btc_a2dp_source_audio_feeding_init(e->par); btc_a2dp_source_audio_feeding_init(e->param);
break; break;
case BTC_MEDIA_FLUSH_AA_TX: case BTC_MEDIA_FLUSH_AA_TX:
btc_a2dp_source_aa_tx_flush(); btc_a2dp_source_aa_tx_flush();
@ -282,29 +290,12 @@ static void btc_a2dp_source_ctrl_handler(BtTaskEvt_t *e)
default: default:
APPL_TRACE_WARNING("media task unhandled evt: 0x%x\n", e->sig); APPL_TRACE_WARNING("media task unhandled evt: 0x%x\n", e->sig);
} }
if (e->par != NULL) {
osi_free(e->par);
}
}
static void btc_a2dp_source_task_handler(void *arg) if (e->param != NULL) {
{ osi_free(e->param);
QueueSetMemberHandle_t xActivatedMember;
BtTaskEvt_t *e = NULL;
for (;;) {
xActivatedMember = xQueueSelectFromSet(btc_aa_src_queue_set, portMAX_DELAY);
if (xActivatedMember == btc_aa_src_data_queue) {
int32_t data_evt;
xQueueReceive(xActivatedMember, &data_evt, 0);
if (data_evt == BTC_A2DP_SOURCE_DATA_EVT) {
btc_a2dp_source_handle_timer(NULL);
} }
} else if (xActivatedMember == btc_aa_src_ctrl_queue) {
xQueueReceive(xActivatedMember, &e, 0);
btc_a2dp_source_ctrl_handler(e);
osi_free(e); osi_free(e);
}
}
} }
bool btc_a2dp_source_startup(void) bool btc_a2dp_source_startup(void)
@ -324,57 +315,28 @@ bool btc_a2dp_source_startup(void)
} }
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */ #endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
btc_aa_src_queue_set = xQueueCreateSet(BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN); btc_aa_src_task_hdl = osi_thread_create(BTC_A2DP_SOURCE_TASK_NAME, BTC_A2DP_SOURCE_TASK_STACK_SIZE, BTC_A2DP_SOURCE_TASK_PRIO, BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE, 2);
configASSERT(btc_aa_src_queue_set);
btc_aa_src_data_queue = xQueueCreate(BTC_A2DP_SOURCE_DATA_QUEUE_LEN, sizeof(void *));
configASSERT(btc_aa_src_data_queue);
xQueueAddToSet(btc_aa_src_data_queue, btc_aa_src_queue_set);
btc_aa_src_ctrl_queue = xQueueCreate(BTC_A2DP_SOURCE_CTRL_QUEUE_LEN, sizeof(void *));
configASSERT(btc_aa_src_ctrl_queue);
xQueueAddToSet(btc_aa_src_ctrl_queue, btc_aa_src_queue_set);
if (!btc_aa_src_data_queue || !btc_aa_src_ctrl_queue || !btc_aa_src_queue_set ) {
goto error_exit;
}
xTaskCreatePinnedToCore(btc_a2dp_source_task_handler, BTC_A2DP_SOURCE_TASK_NAME, BTC_A2DP_SOURCE_TASK_STACK_SIZE, NULL, BTC_A2DP_SOURCE_TASK_PRIO, &btc_aa_src_task_hdl, BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE);
if (btc_aa_src_task_hdl == NULL) { if (btc_aa_src_task_hdl == NULL) {
goto error_exit; goto error_exit;
} }
btc_a2dp_source_ctrl_post(BTC_MEDIA_TASK_INIT, NULL); btc_a2dp_source_ctrl_post(BTC_MEDIA_TASK_INIT, NULL);
APPL_TRACE_EVENT("## A2DP SOURCE MEDIA THREAD STARTED ##\n"); APPL_TRACE_EVENT("## A2DP SOURCE MEDIA THREAD STARTED ##\n");
return true; return true;
error_exit:; error_exit:;
APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__); APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
osi_thread_free(btc_aa_src_task_hdl);
if (btc_aa_src_task_hdl != NULL) {
vTaskDelete(btc_aa_src_task_hdl);
btc_aa_src_task_hdl = NULL; btc_aa_src_task_hdl = NULL;
}
if (btc_aa_src_data_queue) {
vQueueDelete(btc_aa_src_data_queue);
btc_aa_src_data_queue = NULL;
}
if (btc_aa_src_ctrl_queue) {
vQueueDelete(btc_aa_src_ctrl_queue);
btc_aa_src_ctrl_queue = NULL;
}
if (btc_aa_src_queue_set) {
vQueueDelete(btc_aa_src_queue_set);
btc_aa_src_queue_set = NULL;
}
#if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE) #if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE)
if (btc_sbc_encoder_ptr) { if (btc_sbc_encoder_ptr) {
osi_free(btc_sbc_encoder_ptr); osi_free(btc_sbc_encoder_ptr);
btc_sbc_encoder_ptr = NULL; btc_sbc_encoder_ptr = NULL;
} }
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */ #endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
return false; return false;
} }
@ -390,18 +352,9 @@ void btc_a2dp_source_shutdown(void)
future_await(btc_a2dp_source_future); future_await(btc_a2dp_source_future);
btc_a2dp_source_future = NULL; btc_a2dp_source_future = NULL;
vTaskDelete(btc_aa_src_task_hdl); osi_thread_free(btc_aa_src_task_hdl);
btc_aa_src_task_hdl = NULL; btc_aa_src_task_hdl = NULL;
vQueueDelete(btc_aa_src_data_queue);
btc_aa_src_data_queue = NULL;
vQueueDelete(btc_aa_src_ctrl_queue);
btc_aa_src_ctrl_queue = NULL;
vQueueDelete(btc_aa_src_queue_set);
btc_aa_src_queue_set = NULL;
#if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE) #if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE)
osi_free(btc_sbc_encoder_ptr); osi_free(btc_sbc_encoder_ptr);
btc_sbc_encoder_ptr = NULL; btc_sbc_encoder_ptr = NULL;
@ -472,11 +425,9 @@ void btc_a2dp_source_on_suspended(tBTA_AV_SUSPEND *p_av)
btc_a2dp_source_stop_audio_req(); btc_a2dp_source_stop_audio_req();
} }
static void btc_a2dp_source_data_post(int32_t data_type) static void btc_a2dp_source_data_post(void)
{ {
if (xQueueSend(btc_aa_src_data_queue, &data_type, 0) != pdTRUE) { osi_thread_post(btc_aa_src_task_hdl, btc_a2dp_source_handle_timer, NULL, 1, OSI_THREAD_BLOCKING);
APPL_TRACE_DEBUG("Media data Q filled\n");
}
} }
static UINT64 time_now_us() static UINT64 time_now_us()
@ -604,9 +555,13 @@ BOOLEAN btc_a2dp_source_stop_audio_req(void)
* the "cleanup() -> btc_a2dp_stop_media_task()" processing during * the "cleanup() -> btc_a2dp_stop_media_task()" processing during
* the shutdown of the Bluetooth stack. * the shutdown of the Bluetooth stack.
*/ */
#if 0
if (btc_aa_src_ctrl_queue != NULL) { if (btc_aa_src_ctrl_queue != NULL) {
#endif
btc_a2dp_source_ctrl_post(BTC_MEDIA_STOP_AA_TX, NULL); btc_a2dp_source_ctrl_post(BTC_MEDIA_STOP_AA_TX, NULL);
#if 0
} }
#endif
return TRUE; return TRUE;
} }
@ -696,9 +651,13 @@ BOOLEAN btc_a2dp_source_tx_flush_req(void)
* the "cleanup() -> btc_a2dp_stop_media_task()" processing during * the "cleanup() -> btc_a2dp_stop_media_task()" processing during
* the shutdown of the Bluetooth stack. * the shutdown of the Bluetooth stack.
*/ */
#if 0
if (btc_aa_src_ctrl_queue != NULL) { if (btc_aa_src_ctrl_queue != NULL) {
#endif
btc_a2dp_source_ctrl_post(BTC_MEDIA_FLUSH_AA_TX, NULL); btc_a2dp_source_ctrl_post(BTC_MEDIA_FLUSH_AA_TX, NULL);
#if 0
} }
#endif
return TRUE; return TRUE;
} }
@ -1515,7 +1474,7 @@ static void btc_a2dp_source_handle_timer(UNUSED_ATTR void *context)
static void btc_a2dp_source_alarm_cb(UNUSED_ATTR void *context) static void btc_a2dp_source_alarm_cb(UNUSED_ATTR void *context)
{ {
btc_a2dp_source_data_post(BTC_A2DP_SOURCE_DATA_EVT); btc_a2dp_source_data_post();
} }
/******************************************************************************* /*******************************************************************************

View File

@ -39,6 +39,14 @@
#include "stack/dyn_mem.h" /* defines static and/or dynamic memory for components */ #include "stack/dyn_mem.h" /* defines static and/or dynamic memory for components */
/* OS Configuration from User config (eg: sdkconfig) */
#if CONFIG_BLUEDROID_PINNED_TO_CORE
#define TASK_PINNED_TO_CORE (CONFIG_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY)
#else
#define TASK_PINNED_TO_CORE (0)
#endif
/****************************************************************************** /******************************************************************************
** **
** Classic BT features ** Classic BT features

View File

@ -27,9 +27,17 @@
#include "esp_bt.h" #include "esp_bt.h"
#include "stack/hcimsgs.h" #include "stack/hcimsgs.h"
#define HCI_H4_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4)
#define HCI_H4_TASK_NAME "hciH4T"
#define HCI_H4_QUEUE_LEN 1
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE) #if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
#include "l2c_int.h" #include "l2c_int.h"
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
#include "stack/hcimsgs.h"
#define HCI_HAL_SERIAL_BUFFER_SIZE 1026 #define HCI_HAL_SERIAL_BUFFER_SIZE 1026
#define HCI_BLE_EVENT 0x3e #define HCI_BLE_EVENT 0x3e
@ -63,9 +71,7 @@ static hci_hal_env_t hci_hal_env;
static const hci_hal_t interface; static const hci_hal_t interface;
static const hci_hal_callbacks_t *callbacks; static const hci_hal_callbacks_t *callbacks;
static const esp_vhci_host_callback_t vhci_host_cb; static const esp_vhci_host_callback_t vhci_host_cb;
static osi_thread_t *hci_h4_thread;
static xTaskHandle xHciH4TaskHandle;
static xQueueHandle xHciH4Queue;
static void host_send_pkt_available_cb(void); static void host_send_pkt_available_cb(void);
static int host_recv_pkt_cb(uint8_t *data, uint16_t len); static int host_recv_pkt_cb(uint8_t *data, uint16_t len);
@ -110,8 +116,10 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks)
hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX); hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX);
#endif #endif
xHciH4Queue = xQueueCreate(HCI_H4_QUEUE_LEN, sizeof(BtTaskEvt_t)); hci_h4_thread = osi_thread_create(HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, HCI_H4_TASK_PRIO, HCI_H4_TASK_PINNED_TO_CORE, 1);
xTaskCreatePinnedToCore(hci_hal_h4_rx_handler, HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, NULL, HCI_H4_TASK_PRIO, &xHciH4TaskHandle, HCI_H4_TASK_PINNED_TO_CORE); if (hci_h4_thread == NULL) {
return false;
}
//register vhci host cb //register vhci host cb
if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) { if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) {
@ -125,9 +133,8 @@ static void hal_close()
{ {
hci_hal_env_deinit(); hci_hal_env_deinit();
/* delete task and queue */ osi_thread_free(hci_h4_thread);
vTaskDelete(xHciH4TaskHandle); hci_h4_thread = NULL;
vQueueDelete(xHciH4Queue);
} }
/** /**
@ -169,30 +176,12 @@ static uint16_t transmit_data(serial_data_type_t type,
// Internal functions // Internal functions
static void hci_hal_h4_rx_handler(void *arg) static void hci_hal_h4_rx_handler(void *arg)
{ {
BtTaskEvt_t e;
for (;;) {
if (pdTRUE == xQueueReceive(xHciH4Queue, &e, (portTickType)portMAX_DELAY)) {
if (e.sig == SIG_HCI_HAL_RECV_PACKET) {
fixed_queue_process(hci_hal_env.rx_q); fixed_queue_process(hci_hal_env.rx_q);
}
}
}
} }
task_post_status_t hci_hal_h4_task_post(task_post_t timeout) bool hci_hal_h4_task_post(osi_thread_blocking_t blocking)
{ {
BtTaskEvt_t evt; return osi_thread_post(hci_h4_thread, hci_hal_h4_rx_handler, NULL, 0, blocking);
evt.sig = SIG_HCI_HAL_RECV_PACKET;
evt.par = 0;
if (xQueueSend(xHciH4Queue, &evt, timeout) != pdTRUE) {
return TASK_POST_SUCCESS;
}
return TASK_POST_FAIL;
} }
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE) #if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
@ -343,7 +332,7 @@ static void host_send_pkt_available_cb(void)
{ {
//Controller rx cache buffer is ready for receiving new host packet //Controller rx cache buffer is ready for receiving new host packet
//Just Call Host main thread task to process pending packets. //Just Call Host main thread task to process pending packets.
hci_host_task_post(TASK_POST_BLOCKING); hci_host_task_post(OSI_THREAD_BLOCKING);
} }
static int host_recv_pkt_cb(uint8_t *data, uint16_t len) static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
@ -368,7 +357,8 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
pkt->layer_specific = 0; pkt->layer_specific = 0;
memcpy(pkt->data, data, len); memcpy(pkt->data, data, len);
fixed_queue_enqueue(hci_hal_env.rx_q, pkt); fixed_queue_enqueue(hci_hal_env.rx_q, pkt);
hci_hal_h4_task_post(0); hci_hal_h4_task_post(OSI_THREAD_NON_BLOCKING);
BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len); BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len);

View File

@ -21,6 +21,7 @@
#include "common/bt_trace.h" #include "common/bt_trace.h"
#include "stack/hcidefs.h" #include "stack/hcidefs.h"
#include "stack/hcimsgs.h" #include "stack/hcimsgs.h"
#include "stack/btu.h"
#include "common/bt_vendor_lib.h" #include "common/bt_vendor_lib.h"
#include "hci/hci_internals.h" #include "hci/hci_internals.h"
#include "hci/hci_hal.h" #include "hci/hci_hal.h"
@ -33,6 +34,12 @@
#include "osi/mutex.h" #include "osi/mutex.h"
#include "osi/fixed_queue.h" #include "osi/fixed_queue.h"
#define HCI_HOST_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 3)
#define HCI_HOST_TASK_NAME "hciHostT"
#define HCI_HOST_QUEUE_LEN 40
typedef struct { typedef struct {
uint16_t opcode; uint16_t opcode;
future_t *complete_future; future_t *complete_future;
@ -70,10 +77,7 @@ static const uint32_t COMMAND_PENDING_TIMEOUT = 8000;
static bool interface_created; static bool interface_created;
static hci_t interface; static hci_t interface;
static hci_host_env_t hci_host_env; static hci_host_env_t hci_host_env;
static osi_thread_t *hci_host_thread;
static xTaskHandle xHciHostTaskHandle;
static xQueueHandle xHciHostQueue;
static bool hci_host_startup_flag; static bool hci_host_startup_flag;
// Modules we import and callbacks we export // Modules we import and callbacks we export
@ -102,8 +106,10 @@ int hci_start_up(void)
goto error; goto error;
} }
xHciHostQueue = xQueueCreate(HCI_HOST_QUEUE_LEN, sizeof(BtTaskEvt_t)); hci_host_thread = osi_thread_create(HCI_HOST_TASK_NAME, HCI_HOST_TASK_STACK_SIZE, HCI_HOST_TASK_PRIO, HCI_HOST_TASK_PINNED_TO_CORE, 1);
xTaskCreatePinnedToCore(hci_host_thread_handler, HCI_HOST_TASK_NAME, HCI_HOST_TASK_STACK_SIZE, NULL, HCI_HOST_TASK_PRIO, &xHciHostTaskHandle, HCI_HOST_TASK_PINNED_TO_CORE); if (hci_host_thread == NULL) {
return -2;
}
packet_fragmenter->init(&packet_fragmenter_callbacks); packet_fragmenter->init(&packet_fragmenter_callbacks);
hal->open(&hal_callbacks); hal->open(&hal_callbacks);
@ -124,28 +130,15 @@ void hci_shut_down(void)
//low_power_manager->cleanup(); //low_power_manager->cleanup();
hal->close(); hal->close();
vTaskDelete(xHciHostTaskHandle);
vQueueDelete(xHciHostQueue); osi_thread_free(hci_host_thread);
hci_host_thread = NULL;
} }
task_post_status_t hci_host_task_post(task_post_t timeout) bool hci_host_task_post(osi_thread_blocking_t blocking)
{ {
BtTaskEvt_t evt; return osi_thread_post(hci_host_thread, hci_host_thread_handler, NULL, 0, blocking);
if (hci_host_startup_flag == false) {
return TASK_POST_FAIL;
}
evt.sig = SIG_HCI_HOST_SEND_AVAILABLE;
evt.par = 0;
if (xQueueSend(xHciHostQueue, &evt, timeout) != pdTRUE) {
HCI_TRACE_ERROR("xHciHostQueue failed\n");
return TASK_POST_FAIL;
}
return TASK_POST_SUCCESS;
} }
static int hci_layer_init_env(void) static int hci_layer_init_env(void)
@ -218,13 +211,6 @@ static void hci_host_thread_handler(void *arg)
* All packets will be directly copied to single queue in driver layer with * All packets will be directly copied to single queue in driver layer with
* H4 type header added (1 byte). * H4 type header added (1 byte).
*/ */
BtTaskEvt_t e;
for (;;) {
if (pdTRUE == xQueueReceive(xHciHostQueue, &e, (portTickType)portMAX_DELAY)) {
if (e.sig == SIG_HCI_HOST_SEND_AVAILABLE) {
if (esp_vhci_host_check_send_available()) { if (esp_vhci_host_check_send_available()) {
/*Now Target only allowed one packet per TX*/ /*Now Target only allowed one packet per TX*/
BT_HDR *pkt = packet_fragmenter->fragment_current_packet(); BT_HDR *pkt = packet_fragmenter->fragment_current_packet();
@ -239,9 +225,6 @@ static void hci_host_thread_handler(void *arg)
} }
} }
} }
}
}
}
} }
static void transmit_command( static void transmit_command(
@ -271,7 +254,7 @@ static void transmit_command(
BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len); BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len);
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry); fixed_queue_enqueue(hci_host_env.command_queue, wait_entry);
hci_host_task_post(TASK_POST_BLOCKING); hci_host_task_post(OSI_THREAD_BLOCKING);
} }
@ -292,7 +275,7 @@ static future_t *transmit_command_futured(BT_HDR *command)
command->event = MSG_STACK_TO_HC_HCI_CMD; command->event = MSG_STACK_TO_HC_HCI_CMD;
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry); fixed_queue_enqueue(hci_host_env.command_queue, wait_entry);
hci_host_task_post(TASK_POST_BLOCKING); hci_host_task_post(OSI_THREAD_BLOCKING);
return future; return future;
} }
@ -305,7 +288,7 @@ static void transmit_downward(uint16_t type, void *data)
fixed_queue_enqueue(hci_host_env.packet_queue, data); fixed_queue_enqueue(hci_host_env.packet_queue, data);
} }
hci_host_task_post(TASK_POST_BLOCKING); hci_host_task_post(OSI_THREAD_BLOCKING);
} }
@ -479,7 +462,7 @@ intercepted:
/*Tell HCI Host Task to continue TX Pending commands*/ /*Tell HCI Host Task to continue TX Pending commands*/
if (hci_host_env.command_credits && if (hci_host_env.command_credits &&
!fixed_queue_is_empty(hci_host_env.command_queue)) { !fixed_queue_is_empty(hci_host_env.command_queue)) {
hci_host_task_post(TASK_POST_BLOCKING); hci_host_task_post(OSI_THREAD_BLOCKING);
} }
if (wait_entry) { if (wait_entry) {
@ -507,7 +490,7 @@ static void dispatch_reassembled(BT_HDR *packet)
{ {
// Events should already have been dispatched before this point // Events should already have been dispatched before this point
//Tell Up-layer received packet. //Tell Up-layer received packet.
if (btu_task_post(SIG_BTU_HCI_MSG, packet, TASK_POST_BLOCKING) != TASK_POST_SUCCESS) { if (btu_task_post(SIG_BTU_HCI_MSG, packet, OSI_THREAD_BLOCKING) == false) {
osi_free(packet); osi_free(packet);
} }
} }

View File

@ -23,6 +23,8 @@
#include "osi/allocator.h" #include "osi/allocator.h"
#include "osi/osi.h" #include "osi/osi.h"
#include "osi/future.h" #include "osi/future.h"
#include "osi/thread.h"
///// LEGACY DEFINITIONS ///// ///// LEGACY DEFINITIONS /////
/* Message event mask across Host/Controller lib and stack */ /* Message event mask across Host/Controller lib and stack */
@ -95,5 +97,6 @@ const hci_t *hci_layer_get_interface();
int hci_start_up(void); int hci_start_up(void);
void hci_shut_down(void); void hci_shut_down(void);
bool hci_host_task_post(osi_thread_blocking_t blocking);
#endif /* _HCI_LAYER_H_ */ #endif /* _HCI_LAYER_H_ */

View File

@ -25,91 +25,33 @@
#define portBASE_TYPE int #define portBASE_TYPE int
struct bt_task_evt { struct osi_thread;
uint32_t sig; //task sig
void *par; //point to task param
void *cb; //point to function cb
void *arg; //point to function arg
};
typedef struct bt_task_evt BtTaskEvt_t;
typedef bt_status_t (* BtTaskCb_t)(void *arg); typedef struct osi_thread osi_thread_t;
typedef void (*osi_thread_func_t)(void *context);
typedef enum { typedef enum {
SIG_HCI_HAL_RECV_PACKET = 0, OSI_THREAD_CORE_0 = 0,
SIG_HCI_HAL_NUM, OSI_THREAD_CORE_1,
} SIG_HCI_HAL_t; OSI_THREAD_CORE_AFFINITY,
} osi_thread_core_t;
typedef enum { typedef enum {
SIG_HCI_HOST_SEND_AVAILABLE = 0, OSI_THREAD_NON_BLOCKING = 0,
SIG_HCI_HOST_NUM, OSI_THREAD_BLOCKING,
} SIG_HCI_HOST_t; } osi_thread_blocking_t;
typedef enum { osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num);
SIG_BTU_START_UP = 0,
SIG_BTU_HCI_MSG,
SIG_BTU_BTA_MSG,
SIG_BTU_BTA_ALARM,
SIG_BTU_GENERAL_ALARM,
SIG_BTU_ONESHOT_ALARM,
SIG_BTU_L2CAP_ALARM,
SIG_BTU_NUM,
} SIG_BTU_t;
#define TASK_PINNED_TO_CORE (CONFIG_BT_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY) void osi_thread_free(osi_thread_t *thread);
#define HCI_HOST_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, osi_thread_blocking_t blocking);
#define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 3)
#define HCI_HOST_TASK_NAME "hciHostT"
#define HCI_HOST_QUEUE_LEN 40
#define HCI_H4_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) bool osi_thread_set_priority(osi_thread_t *thread, int priority);
#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4)
#define HCI_H4_TASK_NAME "hciH4T"
#define HCI_H4_QUEUE_LEN 1
#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) const char *osi_thread_name(osi_thread_t *thread);
#define BTU_TASK_STACK_SIZE (CONFIG_BT_BTU_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE)
#define BTU_TASK_PRIO (configMAX_PRIORITIES - 5)
#define BTU_TASK_NAME "btuT"
#define BTU_QUEUE_LEN 50
#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx);
#define BTC_TASK_STACK_SIZE (CONFIG_BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
#define BTC_TASK_NAME "btcT"
#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6)
#define BTC_TASK_QUEUE_LEN 60
#define BTC_A2DP_SINK_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTC_A2DP_SINK_TASK_STACK_SIZE (CONFIG_BT_A2DP_SINK_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
#define BTC_A2DP_SINK_TASK_NAME "BtA2dSinkT"
#define BTC_A2DP_SINK_TASK_PRIO (configMAX_PRIORITIES - 3)
#define BTC_A2DP_SINK_DATA_QUEUE_LEN (3)
#define BTC_A2DP_SINK_CTRL_QUEUE_LEN (5)
#define BTC_A2DP_SINK_TASK_QUEUE_SET_LEN (BTC_A2DP_SINK_DATA_QUEUE_LEN + BTC_A2DP_SINK_CTRL_QUEUE_LEN)
#define BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTC_A2DP_SOURCE_TASK_STACK_SIZE (CONFIG_BT_A2DP_SOURCE_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
#define BTC_A2DP_SOURCE_TASK_NAME "BtA2dSourceT"
#define BTC_A2DP_SOURCE_TASK_PRIO (configMAX_PRIORITIES - 3)
#define BTC_A2DP_SOURCE_DATA_QUEUE_LEN (1)
#define BTC_A2DP_SOURCE_CTRL_QUEUE_LEN (5)
#define BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN (BTC_A2DP_SOURCE_DATA_QUEUE_LEN + BTC_A2DP_SOURCE_CTRL_QUEUE_LEN)
#define TASK_POST_NON_BLOCKING (0)
#define TASK_POST_BLOCKING (portMAX_DELAY)
typedef uint32_t task_post_t; /* Timeout of task post return, unit TICK */
typedef enum {
TASK_POST_SUCCESS = 0,
TASK_POST_FAIL,
} task_post_status_t;
task_post_status_t btu_task_post(uint32_t sig, void *param, task_post_t timeout);
task_post_status_t hci_host_task_post(task_post_t timeout);
task_post_status_t hci_hal_h4_task_post(task_post_t timeout);
#endif /* __THREAD_H__ */ #endif /* __THREAD_H__ */

View File

@ -0,0 +1,282 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#include <string.h>
#include "osi/allocator.h"
#include "osi/fixed_queue.h"
#include "osi/semaphore.h"
#include "osi/thread.h"
struct osi_thread {
void *thread_handle; /*!< Store the thread object */
int thread_id; /*!< May for some OS, such as Linux */
bool stop;
uint8_t work_queue_num; /*!< Work queue number */
fixed_queue_t **work_queues; /*!< Point to queue array, and the priority inverse array index */
osi_sem_t work_sem;
osi_sem_t stop_sem;
};
struct osi_thread_start_arg {
osi_thread_t *thread;
osi_sem_t start_sem;
int error;
};
typedef struct {
osi_thread_func_t func;
void *context;
} work_item_t;
static const size_t DEFAULT_WORK_QUEUE_CAPACITY = 100;
static void osi_thread_run(void *arg)
{
struct osi_thread_start_arg *start = (struct osi_thread_start_arg *)arg;
osi_thread_t *thread = start->thread;
osi_sem_give(&start->start_sem);
while (1) {
int idx = 0;
osi_sem_take(&thread->work_sem, OSI_SEM_MAX_TIMEOUT);
if (thread->stop) {
break;
}
while (!thread->stop && idx < thread->work_queue_num) {
work_item_t *item = fixed_queue_try_dequeue(thread->work_queues[idx]);
if (item) {
item->func(item->context);
osi_free(item);
idx = 0;
continue;
} else {
idx++;
}
}
}
thread->thread_handle = NULL;
osi_sem_give(&thread->stop_sem);
vTaskDelete(NULL);
}
static int osi_thread_join(osi_thread_t *thread, uint32_t wait_ms)
{
assert(thread != NULL);
return osi_sem_take(&thread->stop_sem, wait_ms);
}
static void osi_thread_stop(osi_thread_t *thread)
{
int ret;
assert(thread != NULL);
//stop the thread
thread->stop = true;
osi_sem_give(&thread->work_sem);
//join
ret = osi_thread_join(thread, 1000); //wait 1000ms
//if join failed, delete the task here
if (ret != 0 && thread->thread_handle) {
vTaskDelete(thread->thread_handle);
}
}
//in linux, the stack_size, priority and core may not be set here, the code will be ignore the arguments
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num)
{
int ret;
osi_thread_t *thread;
struct osi_thread_start_arg start_arg = {0};
if (stack_size <= 0 ||
core < OSI_THREAD_CORE_0 || core > OSI_THREAD_CORE_AFFINITY ||
work_queue_num <= 0) {
return NULL;
}
thread = (osi_thread_t *)osi_malloc(sizeof(osi_thread_t));
if (thread == NULL) {
goto _err;
}
thread->stop = false;
thread->work_queue_num = work_queue_num;
thread->work_queues = (fixed_queue_t **)osi_malloc(sizeof(fixed_queue_t *) * work_queue_num);
if (thread->work_queues == NULL) {
goto _err;
}
for (int i = 0; i < thread->work_queue_num; i++) {
thread->work_queues[i] = fixed_queue_new(DEFAULT_WORK_QUEUE_CAPACITY);
if (thread->work_queues[i] == NULL) {
goto _err;
}
}
ret = osi_sem_new(&thread->work_sem, 1, 0);
if (ret != 0) {
goto _err;
}
ret = osi_sem_new(&thread->stop_sem, 1, 0);
if (ret != 0) {
goto _err;
}
start_arg.thread = thread;
ret = osi_sem_new(&start_arg.start_sem, 1, 0);
if (ret != 0) {
goto _err;
}
if (xTaskCreatePinnedToCore(osi_thread_run, name, stack_size, &start_arg, priority, &thread->thread_handle, core) != pdPASS) {
goto _err;
}
osi_sem_take(&start_arg.start_sem, OSI_SEM_MAX_TIMEOUT);
osi_sem_free(&start_arg.start_sem);
return thread;
_err:
if (thread) {
if (start_arg.start_sem) {
osi_sem_free(&start_arg.start_sem);
}
if (thread->thread_handle) {
vTaskDelete(thread->thread_handle);
}
for (int i = 0; i < thread->work_queue_num; i++) {
if (thread->work_queues[i]) {
fixed_queue_free(thread->work_queues[i], osi_free_func);
}
}
if (thread->work_queues) {
osi_free(thread->work_queues);
}
if (thread->work_sem) {
osi_sem_free(&thread->work_sem);
}
if (thread->stop_sem) {
osi_sem_free(&thread->stop_sem);
}
osi_free(thread);
}
return NULL;
}
void osi_thread_free(osi_thread_t *thread)
{
if (!thread)
return;
osi_thread_stop(thread);
for (int i = 0; i < thread->work_queue_num; i++) {
if (thread->work_queues[i]) {
fixed_queue_free(thread->work_queues[i], osi_free_func);
}
}
if (thread->work_queues) {
osi_free(thread->work_queues);
}
if (thread->work_sem) {
osi_sem_free(&thread->work_sem);
}
if (thread->stop_sem) {
osi_sem_free(&thread->stop_sem);
}
osi_free(thread);
}
bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, osi_thread_blocking_t blocking)
{
assert(thread != NULL);
assert(func != NULL);
if (queue_idx >= thread->work_queue_num) {
return false;
}
work_item_t *item = (work_item_t *)osi_malloc(sizeof(work_item_t));
if (item == NULL) {
return false;
}
item->func = func;
item->context = context;
if (blocking == OSI_THREAD_BLOCKING) {
fixed_queue_enqueue(thread->work_queues[queue_idx], item);
} else {
if (fixed_queue_try_enqueue(thread->work_queues[queue_idx], item) == false) {
osi_free(item);
return false;
}
}
osi_sem_give(&thread->work_sem);
return true;
}
bool osi_thread_set_priority(osi_thread_t *thread, int priority)
{
assert(thread != NULL);
vTaskPrioritySet(thread->thread_handle, priority);
return true;
}
const char *osi_thread_name(osi_thread_t *thread)
{
assert(thread != NULL);
return pcTaskGetTaskName(thread->thread_handle);
}
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx)
{
if (wq_idx < 0 || wq_idx >= thread->work_queue_num) {
return -1;
}
return fixed_queue_length(thread->work_queues[wq_idx]);
}

View File

@ -1086,7 +1086,7 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context)
event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK; event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;
btu_task_post(SIG_BTU_HCI_MSG, event, TASK_POST_BLOCKING); btu_task_post(SIG_BTU_HCI_MSG, event, OSI_THREAD_BLOCKING);
} }
@ -1291,7 +1291,7 @@ static void btu_hcif_command_status_evt(uint8_t status, BT_HDR *command, void *c
event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK; event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;
btu_task_post(SIG_BTU_HCI_MSG, event, TASK_POST_BLOCKING); btu_task_post(SIG_BTU_HCI_MSG, event, OSI_THREAD_BLOCKING);
} }
/******************************************************************************* /*******************************************************************************

View File

@ -44,6 +44,12 @@
#endif #endif
#endif #endif
#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTU_TASK_STACK_SIZE (4096 + BT_TASK_EXTRA_STACK_SIZE)
#define BTU_TASK_PRIO (configMAX_PRIORITIES - 5)
#define BTU_TASK_NAME "btuT"
#define BTU_QUEUE_LEN 50
hash_map_t *btu_general_alarm_hash_map; hash_map_t *btu_general_alarm_hash_map;
osi_mutex_t btu_general_alarm_lock; osi_mutex_t btu_general_alarm_lock;
static const size_t BTU_GENERAL_ALARM_HASH_MAP_SIZE = 34; static const size_t BTU_GENERAL_ALARM_HASH_MAP_SIZE = 34;
@ -56,16 +62,14 @@ hash_map_t *btu_l2cap_alarm_hash_map;
osi_mutex_t btu_l2cap_alarm_lock; osi_mutex_t btu_l2cap_alarm_lock;
static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 34; static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 34;
//thread_t *bt_workqueue_thread; osi_thread_t *btu_thread = NULL;
//static const char *BT_WORKQUEUE_NAME = "bt_workqueue";
xTaskHandle xBtuTaskHandle = NULL;
xQueueHandle xBtuQueue = 0;
extern void PLATFORM_DisableHciTransport(UINT8 bDisable); extern void PLATFORM_DisableHciTransport(UINT8 bDisable);
extern void btu_task_thread_handler(void *arg); extern void btu_task_thread_handler(void *arg);
void btu_task_start_up(void); void btu_task_start_up(void);
void btu_task_shut_down(void); void btu_task_shut_down(void);
/***************************************************************************** /*****************************************************************************
** V A R I A B L E S * ** V A R I A B L E S *
******************************************************************************/ ******************************************************************************/
@ -178,10 +182,14 @@ void BTU_StartUp(void)
osi_mutex_new(&btu_l2cap_alarm_lock); osi_mutex_new(&btu_l2cap_alarm_lock);
xBtuQueue = xQueueCreate(BTU_QUEUE_LEN, sizeof(BtTaskEvt_t)); btu_thread = osi_thread_create(BTU_TASK_NAME, BTU_TASK_STACK_SIZE, BTU_TASK_PRIO, BTU_TASK_PINNED_TO_CORE, 1);
xTaskCreatePinnedToCore(btu_task_thread_handler, BTU_TASK_NAME, BTU_TASK_STACK_SIZE, NULL, BTU_TASK_PRIO, &xBtuTaskHandle, BTU_TASK_PINNED_TO_CORE); if (btu_thread == NULL) {
goto error_exit;
}
btu_task_post(SIG_BTU_START_UP, NULL, TASK_POST_BLOCKING); if (btu_task_post(SIG_BTU_START_UP, NULL, OSI_THREAD_BLOCKING) == false) {
goto error_exit;
}
return; return;
@ -206,17 +214,14 @@ void BTU_ShutDown(void)
hash_map_free(btu_l2cap_alarm_hash_map); hash_map_free(btu_l2cap_alarm_hash_map);
osi_mutex_free(&btu_l2cap_alarm_lock); osi_mutex_free(&btu_l2cap_alarm_lock);
vTaskDelete(xBtuTaskHandle); if (btu_thread) {
vQueueDelete(xBtuQueue); osi_thread_free(btu_thread);
btu_thread = NULL;
}
btu_general_alarm_hash_map = NULL; btu_general_alarm_hash_map = NULL;
btu_oneshot_alarm_hash_map = NULL; btu_oneshot_alarm_hash_map = NULL;
btu_l2cap_alarm_hash_map = NULL; btu_l2cap_alarm_hash_map = NULL;
xBtuTaskHandle = NULL;
xBtuQueue = 0;
} }
/***************************************************************************** /*****************************************************************************
@ -236,13 +241,14 @@ UINT16 BTU_BleAclPktSize(void)
return 0; return 0;
#endif #endif
} }
#if SCAN_QUEUE_CONGEST_CHECK #if SCAN_QUEUE_CONGEST_CHECK
bool BTU_check_queue_is_congest(void) bool BTU_check_queue_is_congest(void)
{ {
UBaseType_t wait_size = uxQueueMessagesWaiting(xBtuQueue); if (osi_thread_queue_wait_size(btu_thread, 0) >= QUEUE_CONGEST_SIZE) {
if(wait_size >= QUEUE_CONGEST_SIZE ) {
return true; return true;
} }
return false; return false;
} }
#endif #endif

View File

@ -81,6 +81,11 @@ extern void avdt_rcv_sync_info (BT_HDR *p_buf);
#include "btm_ble_int.h" #include "btm_ble_int.h"
#endif #endif
typedef struct {
uint32_t sig;
void *param;
} btu_thread_evt_t;
//#if (defined(BT_APP_DEMO) && BT_APP_DEMO == TRUE) //#if (defined(BT_APP_DEMO) && BT_APP_DEMO == TRUE)
//#include "bt_app_common.h" //#include "bt_app_common.h"
//#endif //#endif
@ -107,8 +112,8 @@ extern osi_mutex_t btu_oneshot_alarm_lock;
extern hash_map_t *btu_l2cap_alarm_hash_map; extern hash_map_t *btu_l2cap_alarm_hash_map;
extern osi_mutex_t btu_l2cap_alarm_lock; extern osi_mutex_t btu_l2cap_alarm_lock;
extern xTaskHandle xBtuTaskHandle; extern void *btu_thread;
extern xQueueHandle xBtuQueue;
extern bluedroid_init_done_cb_t bluedroid_init_done_cb; extern bluedroid_init_done_cb_t bluedroid_init_done_cb;
/* Define a function prototype to allow a generic timeout handler */ /* Define a function prototype to allow a generic timeout handler */
@ -208,66 +213,52 @@ static void btu_bta_alarm_process(TIMER_LIST_ENT *p_tle)
} }
#endif #endif
/***************************************************************************** void btu_thread_handler(void *arg)
**
** Function btu_task_thread_handler
**
** Description Process BTU Task Thread.
******************************************************************************/
void btu_task_thread_handler(void *arg)
{ {
BtTaskEvt_t e; btu_thread_evt_t *evt = (btu_thread_evt_t *)arg;
for (;;) { switch (evt->sig) {
if (pdTRUE == xQueueReceive(xBtuQueue, &e, (portTickType)portMAX_DELAY)) {
switch (e.sig) {
case SIG_BTU_START_UP: case SIG_BTU_START_UP:
btu_task_start_up(); btu_task_start_up();
break; break;
case SIG_BTU_HCI_MSG: case SIG_BTU_HCI_MSG:
btu_hci_msg_process((BT_HDR *)e.par); btu_hci_msg_process((BT_HDR *)evt->param);
break; break;
#if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE) #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
case SIG_BTU_BTA_MSG: case SIG_BTU_BTA_MSG:
bta_sys_event((BT_HDR *)e.par); bta_sys_event((BT_HDR *)evt->param);
break; break;
case SIG_BTU_BTA_ALARM: case SIG_BTU_BTA_ALARM:
btu_bta_alarm_process((TIMER_LIST_ENT *)e.par); btu_bta_alarm_process((TIMER_LIST_ENT *)evt->param);
break; break;
#endif #endif
case SIG_BTU_GENERAL_ALARM: case SIG_BTU_GENERAL_ALARM:
btu_general_alarm_process((TIMER_LIST_ENT *)e.par); case SIG_BTU_ONESHOT_ALARM:
btu_general_alarm_process((TIMER_LIST_ENT *)evt->param);
break; break;
case SIG_BTU_ONESHOT_ALARM: {
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)e.par;
btu_general_alarm_process(p_tle);
break;
}
case SIG_BTU_L2CAP_ALARM: case SIG_BTU_L2CAP_ALARM:
btu_l2cap_alarm_process((TIMER_LIST_ENT *)e.par); btu_l2cap_alarm_process((TIMER_LIST_ENT *)evt->param);
break; break;
default: default:
break; break;
} }
}
} osi_free(evt);
} }
bool btu_task_post(uint32_t sig, void *param, osi_thread_blocking_t blocking)
task_post_status_t btu_task_post(uint32_t sig, void *param, task_post_t timeout)
{ {
BtTaskEvt_t evt; btu_thread_evt_t *evt;
evt.sig = sig; evt = (btu_thread_evt_t *)osi_malloc(sizeof(btu_thread_evt_t));
evt.par = param; if (evt == NULL) {
return false;
if (xQueueSend(xBtuQueue, &evt, timeout) != pdTRUE) {
HCI_TRACE_ERROR("xBtuQueue failed\n");
return TASK_POST_FAIL;
} }
return TASK_POST_SUCCESS; evt->sig = sig;
evt->param = param;
return osi_thread_post(btu_thread, btu_thread_handler, evt, 0, blocking);
} }
void btu_task_start_up(void) void btu_task_start_up(void)
@ -426,7 +417,7 @@ void btu_general_alarm_cb(void *data)
assert(data != NULL); assert(data != NULL);
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data; TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
btu_task_post(SIG_BTU_GENERAL_ALARM, p_tle, TASK_POST_BLOCKING); btu_task_post(SIG_BTU_GENERAL_ALARM, p_tle, OSI_THREAD_BLOCKING);
} }
void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec) void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
@ -540,7 +531,7 @@ static void btu_l2cap_alarm_cb(void *data)
assert(data != NULL); assert(data != NULL);
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data; TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
btu_task_post(SIG_BTU_L2CAP_ALARM, p_tle, TASK_POST_BLOCKING); btu_task_post(SIG_BTU_L2CAP_ALARM, p_tle, OSI_THREAD_BLOCKING);
} }
void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ticks) void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ticks)
@ -623,7 +614,7 @@ void btu_oneshot_alarm_cb(void *data)
btu_stop_timer_oneshot(p_tle); btu_stop_timer_oneshot(p_tle);
btu_task_post(SIG_BTU_ONESHOT_ALARM, p_tle, TASK_POST_BLOCKING); btu_task_post(SIG_BTU_ONESHOT_ALARM, p_tle, OSI_THREAD_BLOCKING);
} }
/* /*

View File

@ -29,6 +29,7 @@
#include "common/bt_target.h" #include "common/bt_target.h"
#include "common/bt_defs.h" #include "common/bt_defs.h"
#include "osi/thread.h"
// HACK(zachoverflow): temporary dark magic // HACK(zachoverflow): temporary dark magic
#define BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK 0x1700 // didn't look used in bt_types...here goes nothing #define BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK 0x1700 // didn't look used in bt_types...here goes nothing
@ -163,6 +164,17 @@ typedef void (*tBTU_EVENT_CALLBACK)(BT_HDR *p_hdr);
#define BTU_TTYPE_UCD_TO 108 #define BTU_TTYPE_UCD_TO 108
#define BTU_TTYPE_BLE_SCAN 109 #define BTU_TTYPE_BLE_SCAN 109
/* BTU Task Signal */
typedef enum {
SIG_BTU_START_UP = 0,
SIG_BTU_HCI_MSG,
SIG_BTU_BTA_MSG,
SIG_BTU_BTA_ALARM,
SIG_BTU_GENERAL_ALARM,
SIG_BTU_ONESHOT_ALARM,
SIG_BTU_L2CAP_ALARM,
SIG_BTU_NUM,
} SIG_BTU_t;
/* This is the inquiry response information held by BTU, and available /* This is the inquiry response information held by BTU, and available
** to applications. ** to applications.
@ -276,6 +288,8 @@ void btu_task_shut_down(void);
UINT16 BTU_BleAclPktSize(void); UINT16 BTU_BleAclPktSize(void);
bool btu_task_post(uint32_t sig, void *param, osi_thread_blocking_t blocking);
/* /*
#ifdef __cplusplus #ifdef __cplusplus
} }