ISO7816是一套协议标准,这套协议不仅规定了智能IC卡的机械电气特性,而且还规定了智能IC卡的应用方法。智能IC卡的主要用途可归为身份识别、支付安全、加密/解密和信息存储四个方面。智能IC卡已经广泛应用到金融、电信、电子商务等领域,我们平常使用的IC电话卡,充值电卡、燃气卡和手机中的SIM卡都属于智能卡的范畴。

ISO7816协议标准中,将协议模型定义为4层:物理层、数据链路层、传输层、应用层。

•  物理层:定义了位交换,主要定义波特率和字符帧的传输方式

•  数据链路层:定义了字符交换,传输的检错与纠错等

•  传输层:定义了针对协议的面向应用的提出报文传输

•  应用层:定义报文交换的内容

当ISO7816在基于英创的工控主板上应用时,可将ISO7816智能卡简单的理解成一个串口设备。串口的物理连接和系统驱动程序实现了ISO7816协议标准中的物理层和数据链路层(如图1中黄线以下部份)。应用程序负责数据的解析与应用,实现ISO7816协议标准的传输层与应用层(如图1中黄线以上部份)。

图1中黄线与红线之间是英创的工控主板,提供了硬件接口、操作系统支持和串口驱动支持,既实现ISO7816协议的数据链路层和物理层。用户将ISO7816智能卡正确的连接到工控主板的串口上,编写应用程序,通过调用系统API函数就能实现对ISO7816智能卡的访问。

图 1:英创工控主板连接ISO7816智能卡

本文将以英创工控主板EM9280连接基于ISO7816协议的ESAM模块为例,讨论用户需要做的两项工作:

1、将智能卡连接到工控主板的串口

2、应用程序如何访问已连接到系统中的智能卡

1、智能卡(ESAM)的硬件连接

        如图2中的U2所示,ESAM模块需要一个工作时钟和一个复位信号,通过一位IO与主机连接实现数据通讯。ESAM的复位信号使用EM9280的一位GPIO控制,工作时钟使用EM9280的一路PWM。ESAM模块使用单个I/O与主机通讯,自动切换收发方向,EM9280提供的是标准3线串口,所以没有办法与ESAM直接连接。图2中利用74HCT157,将串口的RXD,TXD模拟成ISO7816单IO通讯模式,利用串口的RTS#信号实现数据收发方向的自动切换。当EM9280发送数据时,RTS#输出低电平,选通74HCT157的A组,数据通过TXD6→2A→2Y输出到I/O脚。而1A通过R2上拉到高电平,所以1Y也是高电平,RXD6不会收到任何数据。数据发送完成后,RTS#被串口驱动程序自动将置为高电平,74HCT157的B组选通,ESAM模块发送的数据由I/O→1B→1Y到达RXD6,串口接收由ESAM模块发来的数据。此时2B由R2上拉到高电平,所以2Y亦是高电平,不会影响I/O上的数据传输。

图 2:EM9280连接ESAM模块

2、应用程序设置方法

        对应用程序来讲,与ESAM通讯类似于RS485的半双工通讯,只是在开始串口通讯之前,针对ESAM模块,还需要一些额外的设置。

 2.1  产生ESAM工作时钟

ESAM模块缺省工作时钟是其通讯波特率的372倍,我们使用EM9280的PWM1来产生ESAM的工作时钟。

// Generate clock for ISO7816. 
        m_hPWM = CreateFile(_T('PWM1:'), // name of device 
        GENERIC_READ|GENERIC_WRITE, // desired access 
        FILE_SHARE_READ|FILE_SHARE_WRITE, // sharing mode 
        NULL, // security attributes (ignored) 
        OPEN_EXISTING, // creation disposition 
        FILE_FLAG_RANDOM_ACCESS, // flags/attributes 
        NULL); // template file (ignored) 
        if( m_hPWM == INVALID_HANDLE_VALUE ) 
        { 
                goto InitClearUp; 
        }

PWM_INFO PwmInfo; 
        PwmInfo.dwFreq = dwFI_DI_Ratio * dwBaud; // = 372 * 9600 = 3.5712MHz 
        PwmInfo.dwDuty = 50; // 50% 
        PwmInfo.dwResolution = 1; 
        dwNumberOfBytesWritten = 0; 
        WriteFile( m_hPWM, &PwmInfo, sizeof(PWM_INFO), &dwNumberOfBytesWritten, NULL);

2.2  打开串口并使能RTS_TOGGLE功能

使用标准的文件操作函数CreateFile打开串口设备,同时通过SetCommState函数设置串口通讯相关参数。此时ESAM模块的通讯波特率设置为9600bps,8位数据位,1位停止位,偶校验。

DCB dcb; 
        GetCommState( m_hSer, &dcb ); 
        dcb.BaudRate = Baud; // 波特率 = 9600 
        dcb.ByteSize = Databits; // 数据位 = 8 
        dcb.Parity = EVENPARITY; // 偶校验 
        dcb.StopBits = ONESTOPBIT; // 停止位 = 1 
        SetCommState(m_hSer, &dcb);

在图2中,将3线串口模拟成单线的ISO7816模式,使用串口的RTS作为数据传输方向控制信号。EM9280可以为打开的串口任意指定一位GPIO作为其RTS信号线,实现方法如下:

DCB dcb; 
        BOOL bRet;

bRet = DeviceIoControl(m_hSer, // 已经打开的串口设置句柄 
        IOCTL_SET_UART_RTS_PIN, // I/O control code 
        &dwRTSPin, // 选择作为RTS的GPIO,如图2中选择GPIO7 
        sizeof(DWORD), 
        NULL, 
        0, 
        NULL, 
        NULL); 
        if( bRet ) 
        { 
                GetCommState( m_hSer, &dcb ); // Get dcb 
                dcb.fRtsControl = RTS_CONTROL_TOGGLE; // Enable RTS Toggle 
                SetCommState(m_hSer, &dcb); // update dcb 
        }

  2.3  数据收发

应用程序可以创建一个线程,然后等待串口事件接收串口数据。

应用程序调用WriteFile函数发送数据,但需要特别注意ISO7816传输协议中关于“保护时间”要求,协议中规定两个连续的字符帧之间必需要有一个最小时间间隔,即保护时间,当波特率为9600bps时,保护时间最小大约为200uS。

如果直接调用WriteFile将要发送的数据一次性发送

WriteFile( m_hSer, Buf, len, &dwLen, NULL);

在EM9280上测得的字符间时间间隔大约为30uS,显示不能满足协议保护时间的要求。为了达到保护时间的要求,可以采用下面的方式,将需要发送的数据一个字节一个字节的发送。

for( int i; i<len; i++ )

<len; i++="" )="" <br="">                WriteFile( m_hSer, Buf+i, 1, &dwLen, NULL);

上面的for循环每调用一次WriteFile函数,只发送1个字节,在EM9280上测得的字符间时间间隔最小大约为500uS,满足协议保护时间的要求,实际测试也能正常与ESAM模块通讯。

如果主机串口硬件没有支持ISO7816模式,如英创公司工控主板EM9170、EM9283等,就可以按本文的方法,增加很少的几个器件就能连接ISO7816设备。

工控主板对ISO7816智能卡标准的支持的更多相关文章

  1. 3TB硬盘的容量已经超出了传统分区标准的支持

    为什么3TB会有接近750G空间不能用? MBR分区格式是瓶颈 其实3TB硬盘之所以会出现各种问题,关键就在于它的容量已经超出了传统分区标准的支持.传统的硬盘采用MBR分区格式,使用LBA寻址,这种寻 ...

  2. OSS.Common获取枚举字典列表标准库支持

    上篇(.Net Standard扩展支持实例分享)介绍了OSS.Common的标准库支持扩展,也列举了可能遇到问题的解决方案.由于时间有限,同时.net standard暂时还没有提供对Descrip ...

  3. c++ 11开始语言本身和标准库支持并发编程

    c++ 11开始语言本身和标准库支持并发编程,意味着真正要到编译器从语言和标准库层面开始稳定,估计得到17标准出来.14稳定之后的事情了,根据历史经验,新特性的引入到稳定被广泛采用至少要一个大版本的跨 ...

  4. TinyXPath 对于xpath标准的支持测试

    xpath是一种基于xml的查询标准,一般的xml解析工具都具有,有的因为卓越的xpath性能而出名,其匹配查询算法牛逼而又高效,和正则有的一拼.虽然我现在大部分从事前端工作了,但是对于原理性的东西还 ...

  5. Visual Studio2013的C语言编译器对C99标准的支持情况

    Visual Studio2013终于开始比较良好地支持C99特性了.在此之前,如果用C语言写代码的话,变量名都需要放到函数体的前面部分,代码写起来十分别扭. 而Visual Studio2013中的 ...

  6. 用java实现简单快速的webservice客户端/数据采集器(支持soap1.1和soap1.2标准,支持utf-8编码)

    前言: 用了cxf,axis等各种wbeservice实现库,简单试用了一下动态调用的方式,很不满意,完全无法满足业务的需要,所以自己实现了一个webservice采集客户端,方便动态调用外部webs ...

  7. TitleLayout——一个Android轻松实现通用、标准、支持沉浸式状态栏的标题栏库

    TitleLayout 多功能.通用的.可在布局或者使用Java代码实现标题栏:支持沉浸式状态栏,支持左侧返回按钮(不需要手动实现页面返回),左侧支持图片+文字.图片.文字:右侧支持图片.文字等. 堆 ...

  8. gcc对c++标准的支持

    GCC 4.8.1完全支持c++11核心部分,对应的glibc为2.17 gcc 4.9支持c++11正则表达式,卧槽...4.8.5会报terminate called after throwing ...

  9. C++ Standards Support in GCC - GCC 对 C++ 标准的支持

    C++ Standards Support in GCC - 2019-2-20 GCC supports different dialects of C++, corresponding to th ...

随机推荐

  1. BZOJ1697: [Usaco2007 Feb]Cow Sorting牛排序

    1697: [Usaco2007 Feb]Cow Sorting牛排序 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 387  Solved: 215[S ...

  2. Ubuntu 14.04 64位安装Android Studio 和 genymotion (上)

    先说下,Ubuntu 上安装Android Studio真是一路坑阿,一路坑阿,加上天  朝 防火墙挡着,折腾了快一天才弄好阿 找了n多教程,md不是抄的就是转的,而且都没说清楚具体咋装阿,一个图一个 ...

  3. idea 14运行java工程报错-Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable and mvn script match.

    报错信息:Disconnected from the target VM, address: '127.0.0.1:59770', transport: 'socket' -Dmaven.multiM ...

  4. storm高级原语-Transactional topology

    参考: http://xumingming.sinaapp.com/736/twitter-storm-transactional-topolgoy/ http://xumingming.sinaap ...

  5. java随机数生成器

    一.java.lang.Math.Random 调用这个Math.Random()函数能够返回带正号的double值,取值范围是[0.0,1.0)的左闭右开区间,并在该范围内(近似)均匀分布. 二.j ...

  6. java中protect属性用法总结

    测试代码: pojo类: package com.lky.h1; public class Base { private Integer id; protected String name; publ ...

  7. 重写boost内存池

    最近在写游戏服务器网络模块的时候,需要用到内存池.大量玩家通过tcp连接到服务器,通过大量的消息包与服务器进行交互.因此要给每个tcp分配收发两块缓冲区.那么这缓冲区多大呢?通常游戏操作的消息包都很小 ...

  8. JScript_Test

    Hello SyntaxHighlighter function helloSyntaxHighlighter() { return "hi!"; } function hello ...

  9. rac 10g 加入节点具体解释

    目标: 当前我环境中是有两个节点RAC1和RAC2 节点.如今添加一个RAC3节点.   概要:为现有的Oracle10g RAC 加入节点大致包含下面步骤: 1. 配置新的server节点上的硬件及 ...

  10. OD: GS Bypasing via SEH / .data

    通过 SEH 绕过 GS 保护 GS 机制没对 SEH 提供保护,所以可心通过攻击异常来绕过 GS. 实验环境为: VMware : Windows sp4, 此版本无 SafeSEH 的影响 Vis ...