首先以gki模块的初始化为入口,在gki_ulinux.c中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
void
GKI_init(
void
)
{
pthread_mutexattr_t attr;
tGKI_OS *p_os;
memset (&gki_cb,
0
, sizeof (gki_cb));
gki_buffer_init();
gki_timers_init();
alarm_service_init();
gki_cb.com.OSTicks = (UINT32) times(
0
);
pthread_mutexattr_init(&attr);
p_os = &gki_cb.os;
pthread_mutex_init(&p_os->GKI_mutex, &attr);
struct sigevent sigevent;
memset(&sigevent,
0
, sizeof(sigevent));
sigevent.sigev_notify = SIGEV_THREAD;
sigevent.sigev_notify_function = (
void
(*)(union sigval))bt_alarm_cb;
sigevent.sigev_value.sival_ptr = NULL;
if
(timer_create(CLOCK_REALTIME, &sigevent, &posix_timer) == -
1
) {
timer_created =
false
;
}
else
{
timer_created =
true
;
}
}
|
首先将gki_cb清零,这个变量非常重要,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
tGKI_CB gki_cb;
typedef struct
{
tGKI_OS os;
tGKI_COM_CB com;
} tGKI_CB;
typedef struct
{
pthread_mutex_t GKI_mutex;
pthread_t thread_id[GKI_MAX_TASKS];
pthread_mutex_t thread_evt_mutex[GKI_MAX_TASKS];
pthread_cond_t thread_evt_cond[GKI_MAX_TASKS];
pthread_mutex_t thread_timeout_mutex[GKI_MAX_TASKS];
pthread_cond_t thread_timeout_cond[GKI_MAX_TASKS];
} tGKI_OS;
typedef struct {
UINT8 *OSStack[GKI_MAX_TASKS];
/* pointer to beginning of stack */
UINT16 OSStackSize[GKI_MAX_TASKS];
/* stack size available to each task */
INT8 *OSTName[GKI_MAX_TASKS];
/* name of the task */
UINT8 OSRdyTbl[GKI_MAX_TASKS];
/* current state of the task */
UINT16 OSWaitEvt[GKI_MAX_TASKS];
/* events that have to be processed by the task */
UINT16 OSWaitForEvt[GKI_MAX_TASKS];
/* events the task is waiting for*/
UINT32 OSTicks;
/* system ticks from start */
UINT32 OSIdleCnt;
/* idle counter */
INT16 OSDisableNesting;
/* counter to keep track of interrupt disable nesting */
INT16 OSLockNesting;
/* counter to keep track of sched lock nesting */
INT16 OSIntNesting;
/* counter to keep track of interrupt nesting */
/* Timer related variables
*/
INT32 OSTicksTilExp;
/* Number of ticks till next timer expires */
INT32 OSNumOrigTicks;
/* Number of ticks between last timer expiration to the next one */
INT32 OSWaitTmr [GKI_MAX_TASKS];
/* ticks the task has to wait, for specific events */
/* Buffer related variables
*/
BUFFER_HDR_T *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX];
/* array of pointers to the first event in the task mailbox */
BUFFER_HDR_T *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX];
/* array of pointers to the last event in the task mailbox */
/* Define the buffer pool management variables
*/
FREE_QUEUE_T freeq[GKI_NUM_TOTAL_BUF_POOLS];
UINT16 pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];
UINT16 pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];
UINT16 pool_additions[GKI_NUM_TOTAL_BUF_POOLS];
/* Define the buffer pool start addresses
*/
UINT8 *pool_start[GKI_NUM_TOTAL_BUF_POOLS];
/* array of pointers to the start of each buffer pool */
UINT8 *pool_end[GKI_NUM_TOTAL_BUF_POOLS];
/* array of pointers to the end of each buffer pool */
UINT16 pool_size[GKI_NUM_TOTAL_BUF_POOLS];
/* actual size of the buffers in a pool */
/* Define the buffer pool access control variables */
void
*p_user_mempool;
/* User O/S memory pool */
UINT16 pool_access_mask;
/* Bits are set if the corresponding buffer pool is a restricted pool */
UINT8 pool_list[GKI_NUM_TOTAL_BUF_POOLS];
/* buffer pools arranged in the order of size */
UINT8 curr_total_no_of_pools;
/* number of fixed buf pools + current number of dynamic pools */
BOOLEAN timer_nesting;
/* flag to prevent timer interrupt nesting */
} tGKI_COM_CB;
|
tGKI_OS里有个GKI全局锁,一个线程池,还有关于evt和timeout的锁和条件变量。tGKI_COM_CB作为整个GKI的控制中心,里面的数据结构很复杂。
我们继续回到gki_init,在将gki_cb清零后,接下里先后初始化buffer, timer和alarm_service。然后初始化tGKI_OS中的GKI全局锁,最后创建一个定时器,当定时器到期时内核会启动一个线程执行bt_alarm_cb回调函数。
再来看gki_buffer_init是如何初始化缓冲区的,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
void
gki_buffer_init(
void
)
{
UINT8 i, tt, mb;
tGKI_COM_CB *p_cb = &gki_cb.com;
/* Initialize mailboxes */
for
(tt =
0
; tt < GKI_MAX_TASKS; tt++)
{
for
(mb =
0
; mb < NUM_TASK_MBOX; mb++)
{
p_cb->OSTaskQFirst[tt][mb] = NULL;
p_cb->OSTaskQLast [tt][mb] = NULL;
}
}
for
(tt =
0
; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
{
p_cb->pool_start[tt] = NULL;
p_cb->pool_end[tt] = NULL;
p_cb->pool_size[tt] =
0
;
p_cb->freeq[tt].p_first =
0
;
p_cb->freeq[tt].p_last =
0
;
p_cb->freeq[tt].size =
0
;
p_cb->freeq[tt].total =
0
;
p_cb->freeq[tt].cur_cnt =
0
;
p_cb->freeq[tt].max_cnt =
0
;
}
/* Use default from target.h */
p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
/* add pools to the pool_list which is arranged in the order of size */
for
(i=
0
; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
{
p_cb->pool_list[i] = i;
}
p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
return
;
}
|
GKI缓冲区相关的控制数据结构都在tGKI_COM_CB中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
/* Buffer related variables */
BUFFER_HDR_T *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX];
/* array of pointers to the first event in the task mailbox */
BUFFER_HDR_T *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX];
/* array of pointers to the last event in the task mailbox */
typedef struct _buffer_hdr
{
struct _buffer_hdr *p_next;
/* next buffer in the queue */
UINT8 q_id;
/* id of the queue */
UINT8 task_id;
/* task which allocated the buffer*/
UINT8 status;
/* FREE, UNLINKED or QUEUED */
UINT8 Type;
} BUFFER_HDR_T;
|
这里OSTaskQFirst和OSTaskQLast是个BUFFER_HDR_T的二维数组,看上去每个TASK有一个TASK_MBOX数组:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#define GKI_MAX_TASKS
3
/************************************************************************
** Mailbox definitions. Each task has 4 mailboxes that are used to
** send buffers to the task.
*/
#define TASK_MBOX_0
0
#define TASK_MBOX_1
1
#define TASK_MBOX_2
2
#define TASK_MBOX_3
3
#define NUM_TASK_MBOX
4
#define GKI_NUM_TOTAL_BUF_POOLS
10
|
从注释上看每个task有4个mailbox,这个mailbox是用于向task发送buffer的,buffer中可能带了各种参数。
我们回到gki_buffer_init中看是如何初始化buffer的,首先将所有的mailbox都初始化为null,然后gki中一共有GKI_NUM_TOTAL_BUF_POOLS个缓冲池都需要初始化。
再来看gki_timers_init是如何初始化timers的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
void
gki_timers_init(
void
)
{
UINT8 tt;
gki_cb.com.OSTicksTilExp =
0
;
/* Remaining time (of OSTimeCurTimeout) before next timer expires */
gki_cb.com.OSNumOrigTicks =
0
;
for
(tt =
0
; tt < GKI_MAX_TASKS; tt++)
{
gki_cb.com.OSWaitTmr [tt] =
0
;
}
return
;
}
|
timers相比buffer就简单多了,只有三个变量相关,如下:
1
2
3
4
5
|
/* Timer related variables */
INT32 OSTicksTilExp;
/* Number of ticks till next timer expires */
INT32 OSNumOrigTicks;
/* Number of ticks between last timer expiration to the next one */
INT32 OSWaitTmr [GKI_MAX_TASKS];
/* ticks the task has to wait, for specific events */
|
这里的初始化就是给他们都设为0而已。
再来看看alarm_service_init,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
static
void
alarm_service_init() {
alarm_service.ticks_scheduled =
0
;
alarm_service.timer_started_us =
0
;
alarm_service.timer_last_expired_us =
0
;
alarm_service.wakelock = FALSE;
raise_priority_a2dp(TASK_JAVA_ALARM);
}
// Alarm service structure used to pass up via JNI to the bluetooth
// app in order to create a wakeable Alarm.
typedef struct
{
UINT32 ticks_scheduled;
UINT64 timer_started_us;
UINT64 timer_last_expired_us;
bool wakelock;
} alarm_service_t;
|
到这里gki初始化完成了,GKI_init是被谁调用的呢?是被bte_main.c中的bte_main_boot_entry调用的,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/******************************************************************************
**
** Function bte_main_boot_entry
**
** Description BTE MAIN API - Entry point for BTE chip/stack initialization
**
** Returns None
**
******************************************************************************/
void
bte_main_boot_entry(
void
)
{
/* initialize OS */
GKI_init();
bte_main_in_hw_init();
bte_load_conf(BTE_STACK_CONF_FILE);
bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE);
pthread_mutex_init(&cleanup_lock, NULL);
}
|
bte_main_boot_entry又是被谁调用的呢?在btif_core.c的btif_init_bluetooth中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
bt_status_t btif_init_bluetooth() {
UINT8 status;
btif_config_init();
bte_main_boot_entry();
/* As part of the init, fetch the local BD ADDR */
memset(&btif_local_bd_addr,
0
, sizeof(bt_bdaddr_t));
btif_fetch_local_bdaddr(&btif_local_bd_addr);
/* start btif task */
status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
(UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
sizeof(btif_task_stack));
if
(status != GKI_SUCCESS)
return
BT_STATUS_FAIL;
return
BT_STATUS_SUCCESS;
}
|
而btif_init_bluetooth又是被bluetooth.c中init函数调用的,而这个Init又是被谁调用的呢?在Bluetooth.c中如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
static
const
bt_interface_t bluetoothInterface = {
sizeof(bluetoothInterface),
init,
enable,
disable,
cleanup,
get_adapter_properties,
get_adapter_property,
set_adapter_property,
get_remote_device_properties,
get_remote_device_property,
set_remote_device_property,
get_remote_service_record,
get_remote_services,
start_discovery,
cancel_discovery,
create_bond,
remove_bond,
cancel_bond,
get_connection_state,
pin_reply,
ssp_reply,
get_profile_interface,
dut_mode_configure,
dut_mode_send,
#
if
BLE_INCLUDED == TRUE
le_test_mode,
#
else
NULL,
#endif
config_hci_snoop_log,
set_os_callouts,
read_energy_info,
};
const
bt_interface_t* bluetooth__get_bluetooth_interface ()
{
/* fixme -- add property to disable bt interface ? */
return
&bluetoothInterface;
}
static
int
open_bluetooth_stack (
const
struct hw_module_t* module,
char
const
* name,
struct hw_device_t** abstraction)
{
UNUSED(name);
bluetooth_device_t *stack = malloc(sizeof(bluetooth_device_t) );
memset(stack,
0
, sizeof(bluetooth_device_t) );
stack->common.tag = HARDWARE_DEVICE_TAG;
stack->common.version =
0
;
stack->common.module = (struct hw_module_t*)module;
stack->common.close = close_bluetooth_stack;
stack->get_bluetooth_interface = bluetooth__get_bluetooth_interface;
*abstraction = (struct hw_device_t*)stack;
return
0
;
}
static
struct hw_module_methods_t bt_stack_module_methods = {
.open = open_bluetooth_stack,
};
struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
.version_major =
1
,
.version_minor =
0
,
.id = BT_HARDWARE_MODULE_ID,
.name =
"Bluetooth Stack"
,
.author =
"The Android Open Source Project"
,
.methods = &bt_stack_module_methods
};
|
在com_android_bluetooth_btservice_AdapterService.cpp中初始化时有如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
const
char
*id = (strcmp(value,
"1"
)? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
err = hw_get_module(id, (hw_module_t
const
**) &module);
if
(err ==
0
) {
hw_device_t* abstraction;
err = module->methods->open(module, id, &abstraction);
if
(err ==
0
) {
bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
sBluetoothInterface = btStack->get_bluetooth_interface();
}
else
{
ALOGE(
"Error while opening Bluetooth library"
);
}
}
|
这个sBluetoothInterface就是Bluetooth.c中的&bluetoothInterface,这里面有很多函数指针,当调用init时最终就会走到GKI_init。什么时候调用的呢?在initNative中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
static
bool initNative(JNIEnv* env, jobject obj) {
sJniAdapterServiceObj = env->NewGlobalRef(obj);
sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
if
(sBluetoothInterface) {
int
ret = sBluetoothInterface->init(&sBluetoothCallbacks);
if
(ret != BT_STATUS_SUCCESS) {
ALOGE(
"Error while setting the callbacks: %d\n"
, ret);
sBluetoothInterface = NULL;
return
JNI_FALSE;
}
ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
if
(ret != BT_STATUS_SUCCESS) {
ALOGE(
"Error while setting Bluetooth callouts: %d\n"
, ret);
sBluetoothInterface->cleanup();
sBluetoothInterface = NULL;
return
JNI_FALSE;
}
if
( (sBluetoothSocketInterface = (btsock_interface_t *)
sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
ALOGE(
"Error getting socket interface"
);
}
return
JNI_TRUE;
}
return
JNI_FALSE;
}
|
而这个InitNative是AdapterService.java中的native函数,如下:
1
|
private
native
boolean
initNative();
|
该函数调用是在AdapterService的onCreate时,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@Override
public
void
onCreate() {
super
.onCreate();
debugLog(
"onCreate()"
);
mBinder =
new
AdapterServiceBinder(
this
);
mAdapterProperties =
new
AdapterProperties(
this
);
mAdapterStateMachine = AdapterState.make(
this
, mAdapterProperties);
mJniCallbacks =
new
JniCallbacks(mAdapterStateMachine, mAdapterProperties);
initNative();
mNativeAvailable=
true
;
mCallbacks =
new
RemoteCallbackList
//Load the name and address
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mSdpManager = SdpManager.init(
this
);
registerReceiver(mAlarmBroadcastReceiver,
new
IntentFilter(ACTION_ALARM_WAKEUP));
mProfileObserver =
new
ProfileObserver(getApplicationContext(),
this
,
new
Handler());
mProfileObserver.start();
}
|
好了,GKI初始化的整个调用路径都搞清楚了,接下来看GKI_create_task是如何创建任务的,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize)
{
struct sched_param param;
int
policy, ret =
0
;
pthread_attr_t attr1;
gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
gki_cb.com.OSTName[task_id] = taskname;
gki_cb.com.OSWaitTmr[task_id] =
0
;
gki_cb.com.OSWaitEvt[task_id] =
0
;
/* Initialize mutex and condition variable objects for events and timeouts */
pthread_condattr_t cond_attr;
pthread_condattr_init(&cond_attr);
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
pthread_cond_init (&gki_cb.os.thread_evt_cond[task_id], &cond_attr);
pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], NULL);
/* On Android, the new tasks starts running before 'gki_cb.os.thread_id[task_id]' is initialized */
/* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id] for it calls GKI_wait */
gki_pthread_info[task_id].task_id = task_id;
gki_pthread_info[task_id].task_entry = task_entry;
gki_pthread_info[task_id].params =
0
;
ret = pthread_create( &gki_cb.os.thread_id[task_id],
&attr1,
(
void
*)gki_task_entry,
&gki_pthread_info[task_id]);
return
(GKI_SUCCESS);
}
|
这里会创建一个线程执行gki_task_entry,我们看看这个线程入口函数,如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
static
void
gki_task_entry(UINT32 params)
{
gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;
gki_cb.os.thread_id[p_pthread_info->task_id] = pthread_self();
prctl(PR_SET_NAME, (unsigned
long
)gki_cb.com.OSTName[p_pthread_info->task_id],
0
,
0
,
0
);
/* Call the actual thread entry point */
(p_pthread_info->task_entry)(p_pthread_info->params);
pthread_exit(
0
);
/* GKI tasks have no return value */
}
|
这里prctl用于给线程重命名,然后关键是执行线程的task_entry函数,这个task_entry是GKI_create_task时传入的回调。
我们再来看看哪里调用过了GKI_create_task,主要是两个地方,一个是btif_core.c中的btif_init_bluetooth,另一处是bte_main.c中的bte_main_enable。我们先看btif_init_bluetooth,因为这是初始化后创建的第一个task。
1
2
3
4
|
/* start btif task */
status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
(UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
sizeof(btif_task_stack));
|
第一个参数是任务的入口函数,第二个是taskid,第三个是task名称,如下:
1
2
3
4
|
#define BTIF_TASK_STR ((INT8 *)
"BTIF"
)
#define BTU_TASK
0
#define BTIF_TASK
1
#define A2DP_MEDIA_TASK
2
|
看来这个btif task是个蓝牙核心线程,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
static
void
btif_task(UINT32 params)
{
UINT16 event;
BT_HDR *p_msg;
btif_associate_evt();
for
(;;)
{
/* wait for specified events */
event = GKI_wait(
0xFFFF
,
0
);
/*
* Wait for the trigger to init chip and stack. This trigger will
* be received by btu_task once the UART is opened and ready
*/
if
(event == BT_EVT_TRIGGER_STACK_INIT)
{
#
if
(BLE_INCLUDED == TRUE)
btif_dm_load_ble_local_keys();
#endif
BTA_EnableBluetooth(bte_dm_evt);
}
/*
* Failed to initialize controller hardware, reset state and bring
* down all threads
*/
if
(event == BT_EVT_HARDWARE_INIT_FAIL)
{
bte_main_disable();
btif_queue_release();
GKI_task_self_cleanup(BTIF_TASK);
bte_main_shutdown();
btif_dut_mode =
0
;
btif_core_state = BTIF_CORE_STATE_DISABLED;
HAL_CBACK(bt_hal_cbacks,adapter_state_changed_cb,BT_STATE_OFF);
break
;
}
if
(event & EVENT_MASK(GKI_SHUTDOWN_EVT))
break
;
if
(event & TASK_MBOX_1_EVT_MASK)
{
while
((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL)
{
switch
(p_msg->event)
{
case
BT_EVT_CONTEXT_SWITCH_EVT:
btif_context_switched(p_msg);
break
;
default
:
BTIF_TRACE_ERROR(
"unhandled btif event (%d)"
, p_msg->event & BT_EVT_MASK);
break
;
}
GKI_freebuf(p_msg);
}
}
}
btif_disassociate_evt();
}
|
这里在一个无限for循环中用GKI_wait等待事件,当遇到某些事件时break。接下来看看bte_main.c中的bte_main_enable,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
void
bte_main_enable()
{
/* Initialize BTE control block */
BTE_Init();
lpm_enabled = FALSE;
GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
(UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
sizeof(bte_btu_stack));
bte_hci_enable();
GKI_run();
}
|
原来BTU_TASK是在这里初始化的,看下入口函数btu_task,如下:
1
2
3
4
5
6
7
8
9
10
11
|
/*******************************************************************************
**
** Function btu_task
**
** Description This is the main task of the Bluetooth Upper Layers unit.
** It sits in a loop waiting for messages, and dispatches them
** to the appropiate handlers.
**
** Returns should never return
**
*******************************************************************************/
|
BTU_API UINT32 btu_task (UINT32 param)
{
UINT16 event;
BT_HDR *p_msg;
UINT8 i;
UINT16 mask;
BOOLEAN handled;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
(BTU, BTM, L2CAP, and SDP)
*/
btu_init_core();
/* Initialize any optional stack components */
BTE_InitStack();
bta_sys_init();
/* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);
prctl(PR_SET_NAME, (unsigned
long
)
"BTU TASK"
,
0
,
0
,
0
);
raise_priority_a2dp(TASK_HIGH_BTU);
/* Wait for, and process, events */
for
(;;)
{
event = GKI_wait (
0xFFFF
,
0
);
if
(event & TASK_MBOX_0_EVT_MASK)
{
/* Process all messages in the queue */
while
((p_msg = (BT_HDR *) GKI_read_mbox (BTU_HCI_RCV_MBOX)) != NULL)
{
/* Determine the input message type. */
switch
(p_msg->event & BT_EVT_MASK)
{
}
}
}
}
return
(
0
);
|
}
这里省略了不少代码,可以看到BTU_TASK远比BTIF_TASK复杂,不过结构都一样,也是在一个loop里不停地GKI_wait获取event,然后处理event。从注释上看BTU是Bluetooth Upper Layers unit的意思。这里我们暂时不去看各种event的处理,只是了解整个底层GKI的架构。
我们注意到这里在进入loop之前做了一些初始化,先看btu_init_core,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
{
/* Initialize the mandatory core stack components */
btm_init();
l2c_init();
sdp_init();
#
if
BLE_INCLUDED == TRUE
gatt_init();
#
if
(defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)
SMP_Init();
#endif
btm_ble_init();
#endif
}
|
再往下看会调GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);向BTIF_TASK发送BT_EVT_TRIGGER_STACK_INIT这个event。我们来看GKI是如何发送消息的,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
**
** Function GKI_send_event
**
** Description This function is called by tasks to send events to other
** tasks. Tasks can also send events to themselves.
**
** Parameters: task_id - (input) The id of the task to which the event has to
** be sent
** event - (input) The event that has to be sent
**
**
** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
**
*******************************************************************************/
UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
{
if
(task_id < GKI_MAX_TASKS)
{
/* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
/* Set the event bit */
gki_cb.com.OSWaitEvt[task_id] |= event;
pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
return
( GKI_SUCCESS );
}
return
(GKI_FAILURE);
}
|
这里先给目标task的event锁锁上,然后或上该task等待的event,通知该task线程有新的event了,然后解锁返回。我们再看看GKI_wait是如何等待event的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
**
** Function GKI_wait
**
** Description This function is called by tasks to wait for a specific
** event or set of events. The task may specify the duration
** that it wants to wait for, or 0 if infinite.
**
** Parameters: flag - (input) the event or set of events to wait for
** timeout - (input) the duration that the task wants to wait
** for the specific events (in system ticks)
**
**
** Returns the event mask of received events or zero if timeout
**
*******************************************************************************/
UINT16 GKI_wait (UINT16 flag, UINT32 timeout)
{
UINT16 evt;
UINT8 rtask;
struct timespec abstime = {
0
,
0
};
int
sec;
int
nano_sec;
rtask = GKI_get_taskid();
gki_cb.com.OSWaitForEvt[rtask] = flag;
/* protect OSWaitEvt[rtask] from modification from an other thread */
pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
if
(!(gki_cb.com.OSWaitEvt[rtask] & flag))
{
if
(timeout)
{
clock_gettime(CLOCK_MONOTONIC, &abstime);
/* add timeout */
sec = timeout /
1000
;
nano_sec = (timeout %
1000
) * NANOSEC_PER_MILLISEC;
abstime.tv_nsec += nano_sec;
if
(abstime.tv_nsec > NSEC_PER_SEC)
{
abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
}
abstime.tv_sec += sec;
pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],
&gki_cb.os.thread_evt_mutex[rtask], &abstime);
}
else
{
pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask], &gki_cb.os.thread_evt_mutex[rtask]);
}
/* TODO: check, this is probably neither not needed depending on phtread_cond_wait() implmentation,
e.g. it looks like it is implemented as a counter in which case multiple cond_signal
should NOT be lost! */
/* we are waking up after waiting for some events, so refresh variables
no need to call GKI_disable() here as we know that we will have some events as we've been waking
up after condition pending or timeout */
if
(gki_cb.com.OSTaskQFirst[rtask][
0
])
gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
if
(gki_cb.com.OSTaskQFirst[rtask][
1
])
gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
if
(gki_cb.com.OSTaskQFirst[rtask][
2
])
gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
if
(gki_cb.com.OSTaskQFirst[rtask][
3
])
gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
if
(gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
{
gki_cb.com.OSWaitEvt[rtask] =
0
;
/* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond is met */
pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
return
(EVENT_MASK(GKI_SHUTDOWN_EVT));
}
}
/* Clear the wait for event mask */
gki_cb.com.OSWaitForEvt[rtask] =
0
;
/* Return only those bits which user wants... */
evt = gki_cb.com.OSWaitEvt[rtask] & flag;
/* Clear only those bits which user wants... */
gki_cb.com.OSWaitEvt[rtask] &= ~flag;
/* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */
pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
GKI_TRACE(
"GKI_wait %d %x %d %x done"
, (
int
)rtask, (
int
)flag, (
int
)timeout, (
int
)evt);
return
(evt);
}
|
首先设置OSWaitForEvt,如果设置成0xFFFF就表示所有的事件都要关注,然后锁上thread_evt_mutex,看来这个锁是用来锁OSWaitEvt的,这个是收到的待处理的事件。如果没有事件待处理则清空OSWaitForEvt然后返回。如果有事件,如果需要超时等待,则调用pthread_cond_timedwait,否则调用pthread_cond_wait,则task会阻塞等信号。BTIF TASK和BTU TASK都是不用超时等待的。当有别的线程发event过来时会唤醒当前task,然后从OSWaitEvt中取出要处理的event。
接下来看GKI_send_msg,这和发送event有所区别,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
{
BUFFER_HDR_T *p_hdr;
tGKI_COM_CB *p_cb = &gki_cb.com;
p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
GKI_disable();
if
(p_cb->OSTaskQFirst[task_id][mbox])
p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
else
p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
p_hdr->p_next = NULL;
p_hdr->status = BUF_STATUS_QUEUED;
p_hdr->task_id = task_id;
GKI_enable();
GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
return
;
}
|
这里每个task都有若干个mailbox,每个mailbox下都有一个buffer队列,这里其实就是发送一个buffer挂载到对应task的对应box下的buffer队列上。然后发送一个事件通知该task有新的message了。
再来看task是如何读取这些message的,在GKI_read_mbox中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
{
UINT8 task_id = GKI_get_taskid();
void
*p_buf = NULL;
BUFFER_HDR_T *p_hdr;
GKI_disable();
if
(gki_cb.com.OSTaskQFirst[task_id][mbox])
{
p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
p_hdr->p_next = NULL;
p_hdr->status = BUF_STATUS_UNLINKED;
p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
}
GKI_enable();
return
(p_buf);
}
|
值得注意的是每次发送或者读message都要对GKI全局mutex上锁,完毕后还要释放锁。这里读mbox其实就是从mbox的buffer队列里取下队列头返回。