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/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"
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 - ");
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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_ */
|
||||||
|
@ -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__ */
|
||||||
|
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;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user