mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
component/bt : modify OSI thread of bluedroid
abstract of OSI thread to make bluedroid more compatible with different OS.
This commit is contained in:
parent
28e0a17e0a
commit
faf23df19a
@ -189,6 +189,7 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/osi/mutex.c"
|
||||
"bluedroid/osi/osi.c"
|
||||
"bluedroid/osi/semaphore.c"
|
||||
"bluedroid/osi/thread.c"
|
||||
"bluedroid/stack/a2dp/a2d_api.c"
|
||||
"bluedroid/stack/a2dp/a2d_sbc.c"
|
||||
"bluedroid/stack/avct/avct_api.c"
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "osi/alarm.h"
|
||||
#include "osi/thread.h"
|
||||
#include "stack/btm_api.h"
|
||||
#include "stack/btu.h"
|
||||
#include "bta/bta_api.h"
|
||||
#include "bta/bta_sys.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
|
||||
// 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.
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -591,7 +592,7 @@ void bta_alarm_cb(void *data)
|
||||
assert(data != NULL);
|
||||
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)
|
||||
|
@ -47,9 +47,13 @@
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#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 xQueueHandle xBtcQueue = 0;
|
||||
static osi_thread_t *btc_thread;
|
||||
|
||||
static btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
[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.
|
||||
******************************************************************************/
|
||||
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 (;;) {
|
||||
if (pdTRUE == xQueueReceive(xBtcQueue, &msg, (portTickType)portMAX_DELAY)) {
|
||||
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
|
||||
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:
|
||||
profile_tab[msg.pid].btc_call(&msg);
|
||||
profile_tab[msg->pid].btc_call(msg);
|
||||
break;
|
||||
case BTC_SIG_API_CB:
|
||||
profile_tab[msg.pid].btc_cb(&msg);
|
||||
profile_tab[msg->pid].btc_cb(msg);
|
||||
break;
|
||||
default:
|
||||
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) {
|
||||
return BT_STATUS_PARM_INVALID;
|
||||
btc_msg_t *lmsg;
|
||||
|
||||
lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t));
|
||||
if (lmsg == NULL) {
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
|
||||
if (xQueueSend(xBtcQueue, msg, timeout) != pdTRUE) {
|
||||
BTC_TRACE_ERROR("Btc Post failed\n");
|
||||
memcpy(lmsg, msg, sizeof(btc_msg_t));
|
||||
|
||||
if (osi_thread_post(btc_thread, btc_thread_handler, lmsg, 0, blocking) == false) {
|
||||
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;
|
||||
}
|
||||
|
||||
return btc_task_post(&lmsg, TASK_POST_BLOCKING);
|
||||
return btc_task_post(&lmsg, OSI_THREAD_BLOCKING);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int btc_init(void)
|
||||
{
|
||||
xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_LEN, sizeof(btc_msg_t));
|
||||
xTaskCreatePinnedToCore(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle, BTC_TASK_PINNED_TO_CORE);
|
||||
if (xBtcTaskHandle == NULL || xBtcQueue == 0){
|
||||
btc_thread = osi_thread_create("BTC_TASK", BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 1);
|
||||
if (btc_thread == NULL) {
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
|
||||
btc_gap_callback_init();
|
||||
#if SCAN_QUEUE_CONGEST_CHECK
|
||||
btc_adv_list_init();
|
||||
@ -180,20 +187,18 @@ int btc_init(void)
|
||||
|
||||
void btc_deinit(void)
|
||||
{
|
||||
vTaskDelete(xBtcTaskHandle);
|
||||
vQueueDelete(xBtcQueue);
|
||||
osi_thread_free(btc_thread);
|
||||
btc_thread = NULL;
|
||||
#if SCAN_QUEUE_CONGEST_CHECK
|
||||
btc_adv_list_deinit();
|
||||
#endif
|
||||
xBtcTaskHandle = NULL;
|
||||
xBtcQueue = 0;
|
||||
}
|
||||
|
||||
bool btc_check_queue_is_congest(void)
|
||||
{
|
||||
UBaseType_t wait_size = uxQueueMessagesWaiting(xBtcQueue);
|
||||
if(wait_size >= QUEUE_CONGEST_SIZE) {
|
||||
if (osi_thread_queue_wait_size(btc_thread, 0) >= QUEUE_CONGEST_SIZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -45,6 +45,13 @@
|
||||
|
||||
#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
|
||||
*****************************************************************************/
|
||||
@ -64,10 +71,6 @@ enum {
|
||||
BTC_A2DP_SINK_STATE_SHUTTING_DOWN = 2
|
||||
};
|
||||
|
||||
enum {
|
||||
BTC_A2DP_SINK_DATA_EVT = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18)
|
||||
|
||||
typedef struct {
|
||||
uint32_t sig;
|
||||
void *param;
|
||||
} a2dp_sink_task_evt_t;
|
||||
|
||||
typedef struct {
|
||||
UINT16 num_frames_to_be_processed;
|
||||
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_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 int btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF;
|
||||
static future_t *btc_a2dp_sink_future = NULL;
|
||||
static xTaskHandle 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 osi_thread_t *btc_aa_snk_task_hdl = 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)
|
||||
@ -174,26 +179,28 @@ static inline void btc_a2d_cb_to_app(esp_a2d_cb_event_t event, esp_a2d_cb_param_
|
||||
** 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) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
evt->sig = sig;
|
||||
evt->par = par;
|
||||
evt->param = param;
|
||||
|
||||
if (xQueueSend(btc_aa_snk_ctrl_queue, &evt, portMAX_DELAY) != pdTRUE) {
|
||||
APPL_TRACE_WARNING("btc_aa_snk_ctrl_queue failed, sig 0x%x\n", sig);
|
||||
}
|
||||
return osi_thread_post(btc_aa_snk_task_hdl, btc_a2dp_sink_ctrl_handler, evt, 0, OSI_THREAD_BLOCKING);
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e->sig) {
|
||||
case BTC_MEDIA_TASK_SINK_INIT:
|
||||
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);
|
||||
break;
|
||||
case BTC_MEDIA_AUDIO_SINK_CFG_UPDATE:
|
||||
btc_a2dp_sink_handle_decoder_reset(e->par);
|
||||
btc_a2dp_sink_handle_decoder_reset(e->param);
|
||||
break;
|
||||
case BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK:
|
||||
btc_a2dp_sink_handle_clear_track();
|
||||
@ -213,29 +220,12 @@ static void btc_a2dp_sink_ctrl_handler(BtTaskEvt_t *e)
|
||||
default:
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (e->param != NULL) {
|
||||
osi_free(e->param);
|
||||
}
|
||||
} else if (xActivatedMember == btc_aa_snk_ctrl_queue) {
|
||||
xQueueReceive(xActivatedMember, &e, 0);
|
||||
btc_a2dp_sink_ctrl_handler(e);
|
||||
|
||||
osi_free(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool btc_a2dp_sink_startup(void)
|
||||
@ -257,26 +247,14 @@ bool btc_a2dp_sink_startup(void)
|
||||
}
|
||||
#endif /* BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE */
|
||||
|
||||
btc_aa_snk_queue_set = xQueueCreateSet(BTC_A2DP_SINK_TASK_QUEUE_SET_LEN);
|
||||
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);
|
||||
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);
|
||||
if (btc_aa_snk_task_hdl == NULL) {
|
||||
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");
|
||||
|
||||
@ -284,24 +262,11 @@ bool btc_a2dp_sink_startup(void)
|
||||
|
||||
error_exit:;
|
||||
APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_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);
|
||||
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;
|
||||
|
||||
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)
|
||||
osi_free(btc_sbc_decoder_context_ptr);
|
||||
btc_sbc_decoder_context_ptr = NULL;
|
||||
@ -397,11 +353,9 @@ void btc_a2dp_sink_on_suspended(tBTA_AV_SUSPEND *p_av)
|
||||
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) {
|
||||
APPL_TRACE_DEBUG("Media data Q filled\n");
|
||||
}
|
||||
osi_thread_post(btc_aa_snk_task_hdl, btc_a2dp_sink_data_ready, NULL, 1, OSI_THREAD_BLOCKING);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -415,8 +369,7 @@ static void btc_a2dp_sink_data_post(int32_t data_type)
|
||||
*******************************************************************************/
|
||||
static BOOLEAN btc_a2dp_sink_clear_track(void)
|
||||
{
|
||||
btc_a2dp_sink_ctrl_post(BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK, NULL);
|
||||
return TRUE;
|
||||
return btc_a2dp_sink_ctrl_post(BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK, NULL);
|
||||
}
|
||||
|
||||
/* when true media task discards any rx frames */
|
||||
@ -685,8 +638,7 @@ BOOLEAN btc_a2dp_sink_rx_flush_req(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
btc_a2dp_sink_ctrl_post(BTC_MEDIA_FLUSH_AA_RX, NULL);
|
||||
return TRUE;
|
||||
return btc_a2dp_sink_ctrl_post(BTC_MEDIA_FLUSH_AA_RX, NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -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;
|
||||
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);
|
||||
btc_a2dp_sink_data_post(BTC_A2DP_SINK_DATA_EVT);
|
||||
btc_a2dp_sink_data_post();
|
||||
} else {
|
||||
/* let caller deal with a failed allocation */
|
||||
APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - ");
|
||||
|
@ -50,6 +50,13 @@
|
||||
|
||||
#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
|
||||
*****************************************************************************/
|
||||
@ -72,9 +79,6 @@ enum {
|
||||
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
|
||||
(1000/TICKS_PER_SEC) */
|
||||
@ -127,6 +131,11 @@ enum {
|
||||
#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ (5)
|
||||
#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 {
|
||||
UINT16 num_frames_to_be_processed;
|
||||
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_handle_timer(UNUSED_ATTR void *context);
|
||||
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 int btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_OFF;
|
||||
static future_t *btc_a2dp_source_future = NULL;
|
||||
static xTaskHandle 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 osi_thread_t *btc_aa_src_task_hdl = NULL;
|
||||
static esp_a2d_source_data_cb_t btc_aa_src_data_cb = NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
evt->sig = sig;
|
||||
evt->par = par;
|
||||
evt->param = param;
|
||||
|
||||
if (xQueueSend(btc_aa_src_ctrl_queue, &evt, portMAX_DELAY) != pdTRUE) {
|
||||
APPL_TRACE_WARNING("btc_aa_src_ctrl_queue failed, sig 0x%x\n", sig);
|
||||
}
|
||||
osi_thread_post(btc_aa_src_task_hdl, btc_a2dp_source_ctrl_handler, evt, 0, OSI_THREAD_BLOCKING);
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e->sig) {
|
||||
case BTC_MEDIA_TASK_INIT:
|
||||
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();
|
||||
break;
|
||||
case BTC_MEDIA_SBC_ENC_INIT:
|
||||
btc_a2dp_source_enc_init(e->par);
|
||||
btc_a2dp_source_enc_init(e->param);
|
||||
break;
|
||||
case BTC_MEDIA_SBC_ENC_UPDATE:
|
||||
btc_a2dp_source_enc_update(e->par);
|
||||
btc_a2dp_source_enc_update(e->param);
|
||||
break;
|
||||
case BTC_MEDIA_AUDIO_FEEDING_INIT:
|
||||
btc_a2dp_source_audio_feeding_init(e->par);
|
||||
btc_a2dp_source_audio_feeding_init(e->param);
|
||||
break;
|
||||
case BTC_MEDIA_FLUSH_AA_TX:
|
||||
btc_a2dp_source_aa_tx_flush();
|
||||
@ -282,29 +290,12 @@ static void btc_a2dp_source_ctrl_handler(BtTaskEvt_t *e)
|
||||
default:
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (e->param != NULL) {
|
||||
osi_free(e->param);
|
||||
}
|
||||
} else if (xActivatedMember == btc_aa_src_ctrl_queue) {
|
||||
xQueueReceive(xActivatedMember, &e, 0);
|
||||
btc_a2dp_source_ctrl_handler(e);
|
||||
|
||||
osi_free(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool btc_a2dp_source_startup(void)
|
||||
@ -324,57 +315,28 @@ bool btc_a2dp_source_startup(void)
|
||||
}
|
||||
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
|
||||
|
||||
btc_aa_src_queue_set = xQueueCreateSet(BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN);
|
||||
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);
|
||||
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);
|
||||
if (btc_aa_src_task_hdl == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
btc_a2dp_source_ctrl_post(BTC_MEDIA_TASK_INIT, NULL);
|
||||
|
||||
APPL_TRACE_EVENT("## A2DP SOURCE MEDIA THREAD STARTED ##\n");
|
||||
|
||||
return true;
|
||||
|
||||
error_exit:;
|
||||
APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
|
||||
|
||||
if (btc_aa_src_task_hdl != NULL) {
|
||||
vTaskDelete(btc_aa_src_task_hdl);
|
||||
osi_thread_free(btc_aa_src_task_hdl);
|
||||
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_encoder_ptr) {
|
||||
osi_free(btc_sbc_encoder_ptr);
|
||||
btc_sbc_encoder_ptr = NULL;
|
||||
}
|
||||
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -390,18 +352,9 @@ void btc_a2dp_source_shutdown(void)
|
||||
future_await(btc_a2dp_source_future);
|
||||
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;
|
||||
|
||||
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)
|
||||
osi_free(btc_sbc_encoder_ptr);
|
||||
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
APPL_TRACE_DEBUG("Media data Q filled\n");
|
||||
}
|
||||
osi_thread_post(btc_aa_src_task_hdl, btc_a2dp_source_handle_timer, NULL, 1, OSI_THREAD_BLOCKING);
|
||||
}
|
||||
|
||||
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 shutdown of the Bluetooth stack.
|
||||
*/
|
||||
#if 0
|
||||
if (btc_aa_src_ctrl_queue != NULL) {
|
||||
#endif
|
||||
btc_a2dp_source_ctrl_post(BTC_MEDIA_STOP_AA_TX, NULL);
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -696,9 +651,13 @@ BOOLEAN btc_a2dp_source_tx_flush_req(void)
|
||||
* the "cleanup() -> btc_a2dp_stop_media_task()" processing during
|
||||
* the shutdown of the Bluetooth stack.
|
||||
*/
|
||||
#if 0
|
||||
if (btc_aa_src_ctrl_queue != NULL) {
|
||||
#endif
|
||||
btc_a2dp_source_ctrl_post(BTC_MEDIA_FLUSH_AA_TX, NULL);
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
btc_a2dp_source_data_post(BTC_A2DP_SOURCE_DATA_EVT);
|
||||
btc_a2dp_source_data_post();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -39,6 +39,14 @@
|
||||
|
||||
#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
|
||||
|
@ -27,9 +27,17 @@
|
||||
#include "esp_bt.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)
|
||||
#include "l2c_int.h"
|
||||
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
|
||||
#include "stack/hcimsgs.h"
|
||||
|
||||
#define HCI_HAL_SERIAL_BUFFER_SIZE 1026
|
||||
#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_callbacks_t *callbacks;
|
||||
static const esp_vhci_host_callback_t vhci_host_cb;
|
||||
|
||||
static xTaskHandle xHciH4TaskHandle;
|
||||
static xQueueHandle xHciH4Queue;
|
||||
static osi_thread_t *hci_h4_thread;
|
||||
|
||||
static void host_send_pkt_available_cb(void);
|
||||
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);
|
||||
#endif
|
||||
|
||||
xHciH4Queue = xQueueCreate(HCI_H4_QUEUE_LEN, sizeof(BtTaskEvt_t));
|
||||
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);
|
||||
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);
|
||||
if (hci_h4_thread == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//register vhci host cb
|
||||
if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) {
|
||||
@ -125,9 +133,8 @@ static void hal_close()
|
||||
{
|
||||
hci_hal_env_deinit();
|
||||
|
||||
/* delete task and queue */
|
||||
vTaskDelete(xHciH4TaskHandle);
|
||||
vQueueDelete(xHciH4Queue);
|
||||
osi_thread_free(hci_h4_thread);
|
||||
hci_h4_thread = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,30 +176,12 @@ static uint16_t transmit_data(serial_data_type_t type,
|
||||
// Internal functions
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
evt.sig = SIG_HCI_HAL_RECV_PACKET;
|
||||
evt.par = 0;
|
||||
|
||||
if (xQueueSend(xHciH4Queue, &evt, timeout) != pdTRUE) {
|
||||
return TASK_POST_SUCCESS;
|
||||
}
|
||||
|
||||
return TASK_POST_FAIL;
|
||||
return osi_thread_post(hci_h4_thread, hci_hal_h4_rx_handler, NULL, 0, blocking);
|
||||
}
|
||||
|
||||
#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
|
||||
//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)
|
||||
@ -368,7 +357,8 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
|
||||
pkt->layer_specific = 0;
|
||||
memcpy(pkt->data, data, len);
|
||||
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);
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "common/bt_trace.h"
|
||||
#include "stack/hcidefs.h"
|
||||
#include "stack/hcimsgs.h"
|
||||
#include "stack/btu.h"
|
||||
#include "common/bt_vendor_lib.h"
|
||||
#include "hci/hci_internals.h"
|
||||
#include "hci/hci_hal.h"
|
||||
@ -33,6 +34,12 @@
|
||||
#include "osi/mutex.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 {
|
||||
uint16_t opcode;
|
||||
future_t *complete_future;
|
||||
@ -70,10 +77,7 @@ static const uint32_t COMMAND_PENDING_TIMEOUT = 8000;
|
||||
static bool interface_created;
|
||||
static hci_t interface;
|
||||
static hci_host_env_t hci_host_env;
|
||||
|
||||
static xTaskHandle xHciHostTaskHandle;
|
||||
static xQueueHandle xHciHostQueue;
|
||||
|
||||
static osi_thread_t *hci_host_thread;
|
||||
static bool hci_host_startup_flag;
|
||||
|
||||
// Modules we import and callbacks we export
|
||||
@ -102,8 +106,10 @@ int hci_start_up(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
xHciHostQueue = xQueueCreate(HCI_HOST_QUEUE_LEN, sizeof(BtTaskEvt_t));
|
||||
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);
|
||||
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);
|
||||
if (hci_host_thread == NULL) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
packet_fragmenter->init(&packet_fragmenter_callbacks);
|
||||
hal->open(&hal_callbacks);
|
||||
@ -124,28 +130,15 @@ void hci_shut_down(void)
|
||||
|
||||
//low_power_manager->cleanup();
|
||||
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;
|
||||
|
||||
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;
|
||||
return osi_thread_post(hci_host_thread, hci_host_thread_handler, NULL, 0, blocking);
|
||||
}
|
||||
|
||||
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
|
||||
* 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()) {
|
||||
/*Now Target only allowed one packet per TX*/
|
||||
BT_HDR *pkt = packet_fragmenter->fragment_current_packet();
|
||||
@ -239,9 +225,6 @@ static void hci_host_thread_handler(void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void transmit_command(
|
||||
@ -271,7 +254,7 @@ static void transmit_command(
|
||||
BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -305,7 +288,7 @@ static void transmit_downward(uint16_t type, void *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*/
|
||||
if (hci_host_env.command_credits &&
|
||||
!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) {
|
||||
@ -507,7 +490,7 @@ static void dispatch_reassembled(BT_HDR *packet)
|
||||
{
|
||||
// Events should already have been dispatched before this point
|
||||
//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);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/osi.h"
|
||||
#include "osi/future.h"
|
||||
#include "osi/thread.h"
|
||||
|
||||
///// LEGACY DEFINITIONS /////
|
||||
|
||||
/* 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);
|
||||
void hci_shut_down(void);
|
||||
|
||||
bool hci_host_task_post(osi_thread_blocking_t blocking);
|
||||
|
||||
#endif /* _HCI_LAYER_H_ */
|
||||
|
@ -25,91 +25,33 @@
|
||||
|
||||
#define portBASE_TYPE int
|
||||
|
||||
struct bt_task_evt {
|
||||
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;
|
||||
struct osi_thread;
|
||||
|
||||
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 {
|
||||
SIG_HCI_HAL_RECV_PACKET = 0,
|
||||
SIG_HCI_HAL_NUM,
|
||||
} SIG_HCI_HAL_t;
|
||||
|
||||
OSI_THREAD_CORE_0 = 0,
|
||||
OSI_THREAD_CORE_1,
|
||||
OSI_THREAD_CORE_AFFINITY,
|
||||
} osi_thread_core_t;
|
||||
|
||||
typedef enum {
|
||||
SIG_HCI_HOST_SEND_AVAILABLE = 0,
|
||||
SIG_HCI_HOST_NUM,
|
||||
} SIG_HCI_HOST_t;
|
||||
OSI_THREAD_NON_BLOCKING = 0,
|
||||
OSI_THREAD_BLOCKING,
|
||||
} osi_thread_blocking_t;
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
#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)
|
||||
#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
|
||||
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_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
|
||||
bool osi_thread_set_priority(osi_thread_t *thread, int priority);
|
||||
|
||||
#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
||||
#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
|
||||
const char *osi_thread_name(osi_thread_t *thread);
|
||||
|
||||
#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
||||
#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);
|
||||
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx);
|
||||
|
||||
#endif /* __THREAD_H__ */
|
||||
|
282
components/bt/bluedroid/osi/thread.c
Normal file
282
components/bt/bluedroid/osi/thread.c
Normal 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]);
|
||||
}
|
@ -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;
|
||||
|
||||
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;
|
||||
|
||||
btu_task_post(SIG_BTU_HCI_MSG, event, TASK_POST_BLOCKING);
|
||||
btu_task_post(SIG_BTU_HCI_MSG, event, OSI_THREAD_BLOCKING);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -44,6 +44,12 @@
|
||||
#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;
|
||||
osi_mutex_t btu_general_alarm_lock;
|
||||
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;
|
||||
static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 34;
|
||||
|
||||
//thread_t *bt_workqueue_thread;
|
||||
//static const char *BT_WORKQUEUE_NAME = "bt_workqueue";
|
||||
xTaskHandle xBtuTaskHandle = NULL;
|
||||
xQueueHandle xBtuQueue = 0;
|
||||
osi_thread_t *btu_thread = NULL;
|
||||
|
||||
extern void PLATFORM_DisableHciTransport(UINT8 bDisable);
|
||||
|
||||
extern void btu_task_thread_handler(void *arg);
|
||||
void btu_task_start_up(void);
|
||||
void btu_task_shut_down(void);
|
||||
|
||||
/*****************************************************************************
|
||||
** V A R I A B L E S *
|
||||
******************************************************************************/
|
||||
@ -178,10 +182,14 @@ void BTU_StartUp(void)
|
||||
|
||||
osi_mutex_new(&btu_l2cap_alarm_lock);
|
||||
|
||||
xBtuQueue = xQueueCreate(BTU_QUEUE_LEN, sizeof(BtTaskEvt_t));
|
||||
xTaskCreatePinnedToCore(btu_task_thread_handler, BTU_TASK_NAME, BTU_TASK_STACK_SIZE, NULL, BTU_TASK_PRIO, &xBtuTaskHandle, BTU_TASK_PINNED_TO_CORE);
|
||||
btu_thread = osi_thread_create(BTU_TASK_NAME, BTU_TASK_STACK_SIZE, BTU_TASK_PRIO, BTU_TASK_PINNED_TO_CORE, 1);
|
||||
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;
|
||||
|
||||
@ -206,17 +214,14 @@ void BTU_ShutDown(void)
|
||||
hash_map_free(btu_l2cap_alarm_hash_map);
|
||||
osi_mutex_free(&btu_l2cap_alarm_lock);
|
||||
|
||||
vTaskDelete(xBtuTaskHandle);
|
||||
vQueueDelete(xBtuQueue);
|
||||
if (btu_thread) {
|
||||
osi_thread_free(btu_thread);
|
||||
btu_thread = NULL;
|
||||
}
|
||||
|
||||
btu_general_alarm_hash_map = NULL;
|
||||
|
||||
btu_oneshot_alarm_hash_map = NULL;
|
||||
|
||||
btu_l2cap_alarm_hash_map = NULL;
|
||||
|
||||
xBtuTaskHandle = NULL;
|
||||
xBtuQueue = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -236,13 +241,14 @@ UINT16 BTU_BleAclPktSize(void)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SCAN_QUEUE_CONGEST_CHECK
|
||||
bool BTU_check_queue_is_congest(void)
|
||||
{
|
||||
UBaseType_t wait_size = uxQueueMessagesWaiting(xBtuQueue);
|
||||
if(wait_size >= QUEUE_CONGEST_SIZE ) {
|
||||
if (osi_thread_queue_wait_size(btu_thread, 0) >= QUEUE_CONGEST_SIZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
@ -81,6 +81,11 @@ extern void avdt_rcv_sync_info (BT_HDR *p_buf);
|
||||
#include "btm_ble_int.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t sig;
|
||||
void *param;
|
||||
} btu_thread_evt_t;
|
||||
|
||||
//#if (defined(BT_APP_DEMO) && BT_APP_DEMO == TRUE)
|
||||
//#include "bt_app_common.h"
|
||||
//#endif
|
||||
@ -107,8 +112,8 @@ extern osi_mutex_t btu_oneshot_alarm_lock;
|
||||
extern hash_map_t *btu_l2cap_alarm_hash_map;
|
||||
extern osi_mutex_t btu_l2cap_alarm_lock;
|
||||
|
||||
extern xTaskHandle xBtuTaskHandle;
|
||||
extern xQueueHandle xBtuQueue;
|
||||
extern void *btu_thread;
|
||||
|
||||
extern bluedroid_init_done_cb_t bluedroid_init_done_cb;
|
||||
|
||||
/* 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
|
||||
|
||||
/*****************************************************************************
|
||||
**
|
||||
** Function btu_task_thread_handler
|
||||
**
|
||||
** Description Process BTU Task Thread.
|
||||
******************************************************************************/
|
||||
void btu_task_thread_handler(void *arg)
|
||||
void btu_thread_handler(void *arg)
|
||||
{
|
||||
BtTaskEvt_t e;
|
||||
btu_thread_evt_t *evt = (btu_thread_evt_t *)arg;
|
||||
|
||||
for (;;) {
|
||||
if (pdTRUE == xQueueReceive(xBtuQueue, &e, (portTickType)portMAX_DELAY)) {
|
||||
|
||||
switch (e.sig) {
|
||||
switch (evt->sig) {
|
||||
case SIG_BTU_START_UP:
|
||||
btu_task_start_up();
|
||||
break;
|
||||
case SIG_BTU_HCI_MSG:
|
||||
btu_hci_msg_process((BT_HDR *)e.par);
|
||||
btu_hci_msg_process((BT_HDR *)evt->param);
|
||||
break;
|
||||
#if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
|
||||
case SIG_BTU_BTA_MSG:
|
||||
bta_sys_event((BT_HDR *)e.par);
|
||||
bta_sys_event((BT_HDR *)evt->param);
|
||||
break;
|
||||
case SIG_BTU_BTA_ALARM:
|
||||
btu_bta_alarm_process((TIMER_LIST_ENT *)e.par);
|
||||
btu_bta_alarm_process((TIMER_LIST_ENT *)evt->param);
|
||||
break;
|
||||
#endif
|
||||
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;
|
||||
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:
|
||||
btu_l2cap_alarm_process((TIMER_LIST_ENT *)e.par);
|
||||
btu_l2cap_alarm_process((TIMER_LIST_ENT *)evt->param);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osi_free(evt);
|
||||
}
|
||||
|
||||
|
||||
task_post_status_t btu_task_post(uint32_t sig, void *param, task_post_t timeout)
|
||||
bool btu_task_post(uint32_t sig, void *param, osi_thread_blocking_t blocking)
|
||||
{
|
||||
BtTaskEvt_t evt;
|
||||
btu_thread_evt_t *evt;
|
||||
|
||||
evt.sig = sig;
|
||||
evt.par = param;
|
||||
|
||||
if (xQueueSend(xBtuQueue, &evt, timeout) != pdTRUE) {
|
||||
HCI_TRACE_ERROR("xBtuQueue failed\n");
|
||||
return TASK_POST_FAIL;
|
||||
evt = (btu_thread_evt_t *)osi_malloc(sizeof(btu_thread_evt_t));
|
||||
if (evt == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
@ -426,7 +417,7 @@ void btu_general_alarm_cb(void *data)
|
||||
assert(data != NULL);
|
||||
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)
|
||||
@ -540,7 +531,7 @@ static void btu_l2cap_alarm_cb(void *data)
|
||||
assert(data != NULL);
|
||||
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)
|
||||
@ -623,7 +614,7 @@ void btu_oneshot_alarm_cb(void *data)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "common/bt_defs.h"
|
||||
#include "osi/thread.h"
|
||||
|
||||
// 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
|
||||
@ -163,6 +164,17 @@ typedef void (*tBTU_EVENT_CALLBACK)(BT_HDR *p_hdr);
|
||||
#define BTU_TTYPE_UCD_TO 108
|
||||
#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
|
||||
** to applications.
|
||||
@ -276,6 +288,8 @@ void btu_task_shut_down(void);
|
||||
|
||||
UINT16 BTU_BleAclPktSize(void);
|
||||
|
||||
bool btu_task_post(uint32_t sig, void *param, osi_thread_blocking_t blocking);
|
||||
|
||||
/*
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user