RFID会议签到系统总结(十一)――硬件访问(上)

本文介绍了一个RFID签到系统中硬件访问模块的设计思路,通过定义统一的硬件访问接口,使得不同RFID设备可以无缝接入系统。文章详细解释了接口各个组成部分的作用及其在实际应用中的意义。

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

这一块是整个系统的重中之重了,签到系统能否达到客户的要求,最大的瓶颈可能就是在这一块。因为无论是数据库还是Socket通讯,相对来说都还是比较成熟的技术,对于我们软件开发人员来说也比较的熟悉一点,故障排除、性能优化等等可寻求的参考与帮助也比较的多。而涉及硬件的开发对于纯粹的软件开发人员来讲就有点陌生,更何况RFID设备也还不是很成熟的设备。如果你用的是国际知名厂商的产品还好,无论是设备性能、稳定性,还是开发接口文档都比较完备,否则先跑通DEMO都要费点劲。

当然我这里不会太涉及具体硬件的东西,那种不具通用性的东西划不来在这里来总结,这儿主要是讲如何设计硬件访问模块,以求以后硬件的变更对系统的影响减少到最小。

 

硬件厂商提供的API一般都是很五花八门的,而且其风格都是如Win32时代的那些Windows API一样,跟我们现在的编程风格是格格不入。我们要做的第一步就是先要把系统中所有跟访问硬件的有关的动作提取为一个接口,不同的硬件设备根据其API来实现这个接口,系统调用只跟这个接口有关,对于客户端系统来说,硬件API就是不可见的了。

先看看接口的定义:

ContractedBlock.gifExpandedBlockStart.gif硬件访问接口
None.gif      public interface IHardwareAc
None.gif
ExpandedBlockStart.gifContractedBlock.gif      
dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 探测设备连接的串口
InBlock.gif
ExpandedSubBlockEnd.gif             
/// <param name="exceptPort">例外列表(不用探测的串口号)</param>

InBlock.gif
InBlock.gif             
void DetectPort(int[] exceptPort);
InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 初始化设备,准备读取数据
InBlock.gif
InBlock.gif             
bool InitDevice();
InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 关闭设备,释放资源
InBlock.gif
InBlock.gif             
void Release();
InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 从Buffer读数据
InBlock.gif
InBlock.gif             
string[] ReadBuffer();
InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 串口号
InBlock.gif
InBlock.gif             
int Port
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                    
getset;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 设备状态  0:非活动 1:活动    -1:错误
InBlock.gif
InBlock.gif             
int State
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                    
getset;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 硬件名字
InBlock.gif
InBlock.gif             
string Name
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                    
getset;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
InBlock.gif             
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// <summary>
InBlock.gif
InBlock.gif             
/// 设备种类
InBlock.gif
ExpandedSubBlockEnd.gif             
/// </summary>

InBlock.gif
InBlock.gif             
int Category
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                    
getset;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 硬件描述
InBlock.gif
InBlock.gif             
string Description
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                    
get;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 最近读取列表清零时间间隔
InBlock.gif
InBlock.gif             
int ZeroQueue
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                    
getset;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// 读取数据的块数
InBlock.gif
InBlock.gif             
int BlockCount
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                    
getset;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
/**//// <summary>
InBlock.gif
InBlock.gif             
/// 允许的最大串口
InBlock.gif
ExpandedSubBlockEnd.gif             
/// </summary>

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
int MaxSerialPortdot.gif{
InBlock.gif
InBlock.gif                    
getset;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif             
event ErrorHandler OnError;
InBlock.gif
ExpandedBlockEnd.gif      }

None.gif
None.gif 
None.gif
None.gif
public delegate void ErrorHandler(object sender,string ErMsg);
None.gif
None.gif

 

接下来逐步来解释这个接口的定义。

InitDeviceReleaes这二个方法是一组,一个是打开设备,一个是关闭设备,这二个比较好理解,

ReadBuffer这个方法是重头,这是从硬件读数据用的,为什么这里写成ReadBuffer呢?顾名思义这个方法是从一个缓冲(Buffer)里读数据的,对于客户端调用来说,它根本不关心你硬件以多快的速度监测感应区的RFID标签,它是以自己的速度按部就班地读取数据的。如果硬件本身有Buffer机制,那一切省事省力,在这个方法实现里直接调用硬件API就行了。如果硬件没有提供硬Buffer,为了防漏读的需要,我们必须要实现软Buffer的机制,然后在方法实现里从自己的软Buffer里读取数据。这里是对硬件速度的隔离。

下面有几个属性看上面的代码注释就是了,ZeroQueue这个属性必须要说明一下。“最近读取列表清零时间间隔”,这是为高速设备准备的属性,对于高速设备来说,短时间内同一张RFID标签可能会被读到好几次,虽然有些设备本身提供了防冲突机制,但那个时间是比较短的,更何况有些设备不一定有这种机制。所以我们自己必须要维护一个“最近读取列表”,对于这个列表中的数据的生存时间我们当然最好能够用属性公布出来,以便我们可以设置。当然定义“最近时间”更为严谨点,但那样维护列表比较复杂,我们得在列表每一项里加上“进入列表的时间”,鉴于这项功能于全局不是很重要,所以就从简。

BlockCount这个属性则是特殊情况下的产物,旧有系统从IC卡读取的是自己定义规则的数据,并没有用卡ID之类的东西来标识这张卡片的所有者,所以在之前基于旧系统的最初的实现我们也没有用RFID标签的UID来作标识。这一次重新实现时考虑到硬件方面的配置,所以也没有改成UID作标识,还是读取自定义的写入区块的数据。这样为了以后也许要增加数据标识,可能要读取更多的数据区块的数据,这里放一个属性可以灵活应付。(没有用UID作标识,在安全性方面有点欠缺,但也带来一个好处。因为客户为保万无一失,每次使用签到系统前,都要用一批测试卡测试一下整个系统,不用UID作标识的话,测试与正式运行就可以用同一个数据库,省却不少麻烦)

DetectPort方法与MaxSerialPort属性是为动态检测设备串口号准备的。一般来讲,我们可以把设备串口号固定下来,但由于现在电脑很多都没有串口(特别是笔记本),所以很多时候都是用USBRS232来解决。这样为了减少系统配置的麻烦,加了这个动态检测设备串口号的功能。

接口里剩下的只有一个OnError事件了,这个没什么可说的,只是希望在硬件设备出现问题时可以有途径让客户端知道。

 

这样不同的硬件设备只要实现了上述接口,都可以顺利地在系统中被调用了。

转载于:https://www.cnblogs.com/lichdr/archive/2007/06/29/799740.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值