我是靠谱客的博主 甜美香菇,这篇文章主要介绍android nfc驱动,Android NFC 简单梳理,现在分享给大家,希望可以做个参考。

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

在 Android O 中NFC 主要有两个进程 :

be291ff21cedcda551fe7191c42a05b9.png com.android.nfc 向上层app 提供 NFC 接口,另外负责分发各种 event , [email protected] 是 vendor 的 hidl service 。

先来看一下 [email protected] 这个进程 , service 的code 位置在 vendor/nxp/interfaces , service 定义在 rc 文件中 :

service nqnfc_hal_service /vendor/bin/hw/vendor.nxp.hardware.nfc@1.0-service

class hal

user nfc

group nfc

class 为 hal 的service 会在 on boot 时启动

int main() {

......

status = registerPassthroughServiceImplementation();

status = registerPassthroughServiceImplementation();

......

}

这里注册了两个接口 INfc (AOSP)和 INqNfc(Vendor), 可以找到其 HIDL_FETCH_Ixxx 函数可以看到都是去打开 ID 为 NFC_NCI_HARDWARE_MODULE_ID 这个 moudle ,这两个接口的定义分别是 :

/* path: hardware/interfaces/nfc/1.0/INfc.hal */

interface INfc {

open(INfcClientCallback clientCallback) generates (NfcStatus status);

write(NfcData data) generates (uint32_t retval);

coreInitialized(NfcData data) generates (NfcStatus status);

prediscover() generates (NfcStatus status);

close() generates (NfcStatus status);

controlGranted() generates (NfcStatus status);

powerCycle() generates (NfcStatus status);

};

/* path: vendor/nxp/interfaces/opensource/nfc/1.0/INqNfc.hal */

interface INqNfc {

ioctl(uint64_t ioctlType, NfcData inputData) generates(NfcData outputData);

};

下面主要来看 NFC_NCI_HARDWARE_MODULE_ID 这个 moudle 的定义, 其 code 路径是在 vendor/nxp/opensource/external/libnfc-nci/halimpl/pn54x ( 这里不同project 可能不同) , 该路径下的code 会编译为 nfc_nci.nqx.default.so .

在 HIDL_FETCH_INfc 及 HIDL_FETCH_INqNfc 中都会调用该 moudle 的 open 接口 :

static int nfc_open(const hw_module_t* module, const char* name,

hw_device_t** device)

{

if (strcmp(name, NFC_NCI_CONTROLLER) == 0)

{

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->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;

dev->check_fw_dwnld_flag = hal_get_fw_dwnld_flag;

*device = (hw_device_t*) dev;

}

......

}

这里会填充一个 pn547_dev_t 结构体, hidl service 中的接口实际上就是调用其成员函数 .关于其中的调用关系后面在来梳理。

HIDL Service 在通过 dev 结点来与kernel 中 NFC driver 通信, 这里结点地址是写在config 文件中

# Nfc Device Node nameNXP_NFC_DEV_NODE="/dev/nq-nci"

在开启 NFC 时最终调用到 phTmlNfc_i2c_open_and_configure 中打开并保存节点供后续 read/write 使用。

com.android.nfc

接下来主继续看 com.android.nfc 进程 , code 路径在 /vendor/nxp/opensource , 在 AndroidManifest.xml 中有如下定义

.......

android:persistent="true"

......

>

这里 NfcApplication 包含属性 persistent 为 true , 所以它会在开机事由 AM 启动, 其主要任务是创建一个 NfcService 对象 , 下面简单看一下 NfcService 的初始化 :

public NfcService(Application nfcApplication) {

mNfcTagService = new TagService();//提供 Tag 相关接口

mNfcAdapter = new NfcAdapterService();//提供 enable , disable 以及扫描模式等接口

mNxpNfcAdapter = new NxpNfcAdapterService();

mExtrasService = new NfcAdapterExtrasService();

mNxpExtrasService = new NxpNfcAdapterExtrasService();

sService = this;

mScreenStateHelper = new ScreenStateHelper(mContext);//NFC 会根据屏幕状态改变 discovery 等状态

mContentResolver = mContext.getContentResolver();

mDeviceHost = new NativeNfcManager(mContext, this);//JNI 接口

mNfcUnlockManager = NfcUnlockManager.getInstance();

if(mInProvisionMode)

{

/* if device is in provision mode, set this mode at lower layers */

mDeviceHost.doSetProvisionMode(mInProvisionMode);

}

mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode,

mIsLiveCaseEnabled);//负责分发各种 event

mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser,

mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize());

.......

mState = NfcAdapter.STATE_OFF;//初始化状态 STATE_OFF

mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT);//Android Beam 状态

setBeamShareActivityState(mIsNdefPushEnabled);

mScreenState = mScreenStateHelper.checkScreenState();

IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);

//mContext.registerReceiver(mAlaReceiver, lsFilter);

mContext.registerReceiverAsUser(mAlaReceiver, UserHandle.ALL, lsFilter, null, null);

...... // CARD_EMULATION 相关

// Make sure this is only called when object construction is complete.

ServiceManager.addService(SERVICE_NAME, mNfcAdapter);

new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks

initSoundPool();//初始化 NFC 的提示音

}

在初始化各个成员变量之后 , 创建一个线程类 EnableDisableTask 执行 TASK_BOOT 参数 :

case TASK_BOOT:

// 如果上一次关机前NFC 为开启状态则开启 NFC

if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) {

mIsTaskBoot = true;

enableInternal();

mIsTaskBoot = false;

} else {

mDeviceHost.checkFirmware();//这里会检查当前FW的时间戳是否和系统记录的一致,不一致则进行 download FW

}

if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) {

Log.i(TAG, "First Boot");

mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false);

mPrefsEditor.apply();

}

break;

到这里 NfcService 的初始化基本结束, 其他具体的各个内部 service 的作用后续在根据流程来介绍。 这里在来大概看一下连接 HIDL Service 的地方, 在 NFC enable 过程中会调用 NativeNfcManager 的 initialize 方法:

enableInternal()

=>mDeviceHost.initialize()

=> NativeNfcManager : doInitialize

=> nfcManager_doInitialize()

NfcAdaptation& theInstance = NfcAdaptation::GetInstance();

theInstance.Initialize(); //start GKI, NCI task, NFC task

=> NfcAdaptation::Initialize()

=> NfcAdaptation::InitializeHalDeviceContext()

// 后面都是调用 mHal 及 INqNfc 的接口

mHal = INfc::getService();

mNqHal = INqNfc::getService();

NFC driver

上面可以知道在 HIDL service 中通过 ‘/dev/nq-nci’ 结点来 read / write , 下面在简单看一下 NFC driver 。

static struct i2c_driver nqx = {

.id_table = nqx_id,

.probe = nqx_probe,

.remove = nqx_remove,

.driver = {

.owner = THIS_MODULE,

.name = "nq-nci",

.of_match_table = msm_match_table,

.pm = &nfc_pm_ops,

},

};

static const struct of_device_id msm_match_table[] = {

{.compatible = "qcom,nq-nci"},

{}

};

static int __init nqx_dev_init(void)

{

return i2c_add_driver(&nqx);

}

module_init(nqx_dev_init);

首先注册 I2C 设备驱动, 在探测到该设备之后 :

static int nqx_probe(struct i2c_client *client,

const struct i2c_device_id *id)

{

nqx_dev = kzalloc(sizeof(*nqx_dev), GFP_KERNEL);

nqx_dev->client = client;

......//填充nqx_dev 及初始化各个gpio 等

//注册 nq-nci misc设备, 其中会创建 /dev/nq-nci 结点nqx_dev->nqx_device.minor = MISC_DYNAMIC_MINOR;

nqx_dev->nqx_device.name = "nq-nci";

nqx_dev->nqx_device.fops = &nfc_dev_fops;

r = misc_register(&nqx_dev->nqx_device);

.......

再来看该节点的操作函数,其中主要是掉用I2C接口来与挂在 I2C bus 上的NFC chip 通信。

static const struct file_operations nfc_dev_fops = {

.owner = THIS_MODULE,

.llseek = no_llseek,

.read = nfc_read,

.write = nfc_write,

.open = nfc_open,

.unlocked_ioctl = nfc_ioctl,

};

static ssize_t nfc_write(struct file *filp, const char __user *buf,

size_t count, loff_t *offset)

{

struct nqx_dev *nqx_dev = filp->private_data;

tmp = memdup_user(buf, count);

ret = i2c_master_send(nqx_dev->client, tmp, count);

return ret;

}

最后

以上就是甜美香菇最近收集整理的关于android nfc驱动,Android NFC 简单梳理的全部内容,更多相关android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部