1. 概述
GKI以庫libbt-brcm_gki.so(Static Lib?)的形式提供給BlueDroid使用
該層是一個適配層,適配了OS相關的進程、內存相關的管理,還可以用於線程間傳遞消息
主要通過變量gki_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];
int no_timer_suspend; /* 1: no suspend, 0 stop calling GKI_timer_update() */
pthread_mutex_t gki_timer_mutex;
pthread_cond_t gki_timer_cond;
#if (GKI_DEBUG == TRUE)
pthread_mutex_t GKI_trace_mutex;
#endif
} 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 */
#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
UINT32 OSTicksTilStop; /* inactivity delay timer; OS Ticks till stopping system tick */
#endif
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 */
/* Time queue arrays */
TIMER_LIST_Q *timer_queues[GKI_MAX_TIMER_QUEUES];
/* System tick callback */
SYSTEM_TICK_CBACK *p_tick_cb;
BOOLEAN system_tick_running; /* TRUE if system tick is running. Valid only if p_tick_cb is not NULL */
#if (GKI_DEBUG == TRUE)
UINT16 ExceptionCnt; /* number of GKI exceptions that have happened */
EXCEPTION_T Exception[GKI_MAX_EXCEPTION];
#endif
} tGKI_COM_CB;
typedef struct
{
tGKI_OS os;
tGKI_COM_CB com;
} tGKI_CB;
tGKI_CB gki_cb
2. 線程
2.1 主要函數
- GKI_init() 初始化變量gki_cb
- GKI_create_task() 創建線程
- GKI_destroy_task() 銷燬線程
- GKI_run() 時間相關執行函數,目前不知道有何效果
2.2 功能
使用pthread庫實現線程相關功能
GKI管理三個線程
#define BTU_TASK 0
#define BTIF_TASK 1
#define A2DP_MEDIA_TASK 2
3. 事件
3.1 主要函數
- GKI_wait() 等待事件的發生
- GKI_send_event()向指定進程發送事件
- GKI_send_msg() 向指定進程發送buffer
- GKI_read_mbox() 從mailbox中讀取buffer
3.2 功能
tGKI_CB.os.thread_evt_mutex[] 事件的互斥鎖
tGKI_CB.os.thread_evt_cond[] 事件的條件變量
tGKI_CB.com.OSWaitEvt[] 表示當前進程的事件
tGKI_CB.com.OSTaskQFirst[][] 指向進程的mailbox中第一個事件
tGKI_CB.com.OSTaskQLast[][] 指向進程的mailbox中最後一個事件
首先我們要了解Posix互斥鎖和條件變量的使用
tip: 值得一提的是pthread_cond_wait()函數在調用後解鎖參數中的互斥鎖,直至被喚醒後重新對該互斥鎖加鎖
GKI事件的原理
通過GKI_send_event()/GKI_send_msg()發送事件/MBox事件,接收線程通過GKI_wait()可檢測事件的發生,並對不同的事件進行不同的處理
對於MBox事件,需要再循環調用GKI_read_mbox()來得到MBOX Buffer
tip: 事件可以除了可以發往其他線程,也可以發往本線程
每個線程都有四個Mailbox
事件有16個(evt: 0~15)
- 4個保留事件用於Mailbox消息的接收 evt: 0~3
- 4個保留事件用於超時 evt: 4~7
- 8個通用事件共APP使用 evt: 8~15
可依次由EVENT_MASK(evt)得到