基于KL25的RFID构件化工程框架研究
0 引言
目前,射频识别技术(RFID)已在多个领域中被广泛使用,但RFID应用系统是典型的硬件平台相关性系统,通常具有难以维护、更新、移植等特点[1],其中存在大量重复工作。软件构件技术是指通过组装一系列可复用的软件构件形成软件系统的软件技术,以软件构件为基础,设计一个合理的构件化工程框架是降低工程开发的难度,提升软件的可重用性、可移植性和可维护性的有效途径[2]。本文针对RFID应用系统的特点,通过对RFID一般应用模型的分析,封装了构件相关函数,并给出了结构清晰合理的RFID构件化工程框架,有效提高了RFID应用系统的开发效率。同时以思卡尔KL25 MCU和射频芯片RC531构成的实验装置为基础,在Kinetis Design Studio集成开发环境中对该构件框架的使用进行了具体测试,并分析了该构件框架在其他嵌入式系统上的移植应用,对提高系统开发的规范性和可移植性具有重要参考意义。
1 RFID驱动构件的设计及解析
构件设计的目标是可重用,达到此目标的关键是构件提供了契约式的接口,它的输入接口代表了环境为它提供的服务,输出接口代表了它为环境提供的服务。一个接口提供一种服务,完成某种逻辑行为[3]。构件接口由两部分组成:一是署名部分,即构件本身提供服务的描述,由构件头文件(.h)实现;二是行为部分,即构件行为的描述,由源文件(.c)实现。因此,为提高构件可重用性,在设计软件构件时,必须对构件的共性和个性进行分析,抽取出构件的属性和对外接口函数。尽量做到:当一个构件应用到不同系统中时,仅需修改构件的头文件,对于构件的源程序文件则不必修改或改动很小。
1.1 RFID应用系统的一般模型
通过分析RFID应用系统的共性,可以建立一个由3部分组成的一般系统模型[4],如图1所示。控制MCU主要提供对射频读写芯片的控制操作;射频读写芯片及辅助电路用于实现与控制MCU的数据通信并控制与标签的通信操作;天线部分则实现电磁波的收发。
以苏州大学飞思卡尔嵌入式中心开发的 RFID实验装置为例,KL25作为控制MCU,是整个硬件系统的核心;射频读写芯片RC531与KL25通信实现各种功能。RC531支持并行接口或SPI接口两种方式实现与控制MCU的通信。任意一款MCU只需按表1所示提供对应的GPIO引脚即可以模拟SPI的方式控制RC531芯片。
1.2 构件函数封装
在RFID系统中,射频读写芯片RC531作为KL25的外设[5-6],是驱动构件的对象。
RC531对A类卡的通信处理流程如图2所示。首先,发送Request询卡命令给天线工作范围内的所有卡片,卡片在上电复位后响应该命令;随后通过防冲突循环,根据卡的序列号选中一张卡;接着对准备访问的卡片的存储区的密码进行鉴别;在通过了密码验证后,读写模块可以对该存储区的数据进行读、写、增值、减值以及挂起等操作[7]。
根据该处理流程,从上层应用的角度出发,可不必关注防冲突、密码验证等过程,只需要关注对存储区的具体应用。因此RC531构件只需要对A类卡提供初始化、读写数据等功能函数,而防冲突等操作可作为内部函数处理。同理根据B类卡的处理流程,构件需要提供初始化、读取卡号等函数。
综合以上分析,在RC531构件头文件中的内容应主要包含外设模块寄存器相关信息的定义和函数原型的声明。前者指明了本“元构件”与具体硬件相关的信息,而后者则给出了本驱动构件对上层构件或应用程序所提供的接口函数。另外从硬件的角度看,控制射频模块只需要确定MCU与RC531的接口一个要素即可,但由于KL25的每个引脚都需要确定端口号与引脚号两个部分,所以在应用中将这两个部分组合为一个值,方便理解与调用。通过这种设定,上层构件在使用它时,将具有极大的灵活性。构件源程序文件实现对外接口函数功能,构件内部使用的函数也在构件源程序文件中定义。最终在头文件中应给出MF_Init(初始化)、MF_ReadCardA(读A卡)、MF_WriteCardA(写A卡)、MF_Deduct(电子钱包充值)、MF_Recharge(电子钱包扣款)、MF_Halt(挂起)、MF_ ReadCardB(读B卡)等功能函数。以初始化函数为例,其需要完成的功能为:将KL25的GPIO接口初始化为SPI形式,将RC531复位并将天线接口初始化为A类或B类通信状态。因此初始化函数的封装需要提供一个通信协议类型的参数,并需要返回一个状态值反映初始化是否成功。
//将KL25部分GPIO口定义为模拟SPI功能
//MFRC531的MOSI引脚
#define MF_MOSI_PIN
(GPIO_PORT_D << 8) | 3
//MFRC531的MISO引脚
#define MF_MISO_PIN
(GPIO_PORT_D << 8) | 5
…
/函数名称:MF_Init
//功能概要:复位芯片并根据标签类型初始化
//参数说明:ProMode: A类协议 Pro_A
// B类协议 Pro_B
//函数返回:错误码 MI_OK:初始化成功
// MI_NOTAGERR:失败
uint_8 MF_Init(uint_8 ProMode);
…
2 工程框架设计
2.1 工程框架的组织原则
按照软件工程的思想,框架是一个能够被开发人员实例化的系统构架,规定了应用软件的体系结构,定义了模块和对象的分割,确定了各部分的主要职责、协作关系及控制流程[8]。工程框架的设计和组织必须是可复用、可移植和可理解的,以利于提高嵌入式软件的开发效率。因此,本文在设计中遵循以下的原则[9-10]:
(1)系统结构分层,软件与硬件分离。
首先,应用系统按照用户、业务逻辑、驱动进行分层,将不同层次的构件文件组织在不同文件夹下,使框架可即插即用替换构件;其次,从不同的层次中分别提炼出高层构件和底层构件,高层构件与硬件无关,而底层构件与硬件密不可分,是硬件驱动程序的封装。高层构件实现一个具体应用,而底层构件是对硬件驱动程序的封装;同时在硬件构件层中,相对于核心构件最小系统而言,中间构件和终端构件都是核心构件的“外设”,将这些“外设”的驱动程序封装而成的软件构件作为底层外设构件。底层外设构件可以调用底层内部构件,而高层构件可以调用底层外设构件和底层内部构件中的功能构件。
(2)将芯片特性分离
每款芯片都拥有自己的内核及芯片初始化文件,这些文件由芯片设计人员提供,具有特定的内容。将这类文件组织在一起,这样针对某一款芯片进行开发时,应用开发者不必修改该目录。
2.2 工程框架的组织形式
通过RFID应用系统模型,可将射频读写芯片作为外设构件处理。基于框架的组织原则,通过对工程框架的目录名和共性的文件归纳分类组织,得到符合要求的构件化工程框架。以基于KL25的RFID工程为例,其在KDS1.1.1开发环境下的目录结构组织如图3所示。
整个框架中的目录按照开发系统所应用到的文件顺序排列,各目录中存放文件的原则如下:
Includes目录存放开发环境相关的文件,由工程自动生成。
01_DOC中存放工程说明文档,工程有变化时,即时更新。
02_CPU、03_MCU目录分别存放与内核及芯片相关的公共文件,其中包含了几乎所有底层构件都涉及的MCU寄存器的宏定义、启动代码等文件。
04_Linker_File中存放链接脚本文件,描述程序文件在芯片存储区中的存放顺序,该文件与编译器相关。
05_Driver、06_App_componet目录分别存放底层硬件的驱动构件及高层构件文件,底层构件是硬件系统各功能模块的驱动封装,如读写芯片RC531的构件文件等;高层构件用于实现具体的应用功能。
07_Soft_component目录存放稳定、移植性良好、与硬件无关的抽象构件文件,如数值类型转换算法等,如此则实现了业务、逻辑、数据的完全分离。
08_Sources目录包括总头文件includes.h、主函数文件main.c以及中断函数文件isr.h、isr.c。main.c文件是工程任务的核心文件,用户的应用都添加在该文件中。总头文件中包含主程序文件中需要的驱动构件头文件、变量声明等;isr.c中包含了中断函数的实现代码,isr.h是isr.c文件的头文件,存放中断函数声明,因为中断向量表文件是工程框架的重要内容之一,因此,在工程框架中,用户应避免直接对中断向量表文件进行修改,而采用“注册”的方式为用户提供编程接口,既方便用户使用,同时也提高了系统编程的安全性。
3 工程在框架下的移植分析
在实际应用中,工程的移植有多种情况。以KL25下的RFID应用工程为例,当需要在相同的硬件环境下设计不同的工程时,只需以该工程为模板,在05_Driver目录下添加需要的底层构件,并在08_Sources目录下修改主函数中的任务,即可在其余文件保持不变的情况下,快速开发出新的应用工程。这种情况下应用工程之间的可移植性最大。
当将工程移植到相同或相兼容内核的芯片时,仅需修改03_MCU目录下的芯片文件,以及根据硬件连接方式在05_Driver目录下修改RC531构件头文件中的引脚定义,已有的工程即可在新的目标芯片下运行。如将KL25上的工程移植到Cortex-M4内核的K60芯片时,只需将头文件中的引脚定义修改即可。
//将K60部分GPIO口定义为模拟SPI功能
//MFRC531的MOSI引脚
#define MF_MOSI_PIN
(GPIO_PORT_E << 8) | 19
//MFRC531的MISO引脚
#define MF_MISO_PIN
(GPIO_PORT_E << 8) | 1
…
当工程移植到不同内核的芯片时,由于硬件结构一般变化较大,通常需要修改02_CPU、03_MCU、08_Sources目录下的中断注册文件等与芯片直接相关的系统文件,同时还须修改GPIO的驱动,但设备构件文件的结构及工程框架依然可以保持不变。可见在该框架下,工程组织非常清晰,移植也很方便。
4 工程框架应用与测试
测试工程在KDS1.1.1开发环境和SD-FSL-KL25-EVB开发板上进行,测试工程实现的功能为:KL25的串口1与PC通信,接收读取M1卡中数据块5中数据的控制命令,实现框架的中断服务功能;查找并读取标签中的数据,通过串口1将数据显示在PC上。要实现以上功能,需在框架isr.c文件中添加串口1的中断服务例程,并在isr.h文件中实现中断注册,然后在主函数文件中分别调用RFID初始化、读数据构件与串口发送数据构件即可。主函数部分代码如下:
MF_Init(Pro_A);
for(;;)
{
If(1==read_flag)
{
if(MI_OK == MF_ReadCardA
(ReadDataBuff, Key,BlockNo))
{
uart_send_string(UART_1, "Read Success!\r\n");
//将读取的数据转换为16进制字符形式
…
//将数据输出
uart_sendN(UART_1,16,DataBuff);
}
else
{
uart_send_string(UART_1, "Read failed!\r\n");
}
}
…
将测试工程编译后下载到目标板,将开发板上的串口1与PC连接运行,从串口测试工具中发送控制命令“R11”,可以观察到接收窗口中稳定地回送数据,如图4所示。测试结果表明在该工程框架下,工程任务建立简便,运行稳定,控制逻辑清晰可靠,能够满足工程运行的需求。
5 结论
RFID应用系统在市场中被广泛使用,但RFID开发原理较为复杂,同时在开发中存在大量重复工作。设计一个合理的开发框架有助于封装底层构件,帮助开发者高效地开发出稳定的嵌入式RFID产品。本文根据软件工程思想,对RFID构件分析并封装了MF_Init、MF_ReadCardA、MF_WriteCardA、MF_Deduct、MF_Recharge、MF_Halt、MF_ ReadCardB等功能函数,并给出了结构清晰合理的构件化工程框架,对提高RFID应用系统开发的规范性和可移植性具有重要参考意义。同时以飞思卡尔KL25 MCU和射频芯片RC531构成的实验装置为基础,给出了测试工程的创建及测试过程,为RFID应用系统开发提供了一个结构清晰、层次分明、可移植性强的开发模板。