嵌入式技术
目前在Linux系统中,每个厂家都使用不同的方式实现NFC驱动,然后自己在应用层上面做适配。但是Linux也已经推出NFC子系统,很多厂家也逐步在统一。
NFC子系统架构
NFC子系统主要负责:
(1) NFC芯片管理
(2) 轮询目标设备
(3) 底层数据交换
重要结构体
nfc_dev
//表示NFC设备 struct nfc_dev { int idx; //nfc芯片编号 u32 target_next_idx; //下一个target的编号 struct nfc_target *targets; //发现的target int n_targets; //发现额target总数 int targets_generation; struct device dev; bool dev_up; //nfc设备是否开启 bool fw_download_in_progress; //是否处于下载固件中 u8 rf_mode; //RF模式 bool polling; //是否轮询中 struct nfc_target *active_target; //当前激活的target bool dep_link_up; //P2P连接是否开启 struct nfc_genl_data genl_data; u32 supported_protocols; //支持的协议 struct list_head secure_elements; int tx_headroom; int tx_tailroom; struct timer_list check_pres_timer; struct work_struct check_pres_work; bool shutting_down; //是否关闭 struct rfkill *rfkill; //电源控制 struct nfc_vendor_cmd *vendor_cmds; //厂家命令 int n_vendor_cmds; //厂家命令数 struct nfc_ops *ops; //操作函数 struct genl_info *cur_cmd_info; //当前命令信息 };
上面主要是一些NFC的设备状态以及相关状态标志,还有扫描到的卡信息,操作函数等。
nfc_target
//表示目标设备(标签卡) struct nfc_target { u32 idx; //编号 u32 supported_protocols; //支持的协议 u16 sens_res; u8 sel_res; u8 nfcid1_len; u8 nfcid1[NFC_NFCID1_MAXSIZE]; u8 nfcid2_len; u8 nfcid2[NFC_NFCID2_MAXSIZE]; u8 sensb_res_len; u8 sensb_res[NFC_SENSB_RES_MAXSIZE]; u8 sensf_res_len; u8 sensf_res[NFC_SENSF_RES_MAXSIZE]; u8 hci_reader_gate; u8 logical_idx; u8 is_iso15693; u8 iso15693_dsfid; u8 iso15693_uid[NFC_ISO15693_UID_MAXSIZE]; };
上面主要是标签卡的信息,不同的协议会有不同的信息。这些信息在协议中都可以查看到。
nfc_ops
//操作函数接口 struct nfc_ops { int (*dev_up)(struct nfc_dev *dev); //开启 int (*dev_down)(struct nfc_dev *dev); //关闭 int (*start_poll)(struct nfc_dev *dev, u32 im_protocols, u32 tm_protocols); //开始轮询 void (*stop_poll)(struct nfc_dev *dev); //停止轮询 int (*dep_link_up)(struct nfc_dev *dev, struct nfc_target *target, u8 comm_mode, u8 *gb, size_t gb_len); //建立P2P连接 int (*dep_link_down)(struct nfc_dev *dev); //断开P2P连接 int (*activate_target)(struct nfc_dev *dev, struct nfc_target *target, u32 protocol); //激活target void (*deactivate_target)(struct nfc_dev *dev, struct nfc_target *target, u8 mode); //去激活target int (*im_transceive)(struct nfc_dev *dev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context); //Initiator模式传输 int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb); //Target模式传输 int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target); //检查卡在位 int (*fw_download)(struct nfc_dev *dev, const char *firmware_name); //下载固件 /* 安全元素API */ int (*discover_se)(struct nfc_dev *dev); //查找SE int (*enable_se)(struct nfc_dev *dev, u32 se_idx); //使能SE int (*disable_se)(struct nfc_dev *dev, u32 se_idx); //关闭SE int (*se_io) (struct nfc_dev *dev, u32 se_idx, u8 *apdu, size_t apdu_length, se_io_cb_t cb, void *cb_context); //SE I/O传输 };
上面主要就是使能,轮询,传输等接口。
API函数
//分配/释放nfc_dev struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, u32 supported_protocols, int tx_headroom, int tx_tailroom); static inline void nfc_free_device(struct nfc_dev *dev); //注册/注销nfc_dev int nfc_register_device(struct nfc_dev *dev); void nfc_unregister_device(struct nfc_dev *dev); //保存/获取驱动数据 static inline void nfc_set_drvdata(struct nfc_dev *dev, void *data); static inline void *nfc_get_drvdata(struct nfc_dev *dev); //分配发送sk_buff struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, unsigned int flags, unsigned int size, unsigned int *err); //分配接收sk_buff struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp);
接口比较简单,和其他驱动类似,都是分配设备,然后注册即可。
总结
NFC子系统其实不复杂,最主要的还是协议本身,nfc_ops中的接口就是对相关协议的实现。所以写好NFC驱动的关键是对协议要熟悉。
编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !