嵌入式技术
目前在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条评论
快来发表一下你的评论吧 !