直接控制GPIO引脚读取磁卡数据
2008-10-21 14:26
281 查看
1、硬件GPIO引脚使用情况:
GPIO[49:55、57]对应磁卡器的RCP[3]、RDD[3]、CLS、NPWN
2、磁卡各引脚的使用情况:
CLS 刷卡开始为下降沿,磁卡走行中保持低电频,走向结束上升沿,无磁卡走行时保持高电频
RCP记录采样频率,每半个周期的幅度为100千欧 14毫秒;620千欧 60毫秒,前半周期高电,后半周期为低频
RDD数据采样端,当采样引脚RCP为高电频(前半周期)时,该段开始采样
CLS 为共用引脚,RCP、RDD在磁卡不同的情况下分别使用1-3个不同的引脚
3、实现读取磁卡数据的思路:
思路一[/i][/b]:[/i][/i]
A.CLS下降沿时发生中断,置bit计数器为0,以便记录最终得到数据量(以bit为单位);上升沿时,返回逻辑中断向量,唤醒IST
B.RCP上升沿时发生中断,使用时钟中断(2-3微妙发生一次),RDD端进行数据采样;RCP下降沿时关闭时钟中断,根据RDD数据采样计算最终数据,将数据保存至共享的内存空间,以便磁卡驱动来读取数据
思路二:[/i][/b][/i][/b]
A. CLS下降沿时发生中断,置位计数器为0,以便记录最终得到数据量(以bit为单位);上升沿时结束中
B.RCP上升沿时发生中断,使用while语句以轮询方式,采样RDD段的数据;RCP下降沿时,根据RDD数据采样计算最终数据,将数据保存至共享的内存空间,以便磁卡驱动来读取数据
4、实现步骤:
1)、CLS端中断机制的建立,
2)、RCP端中断机制的建立
3)、时钟中断机制的建立(暂时忽略,数据采样工作在RCP上升沿发生中断时进行一次)
5、具体实现方法:
比较觉得:思路二轮询采样RDD数据线的方式不合适,其效率比较低,并且,对于采样的时机比较难把握,因此思路一[/i][/b]成为首选方案。按照思路一,已经实现磁卡的读写功能。
1)、中断机制的建立:
a. BSP中定义中断的逻辑值。如:wince60/PlatForm/XXX/src/inc/bsp_cfg.h中添加定义
#define SYSINTR_MYINTR (SYSINTR_FIRMWARW+23)
b. 在BSP的OAL层intr.c文件中,添加具体的物理中断的定义以及中断处理代码。
根据硬件连接情况及资料得知,需要将相关中断是作为IRQ_GPIOXX_2的子中断进行处理。在XXX/SoC/PXA310…/OAL/INTR/intr.c中,IRQ_GPIOXX_2的相关处理会调用到XXX/ src /oal/oallib/intr.c中的中断处理函数BSPIntrActiveIrq()(该函数会返回对应得物理中断号)、BSPIntrDisableIrq()、BSPIntrDoneIrq()、BSPIntrEnableIrq()、BSPIntrInit()、BSPIntrRequestIrqs()等。因此,在XXX/ src /oal/oallib/intr.c中添加相应得物理中断的定义和处理代码,如:
#define IRQ_GPIO55_MCARD_CLS_R (IRQ_MONAHANS_MAX + 17)
需要注意的是,定义物理中断号的同时,不要忘记修改IRQ_XXX_GPIO_MAX等的定义,至于具体实现操作的代码,就是根据需要来修改了。
c. 修改OEMInterruptHandler()函数对应逻辑中断和物理中断
在这里添加的这个中断GPIO55_R的物理中断号,就是用于在读卡结束时(GPIO55号引脚回有上升沿的跳变),对应逻辑中断SYSINTR_MYINTR,唤起相应的中断程序。对于逻辑中断和物理中断的对应,是由XXX/SoC/PXA310…/OAL/INTR/intr.c中的OEMInterruptHandler()函数来完成的,它会调用BSPIntrActiveIrq(),然后,根据返回的物理中断值来修改sysIntr值。
[小结]:如果一切顺利,那么,到此有关于由IRQ_GPIOXX_2的子中断引起的中断机制就建立完毕了,重新编译生成新的nk.bin就可以了。该中断与非IRQ_GPIOXX_2的中断相比可能会麻烦一些。对于非IRQ_GPIOXX_2的中断,直接在XXX/SoC/PXA310…/OAL/INTR/intr.c文件中修改代码即可。
2)、用户层对内核数据的使用:
a.对于数据的读取,是在RCP引脚的发生跳变的时候进行的,因此,代码是写在XXX/ src /oal/oallib/intr.c中的,在RCP
引脚发生中断时,读数据、并将数据保存下来,以便读卡结束时驱动层可以读到数据。具体读数据的函数代码如下:(一共有三个磁道需要分别读写数据、进行保存,每个磁道的物理特性不同)
void ReadDataFromRDD(UINT32 XLLP_GPIO_BIT_RDD)
{
switch(XLLP_GPIO_BIT_RDD){
case XLLP_GPIO_BIT_CIF_DD5:
if (g_bitIndex1 == MAX_BIT_NUMBER)// MAX_BIT_NUMBER=8
{
g_bitIndex1 = 0;
g_byteIndex1 += 1;
}
if (g_byteIndex1 > MAX_BYTE_NUMBER)// MAX_BYTE_NUMBER=1024
{
return;
}
if (g_pGPIORegs->gplr1 & XLLP_GPIO_BIT_RDD)//读数据寄存器的值
{
g_chBuf1[g_byteIndex1] &= ~(1<<g_bitIndex1); //三个磁道使用的均是负逻辑
}
else
{
g_chBuf1[g_byteIndex1] |= (1 << g_bitIndex1);
}
g_bitIndex1++;
break;
//data type is tract2
case XLLP_GPIO_BIT_CIF_DD3:
……
break;
//data type is tract3
case XLLP_GPIO_BIT_CIF_DD1:
……
break;
default:
break;
}
return;
}
b.使用KernelIoControl ()来完成数据由OAL层向驱动层的传输。
(有些东西具体什么作用不是很清楚,都是是仿照现有BSP中其他使用了KernelIoControl的代码写的)
首先,在XXX/ SRC/INC/ioctl_cfg.h文件中,宏定义一个资源号,该资源号是作为CTL_CODE的第二个参数使用的;宏定义KernelIoControl 中需要的IOControlID。如:
#define MAGNETIC_CARD_DATA_TRANS 4003
#define IOCTL_HAL_MAGNETIC_CARD_TRANS
CTL_CODE(FILE_DEVICE_HAL, (MAGNETIC_CARD_DATA_TRANS), METHOD_BUFFERED, FILE_ANY_ACCESS)
其次,在XXX/ SRC/INC/ioctl_tab.h中,添加映射,如:
{ IOCTL_HAL_MAGNETIC_CARD_TRANS, 0,OALIoCtlHalTransMagneticCardData},
最后,在XXX/ SRC/INC/ioctl.c中添加OALIoCtlHalTransMagneticCardData ()函数的具体代码
c. 使用DeviceIoControl(对应驱动层的XXX_IOControl)或者XXX_Read函数,把数据传递给用户层。
通过以上的操作,直接使用GPIO控制读取磁卡信息的功能已经实现,并且在用户层的测试程序中得到了正确的数据。我也是第一次接触中断机制、第一次从内核中读取数据,可能理解的还不是很透彻。如果有问题,还请大家指出,呵呵,不过,请不要讲一些过于极端的话(偶会被打击的失去信心的),谢谢^_^
GPIO[49:55、57]对应磁卡器的RCP[3]、RDD[3]、CLS、NPWN
2、磁卡各引脚的使用情况:
CLS 刷卡开始为下降沿,磁卡走行中保持低电频,走向结束上升沿,无磁卡走行时保持高电频
RCP记录采样频率,每半个周期的幅度为100千欧 14毫秒;620千欧 60毫秒,前半周期高电,后半周期为低频
RDD数据采样端,当采样引脚RCP为高电频(前半周期)时,该段开始采样
CLS 为共用引脚,RCP、RDD在磁卡不同的情况下分别使用1-3个不同的引脚
3、实现读取磁卡数据的思路:
思路一[/i][/b]:[/i][/i]
A.CLS下降沿时发生中断,置bit计数器为0,以便记录最终得到数据量(以bit为单位);上升沿时,返回逻辑中断向量,唤醒IST
B.RCP上升沿时发生中断,使用时钟中断(2-3微妙发生一次),RDD端进行数据采样;RCP下降沿时关闭时钟中断,根据RDD数据采样计算最终数据,将数据保存至共享的内存空间,以便磁卡驱动来读取数据
思路二:[/i][/b][/i][/b]
A. CLS下降沿时发生中断,置位计数器为0,以便记录最终得到数据量(以bit为单位);上升沿时结束中
B.RCP上升沿时发生中断,使用while语句以轮询方式,采样RDD段的数据;RCP下降沿时,根据RDD数据采样计算最终数据,将数据保存至共享的内存空间,以便磁卡驱动来读取数据
4、实现步骤:
1)、CLS端中断机制的建立,
2)、RCP端中断机制的建立
3)、时钟中断机制的建立(暂时忽略,数据采样工作在RCP上升沿发生中断时进行一次)
5、具体实现方法:
比较觉得:思路二轮询采样RDD数据线的方式不合适,其效率比较低,并且,对于采样的时机比较难把握,因此思路一[/i][/b]成为首选方案。按照思路一,已经实现磁卡的读写功能。
1)、中断机制的建立:
a. BSP中定义中断的逻辑值。如:wince60/PlatForm/XXX/src/inc/bsp_cfg.h中添加定义
#define SYSINTR_MYINTR (SYSINTR_FIRMWARW+23)
b. 在BSP的OAL层intr.c文件中,添加具体的物理中断的定义以及中断处理代码。
根据硬件连接情况及资料得知,需要将相关中断是作为IRQ_GPIOXX_2的子中断进行处理。在XXX/SoC/PXA310…/OAL/INTR/intr.c中,IRQ_GPIOXX_2的相关处理会调用到XXX/ src /oal/oallib/intr.c中的中断处理函数BSPIntrActiveIrq()(该函数会返回对应得物理中断号)、BSPIntrDisableIrq()、BSPIntrDoneIrq()、BSPIntrEnableIrq()、BSPIntrInit()、BSPIntrRequestIrqs()等。因此,在XXX/ src /oal/oallib/intr.c中添加相应得物理中断的定义和处理代码,如:
#define IRQ_GPIO55_MCARD_CLS_R (IRQ_MONAHANS_MAX + 17)
需要注意的是,定义物理中断号的同时,不要忘记修改IRQ_XXX_GPIO_MAX等的定义,至于具体实现操作的代码,就是根据需要来修改了。
c. 修改OEMInterruptHandler()函数对应逻辑中断和物理中断
在这里添加的这个中断GPIO55_R的物理中断号,就是用于在读卡结束时(GPIO55号引脚回有上升沿的跳变),对应逻辑中断SYSINTR_MYINTR,唤起相应的中断程序。对于逻辑中断和物理中断的对应,是由XXX/SoC/PXA310…/OAL/INTR/intr.c中的OEMInterruptHandler()函数来完成的,它会调用BSPIntrActiveIrq(),然后,根据返回的物理中断值来修改sysIntr值。
[小结]:如果一切顺利,那么,到此有关于由IRQ_GPIOXX_2的子中断引起的中断机制就建立完毕了,重新编译生成新的nk.bin就可以了。该中断与非IRQ_GPIOXX_2的中断相比可能会麻烦一些。对于非IRQ_GPIOXX_2的中断,直接在XXX/SoC/PXA310…/OAL/INTR/intr.c文件中修改代码即可。
2)、用户层对内核数据的使用:
a.对于数据的读取,是在RCP引脚的发生跳变的时候进行的,因此,代码是写在XXX/ src /oal/oallib/intr.c中的,在RCP
引脚发生中断时,读数据、并将数据保存下来,以便读卡结束时驱动层可以读到数据。具体读数据的函数代码如下:(一共有三个磁道需要分别读写数据、进行保存,每个磁道的物理特性不同)
void ReadDataFromRDD(UINT32 XLLP_GPIO_BIT_RDD)
{
switch(XLLP_GPIO_BIT_RDD){
case XLLP_GPIO_BIT_CIF_DD5:
if (g_bitIndex1 == MAX_BIT_NUMBER)// MAX_BIT_NUMBER=8
{
g_bitIndex1 = 0;
g_byteIndex1 += 1;
}
if (g_byteIndex1 > MAX_BYTE_NUMBER)// MAX_BYTE_NUMBER=1024
{
return;
}
if (g_pGPIORegs->gplr1 & XLLP_GPIO_BIT_RDD)//读数据寄存器的值
{
g_chBuf1[g_byteIndex1] &= ~(1<<g_bitIndex1); //三个磁道使用的均是负逻辑
}
else
{
g_chBuf1[g_byteIndex1] |= (1 << g_bitIndex1);
}
g_bitIndex1++;
break;
//data type is tract2
case XLLP_GPIO_BIT_CIF_DD3:
……
break;
//data type is tract3
case XLLP_GPIO_BIT_CIF_DD1:
……
break;
default:
break;
}
return;
}
b.使用KernelIoControl ()来完成数据由OAL层向驱动层的传输。
(有些东西具体什么作用不是很清楚,都是是仿照现有BSP中其他使用了KernelIoControl的代码写的)
首先,在XXX/ SRC/INC/ioctl_cfg.h文件中,宏定义一个资源号,该资源号是作为CTL_CODE的第二个参数使用的;宏定义KernelIoControl 中需要的IOControlID。如:
#define MAGNETIC_CARD_DATA_TRANS 4003
#define IOCTL_HAL_MAGNETIC_CARD_TRANS
CTL_CODE(FILE_DEVICE_HAL, (MAGNETIC_CARD_DATA_TRANS), METHOD_BUFFERED, FILE_ANY_ACCESS)
其次,在XXX/ SRC/INC/ioctl_tab.h中,添加映射,如:
{ IOCTL_HAL_MAGNETIC_CARD_TRANS, 0,OALIoCtlHalTransMagneticCardData},
最后,在XXX/ SRC/INC/ioctl.c中添加OALIoCtlHalTransMagneticCardData ()函数的具体代码
c. 使用DeviceIoControl(对应驱动层的XXX_IOControl)或者XXX_Read函数,把数据传递给用户层。
通过以上的操作,直接使用GPIO控制读取磁卡信息的功能已经实现,并且在用户层的测试程序中得到了正确的数据。我也是第一次接触中断机制、第一次从内核中读取数据,可能理解的还不是很透彻。如果有问题,还请大家指出,呵呵,不过,请不要讲一些过于极端的话(偶会被打击的失去信心的),谢谢^_^
相关文章推荐
- Oracle DBA的神器: PRM恢复工具,可脱离Oracle软件运行,直接读取Oracle数据文件中的数据
- 内存中数据输出到stdout, ffmpeg如何直接读取stdio
- 如何在github里面上传代码和数据,这样R语言就可以直接读取了导入了
- VS2010环境下连续可控制的读取Excel文件中数据
- 用C#编程从数据库中读取图片数据导进Excel文件的方法(如何从数据库中读取保存的文件,直接打开,中间不保存到本地)
- Cximage 库使用,直接读取图像数据到内存。
- dsp控制DM9000实现802.3数据收发第三篇,调试过程程序第二版;接受部分可用,但是容易掉帧,采用的读取dm9000中断寄存器的方式获取数据
- Java从控制台中读取数据的各种方法
- [转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)
- Oracle DBA的神器: PRM恢复工具,可脱离Oracle软件运行,直接读取Oracle数据文件中的数据
- 使用GetDIBits直接读取位图数据
- 第三章数程序设计初步--控制结构综合项目4-1文件操作初体验练习1从文件读取数据
- 直接用SQL语句读取几种常见的文件格式中的数据
- Java从控制台中读取数据完全攻略
- Spark Streaming +Kafka 使用底层API直接读取Kafka的Partition数据,手动更新Offset到Zookeeper集群
- HBASE-11425 直接从offheap读取数据
- Java从控制台中读取数据完全攻略
- 地磅称量系统之(37~39) 直接向数据库的数据表WtBill添加测试数据以及绑定用户控件和使用编码的方式控制dataGridView控件的每列属性和添加数据数据库的表中不存在的字段(非绑定列)
- python mysql 插入的数据是字典时,可以直接插入到数据库,不要进行for循环读取每一个字段
- asp.net---代码读取处理数据与JQuery控制