标签:
GKI以库libbt-brcm_gki.so(Static Lib?)的形式提供给BlueDroid使用
该层是一个适配层,适配了OS相关的进程、内存相关的管理,还可以用于线程间传递消息
主要通过变量gki_cb实现对进程的统一管理
<span style="font-family: 'Courier New';">typedef <span class="kwrd">struct</span> { 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]; <span class="kwrd">int</span> no_timer_suspend; <span class="rem">/* 1: no suspend, 0 stop calling GKI_timer_update() */</span> pthread_mutex_t gki_timer_mutex; pthread_cond_t gki_timer_cond; <span class="preproc">#if</span> (GKI_DEBUG == TRUE) pthread_mutex_t GKI_trace_mutex; <span class="preproc">#endif</span> } tGKI_OS; typedef <span class="kwrd">struct</span> { ... UINT8 *OSStack[GKI_MAX_TASKS]; <span class="rem">/* pointer to beginning of stack */</span> UINT16 OSStackSize[GKI_MAX_TASKS]; <span class="rem">/* stack size available to each task */</span> INT8 *OSTName[GKI_MAX_TASKS]; <span class="rem">/* name of the task */</span> UINT8 OSRdyTbl[GKI_MAX_TASKS]; <span class="rem">/* current state of the task */</span> UINT16 OSWaitEvt[GKI_MAX_TASKS]; <span class="rem">/* events that have to be processed by the task */</span> UINT16 OSWaitForEvt[GKI_MAX_TASKS]; <span class="rem">/* events the task is waiting for*/</span> UINT32 OSTicks; <span class="rem">/* system ticks from start */</span> UINT32 OSIdleCnt; <span class="rem">/* idle counter */</span> INT16 OSDisableNesting; <span class="rem">/* counter to keep track of interrupt disable nesting */</span> INT16 OSLockNesting; <span class="rem">/* counter to keep track of sched lock nesting */</span> INT16 OSIntNesting; <span class="rem">/* counter to keep track of interrupt nesting */</span> <span class="rem">/* Timer related variables</span> <span class="rem"> */</span> INT32 OSTicksTilExp; <span class="rem">/* Number of ticks till next timer expires */</span> <span class="preproc">#if</span> (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0)) UINT32 OSTicksTilStop; <span class="rem">/* inactivity delay timer; OS Ticks till stopping system tick */</span> <span class="preproc">#endif</span> INT32 OSNumOrigTicks; <span class="rem">/* Number of ticks between last timer expiration to the next one */</span> INT32 OSWaitTmr [GKI_MAX_TASKS]; <span class="rem">/* ticks the task has to wait, for specific events */</span> ... <span class="rem">/* Buffer related variables</span> <span class="rem"> */</span> BUFFER_HDR_T *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; <span class="rem">/* array of pointers to the first event in the task mailbox */</span> BUFFER_HDR_T *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; <span class="rem">/* array of pointers to the last event in the task mailbox */</span> <span class="rem">/* Define the buffer pool management variables</span> <span class="rem"> */</span> 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]; <span class="rem">/* Define the buffer pool start addresses</span> <span class="rem"> */</span> UINT8 *pool_start[GKI_NUM_TOTAL_BUF_POOLS]; <span class="rem">/* array of pointers to the start of each buffer pool */</span> UINT8 *pool_end[GKI_NUM_TOTAL_BUF_POOLS]; <span class="rem">/* array of pointers to the end of each buffer pool */</span> UINT16 pool_size[GKI_NUM_TOTAL_BUF_POOLS]; <span class="rem">/* actual size of the buffers in a pool */</span> <span class="rem">/* Define the buffer pool access control variables */</span> <span class="kwrd">void</span> *p_user_mempool; <span class="rem">/* User O/S memory pool */</span> UINT16 pool_access_mask; <span class="rem">/* Bits are set if the corresponding buffer pool is a restricted pool */</span> UINT8 pool_list[GKI_NUM_TOTAL_BUF_POOLS]; <span class="rem">/* buffer pools arranged in the order of size */</span> UINT8 curr_total_no_of_pools; <span class="rem">/* number of fixed buf pools + current number of dynamic pools */</span> BOOLEAN timer_nesting; <span class="rem">/* flag to prevent timer interrupt nesting */</span> <span class="rem">/* Time queue arrays */</span> TIMER_LIST_Q *timer_queues[GKI_MAX_TIMER_QUEUES]; <span class="rem">/* System tick callback */</span> SYSTEM_TICK_CBACK *p_tick_cb; BOOLEAN system_tick_running; <span class="rem">/* TRUE if system tick is running. Valid only if p_tick_cb is not NULL */</span> <span class="preproc">#if</span> (GKI_DEBUG == TRUE) UINT16 ExceptionCnt; <span class="rem">/* number of GKI exceptions that have happened */</span> EXCEPTION_T Exception[GKI_MAX_EXCEPTION]; <span class="preproc">#endif</span> } tGKI_COM_CB; typedef <span class="kwrd">struct</span> { tGKI_OS os; tGKI_COM_CB com; } tGKI_CB; tGKI_CB gki_cb</span>
- GKI_init() 初始化变量gki_cb
- GKI_create_task() 创建线程
- GKI_destroy_task() 销毁线程
- GKI_run() 时间相关执行函数,目前不知道有何效果
使用pthread库实现线程相关功能
GKI管理三个线程
<span class="preproc">#define</span> BTU_TASK 0 <span class="preproc">#define</span> BTIF_TASK 1 <span class="preproc">#define</span> A2DP_MEDIA_TASK 2
- GKI_wait() 等待事件的发生
- GKI_send_event()向指定进程发送事件
- GKI_send_msg() 向指定进程发送buffer
- GKI_read_mbox() 从mailbox中读取buffer
<span style="font-family: 'Courier New';">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中最后一个事件</span>
首先我们要了解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)得到
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/luopingfeng/article/details/47750155