NFCApplication 启动分析(原创)
在上篇文章NfcService启动中有说到会DoInitialize,会调用到libnxp-nfc-nci的库中的NfcAppliaction.Initialize().
void NfcAdaptation::Initialize () { ............................ GKI_init (); GKI_enable (); GKI_create_task ((TASKPTR)NFCA_TASK, BTU_TASK, (INT8*)"NFCA_TASK", 0, 0, (pthread_cond_t*)NULL, NULL); { AutoThreadMutex guard(mCondVar); GKI_create_task ((TASKPTR)Thread, MMI_TASK, (INT8*)"NFCA_THREAD", 0, 0, (pthread_cond_t*)NULL, NULL); mCondVar.wait(); } ............................ }
继续看看 GKI_init()里做了一些什么东东:
void GKI_init(void) { pthread_mutexattr_t attr; tGKI_OS *p_os; memset (&gki_cb, 0, sizeof (gki_cb)); //主要初始化mailboxes置空 gki_buffer_init(); //定时器的初始化归零 gki_timers_init(); ...................... }
GKI_enable()没做啥事,直接跳过
最重要的是两个GKI_Create_Task。
分别运行NFCA_TASK和Thread.分别来看看:
UINT32 NfcAdaptation::NFCA_TASK (UINT32 arg) { const char* func = "NfcAdaptation::NFCA_TASK"; ALOGD ("%s: enter", func); GKI_run (0); ALOGD ("%s: exit", func); return 0; }
运行GKI_RUN(0):
void GKI_run (void *p_task_id) { ....................................................................... GKI_TRACE_2("GKI_run, run_cond(%x)=%d ", p_run_cond, *p_run_cond); for (;GKI_TIMER_TICK_EXIT_COND != *p_run_cond;) { do { /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this formula works only for * 1-1000ms heart beat units! */ delay.tv_sec = LINUX_SEC / 1000; delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000); /* [u]sleep can't be used because it uses SIGALRM */ do { err = nanosleep(&delay, &delay); } while (err < 0 && errno == EINTR); if (GKI_TIMER_TICK_RUN_COND != *p_run_cond) break; //GKI has shutdown /* the unit should be alsways 1 (1 tick). only if you vary for some reason heart beat tick * e.g. power saving you may want to provide more ticks */ GKI_timer_update( 1 ); /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d, tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */ } while ( GKI_TIMER_TICK_RUN_COND == *p_run_cond); /* currently on reason to exit above loop is no_timer_suspend == GKI_TIMER_TICK_STOP_COND * block timer main thread till re-armed by */ #ifdef GKI_TICK_TIMER_DEBUG BT_TRACE_0( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> SUSPENDED GKI_timer_update()" ); #endif if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) { GKI_TRACE_1("%s waiting timer mutex", __func__); pthread_mutex_lock( &gki_cb.os.gki_timer_mutex ); pthread_cond_wait( &gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex ); pthread_mutex_unlock( &gki_cb.os.gki_timer_mutex ); GKI_TRACE_1("%s exited timer mutex", __func__); } /* potentially we need to adjust os gki_cb.com.OSTicks */ #ifdef GKI_TICK_TIMER_DEBUG BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> RESTARTED GKI_timer_update(): run_cond: %d", *p_run_cond ); #endif } /* for */ ........................................................... }
更新GKI Timer.
NFCA_TASK的线程工作分析完了,我们来继续分析Thread的工作:
UINT32 NfcAdaptation::Thread (UINT32 arg) { const char* func = "NfcAdaptation::Thread"; ALOGD ("%s: enter", func); { ThreadCondVar CondVar; AutoThreadMutex guard(CondVar); GKI_create_task ((TASKPTR)nfc_task, NFC_TASK, (INT8*)"NFC_TASK", 0, 0, (pthread_cond_t*)CondVar, (pthread_mutex_t*)CondVar); CondVar.wait(); } NfcAdaptation::GetInstance().signal(); GKI_exit_task (GKI_get_taskid ()); ALOGD ("%s: exit", func); return 0; }
这个又创建了一个GKI_create_task, 会开线程任务运行 nfc_task这个函数。继续看看:
UINT32 nfc_task (UINT32 param) { UINT16 event; BT_HDR *p_msg; BOOLEAN free_buf; /* Initialize the nfc control block */ memset (&nfc_cb, 0, sizeof (tNFC_CB)); nfc_cb.trace_level = NFC_INITIAL_TRACE_LEVEL; NFC_TRACE_DEBUG0 ("NFC_TASK started."); /* main loop */ while (TRUE) { //线程挂起等待,直接有事件上来唤醒线程继续往下运行 event = GKI_wait (0xFFFF, 0); /* Handle NFC_TASK_EVT_TRANSPORT_READY from NFC HAL */ if (event & NFC_TASK_EVT_TRANSPORT_READY) { NFC_TRACE_DEBUG0 ("NFC_TASK got NFC_TASK_EVT_TRANSPORT_READY."); /* Reset the NFC controller. */ nfc_set_state (NFC_STATE_CORE_INIT); nci_snd_core_reset (NCI_RESET_TYPE_RESET_CFG); } if (event & NFC_MBOX_EVT_MASK) { //从mailboxed中取消息出来读消息,然后根据消息类型做分发处理 /* Process all incoming NCI messages */ while ((p_msg = (BT_HDR *) GKI_read_mbox (NFC_MBOX_ID)) != NULL) { free_buf = TRUE; /* Determine the input message type. */ switch (p_msg->event & BT_EVT_MASK) { case BT_EVT_TO_NFC_NCI: free_buf = nfc_ncif_process_event (p_msg); break; case BT_EVT_TO_START_TIMER : /* Start nfc_task 1-sec resolution timer */ GKI_start_timer (NFC_TIMER_ID, GKI_SECS_TO_TICKS (1), TRUE); break; case BT_EVT_TO_START_QUICK_TIMER : /* Quick-timer is required for LLCP */ GKI_start_timer (NFC_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE); break; case BT_EVT_TO_NFC_MSGS: nfc_main_handle_hal_evt ((tNFC_HAL_EVT_MSG*)p_msg); break; default: NFC_TRACE_DEBUG1 ("nfc_task: unhandle mbox message, event=%04x", p_msg->event); break; } if (free_buf) { GKI_freebuf (p_msg); } } } /* Process gki timer tick */ if (event & NFC_TIMER_EVT_MASK) { nfc_process_timer_evt (); } /* Process quick timer tick */ if (event & NFC_QUICK_TIMER_EVT_MASK) { nfc_process_quick_timer_evt (); } #if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE) if (event & NFA_MBOX_EVT_MASK) { while ((p_msg = (BT_HDR *) GKI_read_mbox (NFA_MBOX_ID)) != NULL) { nfa_sys_event (p_msg); } } if (event & NFA_TIMER_EVT_MASK) { nfa_sys_timer_update (); } #endif } NFC_TRACE_DEBUG0 ("nfc_task terminated"); GKI_exit_task (GKI_get_taskid ()); return 0; }
分析完这些后,我们一鼓作气,继续往下:
void NfcAdaptation::InitializeHalDeviceContext () { .................................................................... ret = hw_get_module (nci_hal_module, &hw_module); if (ret == 0) { ret = nfc_nci_open (hw_module, &mHalDeviceContext); if (ret != 0) ALOGE ("%s: nfc_nci_open fail", func); } else ALOGE ("%s: fail hw_get_module %s", func, nci_hal_module); ALOGD ("%s: exit", func); }
终于看到了要去调用HAL层了。。
nci_hal_module = "nfc_nci.pn54x"
nfc_nci_open 会调到nfc_open
static int nfc_open(const hw_module_t* module, const char* name, hw_device_t** device) { ALOGD("%s: enter; name=%s", __FUNCTION__, name); int retval = 0; /* 0 is ok; -1 is error */ if (strcmp(name, NFC_NCI_CONTROLLER) == 0) { pn547_dev_t *dev = calloc(1, sizeof(pn547_dev_t)); /* Common hw_device_t fields */ dev->nci_device.common.tag = HARDWARE_DEVICE_TAG; dev->nci_device.common.version = 0x00010000; /* [31:16] major, [15:0] minor */ dev->nci_device.common.module = (struct hw_module_t*) module; dev->nci_device.common.close = nfc_close; /* NCI HAL method pointers */ dev->nci_device.open = hal_open; dev->nci_device.write = hal_write; dev->nci_device.ioctl = hal_ioctl; dev->nci_device.core_initialized = hal_core_initialized; dev->nci_device.pre_discover = hal_pre_discover; dev->nci_device.close = hal_close; dev->nci_device.control_granted = hal_control_granted; dev->nci_device.power_cycle = hal_power_cycle; *device = (hw_device_t*) dev; } else { retval = -EINVAL; } ALOGD("%s: exit %d", __FUNCTION__, retval); return retval; }
此时NFC的开关还没有打开,我们再看看NFC 开关打开时,发生了神马:
从设置中点击开关,会调用NfcEnable 通过Binder 会远端调用NfcService.enable(),这个过程我就不贴代码了,往下看enable() 中做了什么
public boolean enable() throws RemoteException { .................................... new EnableDisableTask().execute(TASK_ENABLE); ............................. }
创建一个异步线程去执行TASK_ENABLE
boolean enableInternal() {try { mRoutingWakeLock.acquire(); try { if (!mDeviceHost.initialize()) { Log.w(TAG, "Error enabling NFC"); updateState(NfcAdapter.STATE_OFF); return false; } } finally { mRoutingWakeLock.release(); } } finally { watchDog.cancel(); } checkSecureElementConfuration(); mIsRouteForced = true; if (mIsHceCapable) { // Generate the initial card emulation routing table fAidTableFull = false; mCardEmulationManager.onNfcEnabled(); } mIsRouteForced = false; synchronized (NfcService.this) { mObjectMap.clear(); mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true); updateState(NfcAdapter.STATE_ON); } synchronized (NfcService.this) { if(mDeviceHost.doCheckJcopDlAtBoot()) { /* start jcop download */ Log.i(TAG, "Calling Jcop Download"); } } initSoundPool(); /* Start polling loop */ Log.e(TAG, "applyRouting -3"); mScreenState = mScreenStateHelper.checkScreenState(); mDeviceHost.doSetScreenOrPowerState(mScreenState); mIsRoutingTableDirty = true; applyRouting(true); return true; }
看点看三行:
boolean enableInternal() {
if (mState == NfcAdapter.STATE_ON) {
return true;
}
Log.i(TAG, "Enabling NFC");
updateState(NfcAdapter.STATE_TURNING_ON);
int timeout = mDeviceHost.getNfcInitTimeout();
if (timeout < INIT_WATCHDOG_MS)
{
timeout = INIT_WATCHDOG_MS;
}
Log.i(TAG, "Enabling NFC timeout" +timeout);
WatchDogThread watchDog = new WatchDogThread("enableInternal", timeout);
watchDog.start();
try {
mRoutingWakeLock.acquire();
try {
if (!mDeviceHost.initialize()) {
Log.w(TAG, "Error enabling NFC");
updateState(NfcAdapter.STATE_OFF);
return false;
}
} finally {
mRoutingWakeLock.release();
}
} finally {
watchDog.cancel();
}
checkSecureElementConfuration();
mIsRouteForced = true;
if (mIsHceCapable) {
// Generate the initial card emulation routing table
fAidTableFull = false;
mCardEmulationManager.onNfcEnabled();
}
mIsRouteForced = false;
synchronized (NfcService.this) {
mObjectMap.clear();
mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true);
updateState(NfcAdapter.STATE_ON);
}
synchronized (NfcService.this) {
if(mDeviceHost.doCheckJcopDlAtBoot()) {
/* start jcop download */
Log.i(TAG, "Calling Jcop Download");
jcopOsDownload();
}
}
initSoundPool();
/* Start polling loop */
Log.e(TAG, "applyRouting -3");
mScreenState = mScreenStateHelper.checkScreenState();
mDeviceHost.doSetScreenOrPowerState(mScreenState);
mIsRoutingTableDirty = true;
applyRouting(true);
return true;
}