Gki分析:
Gki层是一个适配层,适配了操作系统相关的时钟,内存,线程管理。主要通过gki_cb实现对线程的统一管理。可借助GKI快速轻松得移植蓝牙协议栈到其他操作系统或手机平台上。
GKI结构体接口:
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
{
/* Task management variables
*/
/* The stack and stack size are not used on Windows
*/
// btla-specific ++
#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == FALSE))
// btla-specific --
#if (GKI_NUM_FIXED_BUF_POOLS > 0)
UINT8 bufpool0[(ALIGN_POOL(GKI_BUF0_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 1)
UINT8 bufpool1[(ALIGN_POOL(GKI_BUF1_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 2)
UINT8 bufpool2[(ALIGN_POOL(GKI_BUF2_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 3)
UINT8 bufpool3[(ALIGN_POOL(GKI_BUF3_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 4)
UINT8 bufpool4[(ALIGN_POOL(GKI_BUF4_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 5)
UINT8 bufpool5[(ALIGN_POOL(GKI_BUF5_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 6)
UINT8 bufpool6[(ALIGN_POOL(GKI_BUF6_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 7)
UINT8 bufpool7[(ALIGN_POOL(GKI_BUF7_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 8)
UINT8 bufpool8[(ALIGN_POOL(GKI_BUF8_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX];
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 9)
UINT8 bufpool9[(ALIGN_POOL(GKI_BUF9_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX];
#endif
#else
/* Definitions for dynamic buffer use */
#if (GKI_NUM_FIXED_BUF_POOLS > 0)
UINT8 *bufpool0;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 1)
UINT8 *bufpool1;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 2)
UINT8 *bufpool2;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 3)
UINT8 *bufpool3;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 4)
UINT8 *bufpool4;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 5)
UINT8 *bufpool5;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 6)
UINT8 *bufpool6;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 7)
UINT8 *bufpool7;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 8)
UINT8 *bufpool8;
#endif
#if (GKI_NUM_FIXED_BUF_POOLS > 9)
UINT8 *bufpool9;
#endif
#endif
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 */
/* Only take up space timers used in the system (GKI_NUM_TIMERS defined in target.h) */
#if (GKI_NUM_TIMERS > 0)
INT32 OSTaskTmr0 [GKI_MAX_TASKS];
INT32 OSTaskTmr0R [GKI_MAX_TASKS];
#endif
#if (GKI_NUM_TIMERS > 1)
INT32 OSTaskTmr1 [GKI_MAX_TASKS];
INT32 OSTaskTmr1R [GKI_MAX_TASKS];
#endif
#if (GKI_NUM_TIMERS > 2)
INT32 OSTaskTmr2 [GKI_MAX_TASKS];
INT32 OSTaskTmr2R [GKI_MAX_TASKS];
#endif
/* 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;
#if GKI_DYNAMIC_MEMORY == FALSE
GKI_API extern tGKI_CB gki_cb;
#else
GKI_API extern tGKI_CB *gki_cb_ptr;
#define gki_cb (*gki_cb_ptr)
#endif
GKI管理的线程:
l 线程:
BTU_TASK: 等待并分发消息给profile
BTIF_TASK: 处理来自HAL和BTA的消息
A2DP_MEDIA_TASK:
l 操作函数:
GKI_init() 初始化变量gki_cb
GKI_create_task() 创建线程
GKI_destroy_task() 销毁线程
GKI_run()
GKI_wait() 等待事件发生
GKI_send_msg() 向指定线程发送事件
GKI_send_msg() 向指定线程发送MBox事件
GKI_read_mbox() 从mailbox中读取buffer
使用pthread库操作线程,GKI_send_event() 向指定线程发送事件, 接收线程通过GKI_wait()可检测到事件的发生,并对不同的事件进行不同的处理。
GKI_send_msg() 需要再循环调用GKI_read_mbox()来得到MBox buffer。
每个线程都有四个Mailbox,事件有16个(evt: 0~15),由EVENT_MASK(evt)得到
4个MBox事件用于mailbox消息的接收 evt: 0~3
4个超时事件:evt:4~7
8个通用事件供app使用:evt:8~15