Bluedroid GKI源码分析



首先以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<ibluetoothcallback>();
     //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();
}</ibluetoothcallback>



好了,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
<code> /* Initialize the mandatory core stack control blocks
    (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 );
</code>

}


这里省略了不少代码,可以看到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
<code> void btu_init_core( void )
{
     /* 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
}</code>

 

再往下看会调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
<code> /*******************************************************************************
**
** 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);
}</code>



这里先给目标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
<code> /*******************************************************************************
**
** 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);
}</code>



首先设置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
<code> void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
{
     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 ;
}</code>



这里每个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
<code> void *GKI_read_mbox (UINT8 mbox)
{
     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);
}</code>

 

值得注意的是每次发送或者读message都要对GKI全局mutex上锁,完毕后还要释放锁。这里读mbox其实就是从mbox的buffer队列里取下队列头返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值