1. Overview
Gki to library libbt-brcm_gki.so (static Lib ?) To bluedroid.
This layer is an adaptation layer that adapts to OS-related processes and memory-related management and can be used to transmit messages between threads.
The gki_cb variable is used to centrally manage processes.
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. Main Functions of thread 2.1
-Gki_init () initialization variable gki_cb
-Gki_create_task () Creation thread
-Gki_destroy_task () destroy thread
-The gki_run () time-related execution function is unknown.
2.2 features
Use the pthread library to implement thread-related functions
Gki manages three threads
#define BTU_TASK 0#define BTIF_TASK 1#define A2DP_MEDIA_TASK 2
3. Main Functions of event 3.1
-Gki_wait (): Wait for the event to occur.
-Gki_send_event () sends an event to the specified process
-Gki_send_msg () sends the buffer to the specified process
-Gki_read_mbox () reads the buffer from mailbox
3.2 features
Tgki_cb. OS .thread_evt_mutex [] the event mutex tgki_cb. OS .thread_evt_cond [] the event's condition variable token [] indicates the event token of the current process [] [] pointing to the first event token in the mailbox of the Process [] point to the last event in the mailbox of the process
First, we need to understand the use of POSIX mutex lock and conditional variables.
Tip: It is worth mentioning that the pthread_cond_wait () function is called to unlock the mutex lock in the parameter until it is awakened and then re-locks the mutex lock.
How gki events work
Use gki_send_event ()/gki_send_msg () to send events/mbox events. The receiving thread can detect events through gki_wait () and process different events differently.
For mbox events, gki_read_mbox () needs to be recycled to obtain the mbox buffer.
Tip: events can be sent to other threads or to the local thread.
Each thread has four mailboxes.
There are 16 events (EVT: 0 ~ 15)
-Four reserved events are used to receive the mailbox message EVT: 0 ~ 3
-Four retention events are used to time out EVT: 4 ~ 7
-A total of 8 General events are used by the app EVT: 8 ~ 15
It can be obtained by event_mask (EVT) in sequence.