当前位置:首页 > 实验二线程同步调试实验
嵌入式操作系统实验指导书
实验六 IO接口控制实验之七段数码
管和LED显示实验
[实验目的]
1、掌握在Windows CE下访问硬件I/O寄存器的一般方法; 2、了解WinCE下IO访问机制和原理; 3、了解数码管(LED)的显示及控制原理; 4、熟悉EVC和VS.Net的使开发环境;
[实验仪器]
1、装有Platform Builder、EVC和VS.Net开发平台的PC机一台 2、XSBase270实验开发平台一套
[实验原理]
1、硬件接口电路分析
XSBase目标板LED和七段数码显示接口电路如图6-1所示,74HC574为D锁存器,在时钟信号CLK作用下,该锁存器将输入信号进行锁存,即xQ=xD(x=1~8)。从电路图中可以看出,LED和八段数码显示电路将74HC574的时钟信号输入端作为片选信号,其中LED显示的片选信号为LED_CS4、七段数码显示的片选信号为LED_CS1(另外还有2组七段数码显示未画出,参考原理图)。在七段数码显示电路中,数据的高位(D7、D15:即数码管的小数点dp段)用作七段数码的公共选通信号,通过控制PNP三极管来控制数码管的显示。
嵌入式操作系统实验指导书
图6-1 LED和七段数码显示接口电路
显示电路中的片选信号LED_CSx(x=1-4),由XSBase270目标板系统的处理器PXA270x 的地址信号BA22~BA20通过3-8译码器LC138产生(如图2-2所示)。
图 6-2 片选信号产生电路
由3-8控制功能可知,当BA22、BA21、BA20=101时产生LED显示电路的片选信号LED_CS4,当BA22、BA21、BA20=010、011、100时分别产生七段数码显示电路的片选信号LED_CS1、LED_CS2、LED_CS3(另外2组八段显示电路参考系统提供的总电路图)。根据分析,可以得出七段数码管和LED的片选信号为:LED_CS1=0x10200000、LED_CS2
嵌入式操作系统实验指导书
=0x10300000、LED_CS3=0x10400000,LED_CS4=0x10500000。
2、Windows CE下访问物理地址的方法
2.1 虚拟内存函数介绍
IO接口属于XScale处理器的外部设备,类似于通常所使用的PC的串口、并口或者PC喇叭。对于一般单片机,可以直接操作硬件,即通过直接读写IO端口来访问硬件。而对于Windows CE操作系统,不允许直接访问硬件,尽管知道物理地址,我们仍不能直接访问它,因此必须使用特殊的方法来访问硬件。
Windows CE操作系统出于稳定性和安全的要求,屏蔽了用户应用程序对硬件访问的权限,只有内核应用程序才可以访问硬件资源。如果要直接访问某一个地址的物理内存,可以采用内存映射的方法,将该硬件寄存器映射到普通的内存空间,像操作内存地址一样操作硬件寄存器。Windows CE提供了VirtualAlloc()和VirtualCopy()函数,VirtualAlloc负责在虚拟内存空间内保留一段虚拟内存,而VirtualCopy负责把一段物理内存和虚拟内存绑定,这样,最终对物理内存的访问还是通过虚拟地址进行。下面简单介绍这些函数的作用和使用方法。
VirtualAlloc()函数用于分配一块内存空间。如果要映射一个硬件寄存器,必然要将其映射到一块确定的内存空间。在这里我们分配一个内存空间。这个内存空间并不占用实际内存空间,而是留待后面进行分配。
VirtualAlloc()函数原型为: LPVOID VirtualAlloc( LPVOID lpAddress, // 希望的虚拟内存起始地址 DWORD dwSize, // 以字节为单位的大小 DWORD flAllocationType, // 申请类型,分为Reserve和Commit DWORD flProtect // 访问权限 );
其参数lpAddress包含一个内存地址,用于定义待分配区域的首地址。通常可将此参数设置为NULL,由系统通过搜索地址空间来决定满足条件未保留的地址空间。这时系统可从地址空间的任意位置处开始保留一个区域。如果存在一个足够大的空闲区域,那么系统将会保留此区域并返回此保留区域的虚拟地址,否则将导致分配的失败而返回NULL。这里需要特别指出的是,在指定lpAddress的内存地址时,必须确保从分配粒度的边界处开始。
VirtualCopy()负责将硬件设备寄存器的物理地址与VirtualAlloc()分配的虚拟地址做一个映射关系,这样驱动程序访问虚拟地址即是访问对应的物理地址处的第一个寄存器。
VirtualCopy()函数原型为: BOOL VirtualCopy( LPVOID lpvDest, // 虚拟内存的目标地址 LPVOID lpvSrc, // 物理内存地址 DWORD cbSize, // 要绑定的大小 DWORD fdwProtect // 访问权限 );
由于EVC里没有提供没有VirtualCopy()的头文件和库文件(这些是由Platform Builder提供的),因此需要将它们作为外部函数调用导入。如下:
extern \__declspec(dllimport) BOOL VirtualCopy(LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect );
嵌入式操作系统实验指导书
如此调用VirtualCopy函数后,物理地址和虚拟内存空间就对应起来了。
对于分配的内存空间,虽然没有占用实际的内存空间,但是还是占用了系统的存储器地址,因此在退出程序时需要将其释放掉。使用的函数是VirtualFree()。其函数原型为:
BOOL VirtualFree(
LPVOID lpAddress, // 虚拟内存的地址 DWORD dwSize, // 释放的地址空间区域的大小 DWORD dwFreeType // 释放内存类型 ); 其中,参数lpAddress为指向待释放页面区域的指针。参数dwSize指定了要释放的地址空间区域的大小,如果参数dwFreeType指定了MEM_RELEASE标志,则将dwSize设置为0,由系统计算在特定内存地址上的待释放区域的大小。参数dwFreeType为所执行的释放操作的类型。
2.2 虚拟内存函数使用方法
首先使用VirtualAlloc分配出一个虚拟的地址空间,代码如下: VirtualAlloc(0,0x1000,MEM_RESERVE,PAGE_READWRITE)
这样就分配出一个MEM_RESERVE类型的存储器空间,它并没有占用实际内存空间,而是虚拟的地址空间。
接着将实际的硬件地址(例如LED的片选控制信号地址)映射到前面分配的虚拟地址空间,使用VirtualCopy函数建立起两个地址间的映射关系。具体代码如下:
VirtualCopy((PVOID)pLightReg,(PVOID)(pLightIoBaseAddress>>8),0x1000,PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL)
这里的pLightReg即前面分配的虚拟地址空间,而pLightIoBaseAddress为实际的硬件地址,需要将它右移8位,因为在函数中存储器分配是以256位为单位的。而后面的选项则指定了映射地址的属性——可读写、不缓冲以及硬件物理地址。
现在就可以使用虚拟地址访问原本不能直接访问的硬件地址了。在程序退出的时候,出于安全与妥善考虑,还应使用VirtualFree将已经分配的空间释放掉。实际的代码如下:
VirtualFree((PVOID) pLightReg,,0,MEM_RELEASE);
[实验内容]
1、 了解在Windows CE下访问一般硬件寄存器的方法,掌握EVC下对硬件I/O寄存器的访
问方法,以及使用EVC对硬件设备编程的一般方法。
2、 使用EVC或VS.net编写对XSBase270目标板的LED和七段数码控制程序。
[实验步骤]
第一步:连接好实验系统,打开实验箱电源。
第二步:打开对应的工程文件,我们可以看到硬件地址映射到内存的关键代码如下:
BOOL CLEDDlg::SetMemoryMap() {
if(!(v_pLEDBaseAddr1=(USHORT*)VirtualAlloc(0,0x400,MEM_RESERVE,PAGE_READWRITE))) {
MessageBox(TEXT(\ return FALSE;
共分享92篇相关文档