英创嵌入式Linux工控主板如何实现ISO7816协议
作者:互联网
当ISO7816在基于英创的工控主板上应用时,可将ISO7816智能卡简单的理解成一个串口设备。串口的物理连接和系统驱动程序实现了ISO7816协议标准中的物理层和数据链路层(如图1中黄线以下部份)。应用程序负责数据的解析与应用,实现ISO7816协议标准的传输层与应用层(如图1中黄线以上部份)。
图1中黄线与红线之间是英创的工控主板,提供了硬件接口、操作系统支持和串口驱动支持,既实现ISO7816协议的数据链路层和物理层。用户将ISO7816智能卡正确的连接到工控主板的串口上,编写应用程序,通过调用系统API函数就能实现对ISO7816智能卡的访问。
图 1:英创工控主板连接ISO7816智能卡
本文将以英创工控主板EM9280连接基于ISO7816协议的ESAM模块为例,讨论用户需要做的两项工作:
1、将智能卡连接到工控主板的串口
2、应用程序如何访问已连接到系统中的智能卡
1、智能卡(ESAM)的硬件连接
图 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
WriteFile( m_hSer, Buf+i, 1, &dwLen, NULL);
上面的for循环每调用一次WriteFile函数,只发送1个字节,在EM9280上测得的字符间时间间隔最小大约为500uS,满足协议保护时间的要求,实际测试也能正常与ESAM模块通讯。
如果主机串口硬件没有支持ISO7816模式,如英创公司工控主板EM9170、EM9283等,就可以按本文的方法,增加很少的几个器件就能连接ISO7816设备。
英创公司Atmel系列工控主板,CPU的串口本身就支持ISO7816模式,可直接连接IS07816智能卡。我们实现了相应的驱动程序,相关的使用方法可参考下面的文章:
ISO7816通讯协议在工控主板EM9160中的实现方案
工控主板EM9161对ISO7816协议的支持
英创嵌入式Linux工控主板如何实现ISO7816协议
我们还提供了ESAM模块完整的测试程序,需要的用户可与我们联系获取相关代码。
标签:ISO7816,英创,Linux,dcb,ESAM,串口,智能卡,工控 来源: https://www.cnblogs.com/icaowu/p/14903034.html