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;
}
posted @ 2020-05-06 10:04  five.li  阅读(1000)  评论(0编辑  收藏  举报