Android蓝牙源码分析——关于GKI

GKI模块是Bluedroid中用于线程间通信的,我们知道蓝牙所有的操作最终都会交给Bluedroid处理,而调用方可能来自多个线程,Bluedroid中有大量的全局变量,为避免多线程导致的数据不一致问题,干脆统一切换到一个固定的工作线程中执行。类似于Java中的post Runnable,这里是给线程发送消息或事件。

接下来我们开始分析GKI源码,文件并不多,我们首先以gki模块的初始化为入口,在gki_ulinux.c中,如下:

 
  1. void GKI_init(void)

  2. {

  3. pthread_mutexattr_t attr;

  4. tGKI_OS *p_os;

  5.  
  6. memset (&gki_cb, 0, sizeof (gki_cb));

  7.  
  8. gki_buffer_init();

  9. gki_timers_init();

  10. alarm_service_init();

  11.  
  12. gki_cb.com.OSTicks = (UINT32) times(0);

  13.  
  14. pthread_mutexattr_init(&attr);

  15.  
  16. p_os = &gki_cb.os;

  17. pthread_mutex_init(&p_os->GKI_mutex, &attr);

  18.  
  19. struct sigevent sigevent;

  20. memset(&sigevent, 0, sizeof(sigevent));

  21. sigevent.sigev_notify = SIGEV_THREAD;

  22. sigevent.sigev_notify_function = (void (*)(union sigval))bt_alarm_cb;

  23. sigevent.sigev_value.sival_ptr = NULL;

  24. if (timer_create(CLOCK_REALTIME, &sigevent, &posix_timer) == -1) {

  25. timer_created = false;

  26. } else {

  27. timer_created = true;

  28. }

  29. }

首先将gki_cb清零,这个变量非常重要,如下:

 
  1. tGKI_CB gki_cb;

  2.  
  3. typedef struct

  4. {

  5. tGKI_OS os;

  6. tGKI_COM_CB com;

  7. } tGKI_CB;

  8.  
  9. typedef struct

  10. {

  11. pthread_mutex_t GKI_mutex;

  12. pthread_t thread_id[GKI_MAX_TASKS];

  13. pthread_mutex_t thread_evt_mutex[GKI_MAX_TASKS];

  14. pthread_cond_t thread_evt_cond[GKI_MAX_TASKS];

  15. pthread_mutex_t thread_timeout_mutex[GKI_MAX_TASKS];

  16. pthread_cond_t thread_timeout_cond[GKI_MAX_TASKS];

  17. } tGKI_OS;

  18.  
  19. typedef struct {

  20. UINT8 *OSStack[GKI_MAX_TASKS]; /* pointer to beginning of stack */

  21. UINT16 OSStackSize[GKI_MAX_TASKS]; /* stack size available to each task */

  22.  
  23.  
  24. INT8 *OSTName[GKI_MAX_TASKS]; /* name of the task */

  25.  
  26. UINT8 OSRdyTbl[GKI_MAX_TASKS]; /* current state of the task */

  27. UINT16 OSWaitEvt[GKI_MAX_TASKS]; /* events that have to be processed by the task */

  28. UINT16 OSWaitForEvt[GKI_MAX_TASKS]; /* events the task is waiting for*/

  29.  
  30. UINT32 OSTicks; /* system ticks from start */

  31. UINT32 OSIdleCnt; /* idle counter */

  32. INT16 OSDisableNesting; /* counter to keep track of interrupt disable nesting */

  33. INT16 OSLockNesting; /* counter to keep track of sched lock nesting */

  34. INT16 OSIntNesting; /* counter to keep track of interrupt nesting */

  35.  
  36. /* Timer related variables

  37. */

  38. INT32 OSTicksTilExp; /* Number of ticks till next timer expires */

  39. INT32 OSNumOrigTicks; /* Number of ticks between last timer expiration to the next one */

  40.  
  41. INT32 OSWaitTmr [GKI_MAX_TASKS]; /* ticks the task has to wait, for specific events */

  42.  
  43. /* Buffer related variables

  44. */

  45. BUFFER_HDR_T *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */

  46. BUFFER_HDR_T *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */

  47.  
  48. /* Define the buffer pool management variables

  49. */

  50. FREE_QUEUE_T freeq[GKI_NUM_TOTAL_BUF_POOLS];

  51.  
  52. UINT16 pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];

  53. UINT16 pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];

  54. UINT16 pool_additions[GKI_NUM_TOTAL_BUF_POOLS];

  55.  
  56. /* Define the buffer pool start addresses

  57. */

  58. UINT8 *pool_start[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the start of each buffer pool */

  59. UINT8 *pool_end[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the end of each buffer pool */

  60. UINT16 pool_size[GKI_NUM_TOTAL_BUF_POOLS]; /* actual size of the buffers in a pool */

  61.  
  62. /* Define the buffer pool access control variables */

  63. void *p_user_mempool; /* User O/S memory pool */

  64. UINT16 pool_access_mask; /* Bits are set if the corresponding buffer pool is a restricted pool */

  65. UINT8 pool_list[GKI_NUM_TOTAL_BUF_POOLS]; /* buffer pools arranged in the order of size */

  66. UINT8 curr_total_no_of_pools; /* number of fixed buf pools + current number of dynamic pools */

  67.  
  68. BOOLEAN timer_nesting; /* flag to prevent timer interrupt nesting */

  69. } 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. void gki_buffer_init(void)

  2. {

  3. UINT8 i, tt, mb;

  4. tGKI_COM_CB *p_cb = &gki_cb.com;

  5.  
  6. /* Initialize mailboxes */

  7. for (tt = 0; tt < GKI_MAX_TASKS; tt++)

  8. {

  9. for (mb = 0; mb < NUM_TASK_MBOX; mb++)

  10. {

  11. p_cb->OSTaskQFirst[tt][mb] = NULL;

  12. p_cb->OSTaskQLast [tt][mb] = NULL;

  13. }

  14. }

  15.  
  16. for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)

  17. {

  18. p_cb->pool_start[tt] = NULL;

  19. p_cb->pool_end[tt] = NULL;

  20. p_cb->pool_size[tt] = 0;

  21.  
  22. p_cb->freeq[tt].p_first = 0;

  23. p_cb->freeq[tt].p_last = 0;

  24. p_cb->freeq[tt].size = 0;

  25. p_cb->freeq[tt].total = 0;

  26. p_cb->freeq[tt].cur_cnt = 0;

  27. p_cb->freeq[tt].max_cnt = 0;

  28. }

  29.  
  30. /* Use default from target.h */

  31. p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;

  32.  
  33. /* add pools to the pool_list which is arranged in the order of size */

  34. for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)

  35. {

  36. p_cb->pool_list[i] = i;

  37. }

  38.  
  39. p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;

  40.  
  41. return;

  42. }

GKI缓冲区相关的控制数据结构都在tGKI_COM_CB中,如下:

 
  1. /* Buffer related variables */

  2. BUFFER_HDR_T *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */

  3. BUFFER_HDR_T *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */

  4.  
  5. typedef struct _buffer_hdr

  6. {

  7. struct _buffer_hdr *p_next; /* next buffer in the queue */

  8. UINT8 q_id; /* id of the queue */

  9. UINT8 task_id; /* task which allocated the buffer*/

  10. UINT8 status; /* FREE, UNLINKED or QUEUED */

  11. UINT8 Type;

  12. } BUFFER_HDR_T;

这里OSTaskQFirst和OSTaskQLast是个BUFFER_HDR_T的二维数组,看上去每个TASK有一个TASK_MBOX数组:

 
  1. #define GKI_MAX_TASKS 3

  2.  
  3. /************************************************************************

  4. ** Mailbox definitions. Each task has 4 mailboxes that are used to

  5. ** send buffers to the task.

  6. */

  7. #define TASK_MBOX_0 0

  8. #define TASK_MBOX_1 1

  9. #define TASK_MBOX_2 2

  10. #define TASK_MBOX_3 3

  11.  
  12. #define NUM_TASK_MBOX 4

  13.  
  14. #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. void gki_timers_init(void)

  2. {

  3. UINT8 tt;

  4.  
  5. gki_cb.com.OSTicksTilExp = 0; /* Remaining time (of OSTimeCurTimeout) before next timer expires */

  6. gki_cb.com.OSNumOrigTicks = 0;

  7.  
  8. for (tt = 0; tt < GKI_MAX_TASKS; tt++)

  9. {

  10. gki_cb.com.OSWaitTmr [tt] = 0;

  11. }

  12.  
  13. return;

  14. }

timers相比buffer就简单多了,只有三个变量相关,如下:

 
  1. /* Timer related variables */

  2. INT32 OSTicksTilExp; /* Number of ticks till next timer expires */

  3. INT32 OSNumOrigTicks; /* Number of ticks between last timer expiration to the next one */

  4.  
  5. INT32 OSWaitTmr [GKI_MAX_TASKS]; /* ticks the task has to wait, for specific events */

这里的初始化就是给他们都设为0而已。

再来看看alarm_service_init,如下:

 
  1. static void alarm_service_init() {

  2. alarm_service.ticks_scheduled = 0;

  3. alarm_service.timer_started_us = 0;

  4. alarm_service.timer_last_expired_us = 0;

  5. alarm_service.wakelock = FALSE;

  6. raise_priority_a2dp(TASK_JAVA_ALARM);

  7. }

  8.  
  9. // Alarm service structure used to pass up via JNI to the bluetooth

  10. // app in order to create a wakeable Alarm.

  11. typedef struct

  12. {

  13. UINT32 ticks_scheduled;

  14. UINT64 timer_started_us;

  15. UINT64 timer_last_expired_us;

  16. bool wakelock;

  17. } alarm_service_t;

到这里gki初始化完成了,GKI_init是被谁调用的呢?是被bte_main.c中的bte_main_boot_entry调用的,如下:

 
  1. /******************************************************************************

  2. **

  3. ** Function bte_main_boot_entry

  4. **

  5. ** Description BTE MAIN API - Entry point for BTE chip/stack initialization

  6. **

  7. ** Returns None

  8. **

  9. ******************************************************************************/

  10. void bte_main_boot_entry(void)

  11. {

  12. /* initialize OS */

  13. GKI_init();

  14.  
  15. bte_main_in_hw_init();

  16.  
  17. bte_load_conf(BTE_STACK_CONF_FILE);

  18. bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE);

  19.  
  20. pthread_mutex_init(&cleanup_lock, NULL);

  21. }

bte_main_boot_entry又是被谁调用的呢?在btif_core.c的btif_init_bluetooth中,如下:

 
  1. bt_status_t btif_init_bluetooth() {

  2. UINT8 status;

  3. btif_config_init();

  4. bte_main_boot_entry();

  5.  
  6. /* As part of the init, fetch the local BD ADDR */

  7. memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t));

  8. btif_fetch_local_bdaddr(&btif_local_bd_addr);

  9.  
  10. /* start btif task */

  11. status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,

  12. (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),

  13. sizeof(btif_task_stack));

  14.  
  15. if (status != GKI_SUCCESS)

  16. return BT_STATUS_FAIL;

  17.  
  18. return BT_STATUS_SUCCESS;

  19. }

而btif_init_bluetooth又是被bluetooth.c中init函数调用的,而这个Init又是被谁调用的呢?在Bluetooth.c中如下:

 
  1. static const bt_interface_t bluetoothInterface = {

  2. sizeof(bluetoothInterface),

  3. init,

  4. enable,

  5. disable,

  6. cleanup,

  7. get_adapter_properties,

  8. get_adapter_property,

  9. set_adapter_property,

  10. get_remote_device_properties,

  11. get_remote_device_property,

  12. set_remote_device_property,

  13. get_remote_service_record,

  14. get_remote_services,

  15. start_discovery,

  16. cancel_discovery,

  17. create_bond,

  18. remove_bond,

  19. cancel_bond,

  20. get_connection_state,

  21. pin_reply,

  22. ssp_reply,

  23. get_profile_interface,

  24. dut_mode_configure,

  25. dut_mode_send,

  26. #if BLE_INCLUDED == TRUE

  27. le_test_mode,

  28. #else

  29. NULL,

  30. #endif

  31. config_hci_snoop_log,

  32. set_os_callouts,

  33. read_energy_info,

  34. };

  35.  
  36. const bt_interface_t* bluetooth__get_bluetooth_interface ()

  37. {

  38. /* fixme -- add property to disable bt interface ? */

  39.  
  40. return &bluetoothInterface;

  41. }

  42.  
  43. static int open_bluetooth_stack (const struct hw_module_t* module, char const* name,

  44. struct hw_device_t** abstraction)

  45. {

  46. UNUSED(name);

  47.  
  48. bluetooth_device_t *stack = malloc(sizeof(bluetooth_device_t) );

  49. memset(stack, 0, sizeof(bluetooth_device_t) );

  50. stack->common.tag = HARDWARE_DEVICE_TAG;

  51. stack->common.version = 0;

  52. stack->common.module = (struct hw_module_t*)module;

  53. stack->common.close = close_bluetooth_stack;

  54. stack->get_bluetooth_interface = bluetooth__get_bluetooth_interface;

  55. *abstraction = (struct hw_device_t*)stack;

  56. return 0;

  57. }

  58.  
  59.  
  60. static struct hw_module_methods_t bt_stack_module_methods = {

  61. .open = open_bluetooth_stack,

  62. };

  63.  
  64. struct hw_module_t HAL_MODULE_INFO_SYM = {

  65. .tag = HARDWARE_MODULE_TAG,

  66. .version_major = 1,

  67. .version_minor = 0,

  68. .id = BT_HARDWARE_MODULE_ID,

  69. .name = "Bluetooth Stack",

  70. .author = "The Android Open Source Project",

  71. .methods = &bt_stack_module_methods

  72. };

在com_android_bluetooth_btservice_AdapterService.cpp中初始化时有如下代码:

 
  1. const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);

  2. err = hw_get_module(id, (hw_module_t const**) &module);

  3. if (err == 0) {

  4. hw_device_t* abstraction;

  5. err = module->methods->open(module, id, &abstraction);

  6. if (err == 0) {

  7. bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;

  8. sBluetoothInterface = btStack->get_bluetooth_interface();

  9. } else {

  10. ALOGE("Error while opening Bluetooth library");

  11. }

  12. }

这个sBluetoothInterface就是Bluetooth.c中的&bluetoothInterface,这里面有很多函数指针,当调用init时最终就会走到GKI_init。什么时候调用的呢?在initNative中,如下:

 
  1. static bool initNative(JNIEnv* env, jobject obj) {

  2. sJniAdapterServiceObj = env->NewGlobalRef(obj);

  3. sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));

  4.  
  5. if (sBluetoothInterface) {

  6. int ret = sBluetoothInterface->init(&sBluetoothCallbacks);

  7. if (ret != BT_STATUS_SUCCESS) {

  8. ALOGE("Error while setting the callbacks: %d\n", ret);

  9. sBluetoothInterface = NULL;

  10. return JNI_FALSE;

  11. }

  12. ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);

  13. if (ret != BT_STATUS_SUCCESS) {

  14. ALOGE("Error while setting Bluetooth callouts: %d\n", ret);

  15. sBluetoothInterface->cleanup();

  16. sBluetoothInterface = NULL;

  17. return JNI_FALSE;

  18. }

  19.  
  20. if ( (sBluetoothSocketInterface = (btsock_interface_t *)

  21. sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {

  22. ALOGE("Error getting socket interface");

  23. }

  24.  
  25. return JNI_TRUE;

  26. }

  27. return JNI_FALSE;

  28. }

而这个InitNative是AdapterService.java中的native函数,如下:

private native boolean initNative();
  •  

该函数调用是在AdapterService的onCreate时,如下:

 
  1. @Override

  2. public void onCreate() {

  3. super.onCreate();

  4. debugLog("onCreate()");

  5. mBinder = new AdapterServiceBinder(this);

  6. mAdapterProperties = new AdapterProperties(this);

  7. mAdapterStateMachine = AdapterState.make(this, mAdapterProperties);

  8. mJniCallbacks = new JniCallbacks(mAdapterStateMachine, mAdapterProperties);

  9. initNative();

  10. mNativeAvailable=true;

  11. mCallbacks = new RemoteCallbackList<IBluetoothCallback>();

  12. //Load the name and address

  13. getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);

  14. getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);

  15. mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

  16. mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);

  17.  
  18. mSdpManager = SdpManager.init(this);

  19. registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP));

  20. mProfileObserver = new ProfileObserver(getApplicationContext(), this, new Handler());

  21. mProfileObserver.start();

  22. }

好了,GKI初始化的整个调用路径都搞清楚了,接下来看GKI_create_task是如何创建任务的,如下:

 
  1. UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize)

  2. {

  3. struct sched_param param;

  4. int policy, ret = 0;

  5. pthread_attr_t attr1;

  6.  
  7. gki_cb.com.OSRdyTbl[task_id] = TASK_READY;

  8. gki_cb.com.OSTName[task_id] = taskname;

  9. gki_cb.com.OSWaitTmr[task_id] = 0;

  10. gki_cb.com.OSWaitEvt[task_id] = 0;

  11.  
  12. /* Initialize mutex and condition variable objects for events and timeouts */

  13. pthread_condattr_t cond_attr;

  14. pthread_condattr_init(&cond_attr);

  15. pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);

  16.  
  17. pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);

  18. pthread_cond_init (&gki_cb.os.thread_evt_cond[task_id], &cond_attr);

  19. pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);

  20. pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], NULL);

  21.  
  22. /* On Android, the new tasks starts running before 'gki_cb.os.thread_id[task_id]' is initialized */

  23. /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id] for it calls GKI_wait */

  24. gki_pthread_info[task_id].task_id = task_id;

  25. gki_pthread_info[task_id].task_entry = task_entry;

  26. gki_pthread_info[task_id].params = 0;

  27.  
  28. ret = pthread_create( &gki_cb.os.thread_id[task_id],

  29. &attr1,

  30. (void *)gki_task_entry,

  31. &gki_pthread_info[task_id]);

  32.  
  33. return (GKI_SUCCESS);

  34. }

这里会创建一个线程执行gki_task_entry,我们看看这个线程入口函数,如下:

 
  1. static void gki_task_entry(UINT32 params)

  2. {

  3. gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;

  4. gki_cb.os.thread_id[p_pthread_info->task_id] = pthread_self();

  5.  
  6. prctl(PR_SET_NAME, (unsigned long)gki_cb.com.OSTName[p_pthread_info->task_id], 0, 0, 0);

  7.  
  8. /* Call the actual thread entry point */

  9. (p_pthread_info->task_entry)(p_pthread_info->params);

  10.  
  11. pthread_exit(0); /* GKI tasks have no return value */

  12. }

这里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. /* start btif task */

  2. status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,

  3. (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),

  4. sizeof(btif_task_stack));

第一个参数是任务的入口函数,第二个是taskid,第三个是task名称,如下:

 
  1. #define BTIF_TASK_STR ((INT8 *) "BTIF")

  2. #define BTU_TASK 0

  3. #define BTIF_TASK 1

  4. #define A2DP_MEDIA_TASK 2

看来这个btif task是个蓝牙核心线程,如下:

 
  1. static void btif_task(UINT32 params)

  2. {

  3. UINT16 event;

  4. BT_HDR *p_msg;

  5.  
  6. btif_associate_evt();

  7.  
  8. for(;;)

  9. {

  10. /* wait for specified events */

  11. event = GKI_wait(0xFFFF, 0);

  12.  
  13. /*

  14. * Wait for the trigger to init chip and stack. This trigger will

  15. * be received by btu_task once the UART is opened and ready

  16. */

  17. if (event == BT_EVT_TRIGGER_STACK_INIT)

  18. {

  19. #if (BLE_INCLUDED == TRUE)

  20. btif_dm_load_ble_local_keys();

  21. #endif

  22. BTA_EnableBluetooth(bte_dm_evt);

  23. }

  24.  
  25. /*

  26. * Failed to initialize controller hardware, reset state and bring

  27. * down all threads

  28. */

  29. if (event == BT_EVT_HARDWARE_INIT_FAIL)

  30. {

  31. bte_main_disable();

  32. btif_queue_release();

  33. GKI_task_self_cleanup(BTIF_TASK);

  34. bte_main_shutdown();

  35. btif_dut_mode = 0;

  36. btif_core_state = BTIF_CORE_STATE_DISABLED;

  37. HAL_CBACK(bt_hal_cbacks,adapter_state_changed_cb,BT_STATE_OFF);

  38. break;

  39. }

  40.  
  41. if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))

  42. break;

  43.  
  44. if(event & TASK_MBOX_1_EVT_MASK)

  45. {

  46. while((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL)

  47. {

  48. switch (p_msg->event)

  49. {

  50. case BT_EVT_CONTEXT_SWITCH_EVT:

  51. btif_context_switched(p_msg);

  52. break;

  53. default:

  54. BTIF_TRACE_ERROR("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK);

  55. break;

  56. }

  57.  
  58. GKI_freebuf(p_msg);

  59. }

  60. }

  61. }

  62.  
  63. btif_disassociate_evt();

  64. }

这里在一个无限for循环中用GKI_wait等待事件,当遇到某些事件时break。接下来看看bte_main.c中的bte_main_enable,如下:

 
  1. void bte_main_enable()

  2. {

  3. /* Initialize BTE control block */

  4. BTE_Init();

  5.  
  6. lpm_enabled = FALSE;

  7.  
  8. GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,

  9. (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),

  10. sizeof(bte_btu_stack));

  11.  
  12. bte_hci_enable();

  13.  
  14. GKI_run();

  15. }

原来BTU_TASK是在这里初始化的,看下入口函数btu_task,如下:

 
  1. /*******************************************************************************

  2. **

  3. ** Function btu_task

  4. **

  5. ** Description This is the main task of the Bluetooth Upper Layers unit.

  6. ** It sits in a loop waiting for messages, and dispatches them

  7. ** to the appropiate handlers.

  8. **

  9. ** Returns should never return

  10. **

  11. *******************************************************************************/

  12. BTU_API UINT32 btu_task (UINT32 param)

  13. {

  14. UINT16 event;

  15. BT_HDR *p_msg;

  16. UINT8 i;

  17. UINT16 mask;

  18. BOOLEAN handled;

  19.  
  20. /* Initialize the mandatory core stack control blocks

  21. (BTU, BTM, L2CAP, and SDP)

  22. */

  23. btu_init_core();

  24.  
  25. /* Initialize any optional stack components */

  26. BTE_InitStack();

  27.  
  28. bta_sys_init();

  29.  
  30. /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */

  31. GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);

  32.  
  33. prctl(PR_SET_NAME, (unsigned long)"BTU TASK", 0, 0, 0);

  34.  
  35. raise_priority_a2dp(TASK_HIGH_BTU);

  36.  
  37. /* Wait for, and process, events */

  38. for (;;)

  39. {

  40. event = GKI_wait (0xFFFF, 0);

  41.  
  42. if (event & TASK_MBOX_0_EVT_MASK)

  43. {

  44. /* Process all messages in the queue */

  45. while ((p_msg = (BT_HDR *) GKI_read_mbox (BTU_HCI_RCV_MBOX)) != NULL)

  46. {

  47. /* Determine the input message type. */

  48. switch (p_msg->event & BT_EVT_MASK)

  49. {

  50. }

  51. }

  52. }

  53.  
  54. }

  55.  
  56. return(0);

  57. }

这里省略了不少代码,可以看到BTU_TASK远比BTIF_TASK复杂,不过结构都一样,也是在一个loop里不停地GKI_wait获取event,然后处理event。从注释上看BTU是Bluetooth Upper Layers unit的意思。这里我们暂时不去看各种event的处理,只是了解整个底层GKI的架构。

我们注意到这里在进入loop之前做了一些初始化,先看btu_init_core,如下:

 
  1. void btu_init_core(void)

  2. {

  3. /* Initialize the mandatory core stack components */

  4. btm_init();

  5.  
  6. l2c_init();

  7.  
  8. sdp_init();

  9.  
  10. #if BLE_INCLUDED == TRUE

  11. gatt_init();

  12. #if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)

  13. SMP_Init();

  14. #endif

  15. btm_ble_init();

  16. #endif

  17. }

再往下看会调GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);向BTIF_TASK发送BT_EVT_TRIGGER_STACK_INIT这个event。我们来看GKI是如何发送消息的,如下:

 
  1. /*******************************************************************************

  2. **

  3. ** Function GKI_send_event

  4. **

  5. ** Description This function is called by tasks to send events to other

  6. ** tasks. Tasks can also send events to themselves.

  7. **

  8. ** Parameters: task_id - (input) The id of the task to which the event has to

  9. ** be sent

  10. ** event - (input) The event that has to be sent

  11. **

  12. **

  13. ** Returns GKI_SUCCESS if all OK, else GKI_FAILURE

  14. **

  15. *******************************************************************************/

  16.  
  17. UINT8 GKI_send_event (UINT8 task_id, UINT16 event)

  18. {

  19. if (task_id < GKI_MAX_TASKS)

  20. {

  21. /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */

  22. pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);

  23.  
  24. /* Set the event bit */

  25. gki_cb.com.OSWaitEvt[task_id] |= event;

  26.  
  27. pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);

  28.  
  29. pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);

  30.  
  31. return ( GKI_SUCCESS );

  32. }

  33. return (GKI_FAILURE);

  34. }

这里先给目标task的event锁锁上,然后或上该task等待的event,通知该task线程有新的event了,然后解锁返回。我们再看看GKI_wait是如何等待event的:

 
  1. /*******************************************************************************

  2. **

  3. ** Function GKI_wait

  4. **

  5. ** Description This function is called by tasks to wait for a specific

  6. ** event or set of events. The task may specify the duration

  7. ** that it wants to wait for, or 0 if infinite.

  8. **

  9. ** Parameters: flag - (input) the event or set of events to wait for

  10. ** timeout - (input) the duration that the task wants to wait

  11. ** for the specific events (in system ticks)

  12. **

  13. **

  14. ** Returns the event mask of received events or zero if timeout

  15. **

  16. *******************************************************************************/

  17. UINT16 GKI_wait (UINT16 flag, UINT32 timeout)

  18. {

  19. UINT16 evt;

  20. UINT8 rtask;

  21. struct timespec abstime = { 0, 0 };

  22.  
  23. int sec;

  24. int nano_sec;

  25.  
  26. rtask = GKI_get_taskid();

  27.  
  28. gki_cb.com.OSWaitForEvt[rtask] = flag;

  29.  
  30. /* protect OSWaitEvt[rtask] from modification from an other thread */

  31. pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);

  32.  
  33. if (!(gki_cb.com.OSWaitEvt[rtask] & flag))

  34. {

  35. if (timeout)

  36. {

  37. clock_gettime(CLOCK_MONOTONIC, &abstime);

  38.  
  39. /* add timeout */

  40. sec = timeout / 1000;

  41. nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;

  42. abstime.tv_nsec += nano_sec;

  43. if (abstime.tv_nsec > NSEC_PER_SEC)

  44. {

  45. abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);

  46. abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;

  47. }

  48. abstime.tv_sec += sec;

  49.  
  50. pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],

  51. &gki_cb.os.thread_evt_mutex[rtask], &abstime);

  52. }

  53. else

  54. {

  55. pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask], &gki_cb.os.thread_evt_mutex[rtask]);

  56. }

  57.  
  58. /* TODO: check, this is probably neither not needed depending on phtread_cond_wait() implmentation,

  59. e.g. it looks like it is implemented as a counter in which case multiple cond_signal

  60. should NOT be lost! */

  61.  
  62. /* we are waking up after waiting for some events, so refresh variables

  63. no need to call GKI_disable() here as we know that we will have some events as we've been waking

  64. up after condition pending or timeout */

  65.  
  66. if (gki_cb.com.OSTaskQFirst[rtask][0])

  67. gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;

  68. if (gki_cb.com.OSTaskQFirst[rtask][1])

  69. gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;

  70. if (gki_cb.com.OSTaskQFirst[rtask][2])

  71. gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;

  72. if (gki_cb.com.OSTaskQFirst[rtask][3])

  73. gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;

  74.  
  75. if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)

  76. {

  77. gki_cb.com.OSWaitEvt[rtask] = 0;

  78. /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond is met */

  79. pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);

  80. return (EVENT_MASK(GKI_SHUTDOWN_EVT));

  81. }

  82. }

  83.  
  84. /* Clear the wait for event mask */

  85. gki_cb.com.OSWaitForEvt[rtask] = 0;

  86.  
  87. /* Return only those bits which user wants... */

  88. evt = gki_cb.com.OSWaitEvt[rtask] & flag;

  89.  
  90. /* Clear only those bits which user wants... */

  91. gki_cb.com.OSWaitEvt[rtask] &= ~flag;

  92.  
  93. /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */

  94. pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);

  95.  
  96. GKI_TRACE("GKI_wait %d %x %d %x done", (int)rtask, (int)flag, (int)timeout, (int)evt);

  97. return (evt);

  98. }

首先设置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. void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)

  2. {

  3. BUFFER_HDR_T *p_hdr;

  4. tGKI_COM_CB *p_cb = &gki_cb.com;

  5.  
  6. p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);

  7.  
  8. GKI_disable();

  9.  
  10. if (p_cb->OSTaskQFirst[task_id][mbox])

  11. p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;

  12. else

  13. p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;

  14.  
  15. p_cb->OSTaskQLast[task_id][mbox] = p_hdr;

  16.  
  17. p_hdr->p_next = NULL;

  18. p_hdr->status = BUF_STATUS_QUEUED;

  19. p_hdr->task_id = task_id;

  20.  
  21. GKI_enable();

  22.  
  23. GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));

  24.  
  25. return;

  26. }

这里每个task都有若干个mailbox,每个mailbox下都有一个buffer队列,这里其实就是发送一个buffer挂载到对应task的对应box下的buffer队列上。然后发送一个事件通知该task有新的message了。

再来看task是如何读取这些message的,在GKI_read_mbox中,如下:

 
  1. void *GKI_read_mbox (UINT8 mbox)

  2. {

  3. UINT8 task_id = GKI_get_taskid();

  4. void *p_buf = NULL;

  5. BUFFER_HDR_T *p_hdr;

  6.  
  7. GKI_disable();

  8.  
  9. if (gki_cb.com.OSTaskQFirst[task_id][mbox])

  10. {

  11. p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];

  12. gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;

  13.  
  14. p_hdr->p_next = NULL;

  15. p_hdr->status = BUF_STATUS_UNLINKED;

  16.  
  17. p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;

  18. }

  19.  
  20. GKI_enable();

  21.  
  22. return (p_buf);

  23. }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值