wince下GPIO的的访问
2010-12-02 13:07
162 查看
因为在WINCE下能够直接访问的都是虚拟地址,不能直接访问GPIO端口,因此我们首先需要将GPIO口的物理地址映射到虚拟地址上来。
用下面的函数,就可以对他们进行分配:
volatile S3C2440A_IOPORT_REG *v_pIOPregs ;
BOOL mInitialized;
bool InitializeAddresses(VOID); // Virtual allocation
bool InitializeAddresses(VOID)
{
bool RetValue = TRUE;
/* IO Register Allocation */
v_pIOPregs = (volatile S3C2440A_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL)
{
ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc faiGPIO!/r/n")));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8),
sizeof (S3C2440A_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy faiGPIO!/r/n")));
RetValue = FALSE;
}
}
if (!RetValue)
{
if (v_pIOPregs)
{
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
}
return(RetValue);
}
下面简单学习下,这个函数,方便以后查阅。
一般都是通过使用VirtualAlloc和VirtualCopy这两个函数来完成映射。
VirtualAlloc():首先会从我们的虚拟地址空间中申请或者预留一块虚拟地址空间,准备接下来要用它,注意,物理内存并没有减少,只是虚拟地址少了一块可用的区域。
VirtualCopy():负责把一段物理内存和虚拟内存帮定,这样,最终对物理内存的访问还是通过虚拟地址的进行。
VirtualFree():如果申请内存失败的话,要通过该函数进行释放,负责内存泄露。
如果VirtualAlloc()函数执行成功的话,它讲返回一个指针( v_pIOPregs),通过该指针,就可以来对GPIO来进行操作,如:
DWORD GIO_Init(DWORD dwContext)
{
RETAILMSG(1,(TEXT("GPIO Initialize ...")));
if (!InitializeAddresses())
return (FALSE);
v_pIOPregs->GPBCON = (v_pIOPregs->GPBCON &~(3 << 10)) | (1<< 10); // GPB5 == OUTPUT.
v_pIOPregs->GPBCON = (v_pIOPregs->GPBCON &~(3 << 12)) | (1<< 12); // GPB6 == OUTPUT.
v_pIOPregs->GPBCON = (v_pIOPregs->GPBCON &~(3 << 14)) | (1<< 14); // GPB7 == OUTPUT.
v_pIOPregs->GPBCON = (v_pIOPregs->GPBCON &~(3 << 16)) | (1<< 16); // GPB8 == OUTPUT.
mInitialized = TRUE;
RETAILMSG(1,(TEXT("OK !!!/n")));
return TRUE;
}
另外为什么是这种用法呢( v_pIOPregs->GPBCON)?我们可以在F:/WINCE500/PLATFORM/S3C2440/Src/Inc的目录下找到一s3c2440a_ioport.h文件,打开可以找到:S3C2440A_IOPORT_REG
typedef struct {
UINT32 GPACON; // Port A - offset 0
UINT32 GPADAT; // Data
UINT32 PAD1[2];
UINT32 GPBCON; // Port B - offset 0x10
UINT32 GPBDAT; // Data
UINT32 GPBDN; // Pull-down disable
UINT32 PAD2;
UINT32 GPCCON; // Port C - offset 0x20
UINT32 GPCDAT; // Data
UINT32 GPCDN; // Pull-down disable
UINT32 PAD3;
UINT32 GPDCON; // Port D - offset 0x30
UINT32 GPDDAT; // Data
UINT32 GPDDN; // Pull-down disable
UINT32 PAD4;
UINT32 GPECON; // Port E - offset 0x40
UINT32 GPEDAT; // Data
UINT32 GPEDN; // Pull-down disable
UINT32 PAD5;
UINT32 GPFCON; // Port F - offset 0x50
UINT32 GPFDAT;
UINT32 GPFDN;
UINT32 PAD6;
UINT32 GPGCON; // Port G - offset 0x60
UINT32 GPGDAT;
UINT32 GPGDN;
UINT32 PAD7;
UINT32 GPHCON; // Port H - offset 0x70
UINT32 GPHDAT;
UINT32 GPHDN;
UINT32 PAD8;
UINT32 MISCCR; // misc control reg - offset 0x80
UINT32 DCLKCON; // DCLK0/1 control reg
UINT32 EXTINT0; // external interrupt control reg 0
UINT32 EXTINT1; // external interrupt control reg 1
UINT32 EXTINT2; // external interrupt control reg 2
UINT32 EINTFLT0; // reserved
UINT32 EINTFLT1; // reserved
UINT32 EINTFLT2; // external interrupt filter reg 2
UINT32 EINTFLT3; // external interrupt filter reg 3
UINT32 EINTMASK; // external interrupt mask reg
UINT32 EINTPEND; // external interrupt pending reg
UINT32 GSTATUS0; // external pin status
UINT32 GSTATUS1; // chip ID
UINT32 GSTATUS2; // reset status
UINT32 GSTATUS3; // inform register
UINT32 GSTATUS4; // inform register
UINT32 FLTOUT; // C0 - added by simon
UINT32 DSC0;
UINT32 DSC1;
UINT32 MSLCON;
UINT32 GPJCON; // D0
UINT32 GPJDAT;
UINT32 GPJDN;
UINT32 PDA9;
} S3C2440A_IOPORT_REG, *PS3C2440A_IOPORT_REG;
S3C2440A_IOPORT_REG就是个结构体数组,而他又定义了一个指定变量volatile S3C2440A_IOPORT_REG *v_pIOPregs,一次可以通过*v_pIOPregs它来访问GPIO了。
补习c语言结构体数组知识:
volatile S3C2440A_IOPORT_REG *v_pIOPregs;
volatile PS3C2440A_IOPORT_REG v_pIOPregs;
这样定义结构体是有区别的。
前者用的时候可以为:v_pIOPregs->GPACON 或者为(*v_pIOPregs).GPACON.
后者只能为:v_IOPregs.GPACON;
用下面的函数,就可以对他们进行分配:
volatile S3C2440A_IOPORT_REG *v_pIOPregs ;
BOOL mInitialized;
bool InitializeAddresses(VOID); // Virtual allocation
bool InitializeAddresses(VOID)
{
bool RetValue = TRUE;
/* IO Register Allocation */
v_pIOPregs = (volatile S3C2440A_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL)
{
ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc faiGPIO!/r/n")));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8),
sizeof (S3C2440A_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy faiGPIO!/r/n")));
RetValue = FALSE;
}
}
if (!RetValue)
{
if (v_pIOPregs)
{
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
}
return(RetValue);
}
下面简单学习下,这个函数,方便以后查阅。
一般都是通过使用VirtualAlloc和VirtualCopy这两个函数来完成映射。
VirtualAlloc():首先会从我们的虚拟地址空间中申请或者预留一块虚拟地址空间,准备接下来要用它,注意,物理内存并没有减少,只是虚拟地址少了一块可用的区域。
VirtualCopy():负责把一段物理内存和虚拟内存帮定,这样,最终对物理内存的访问还是通过虚拟地址的进行。
VirtualFree():如果申请内存失败的话,要通过该函数进行释放,负责内存泄露。
如果VirtualAlloc()函数执行成功的话,它讲返回一个指针( v_pIOPregs),通过该指针,就可以来对GPIO来进行操作,如:
DWORD GIO_Init(DWORD dwContext)
{
RETAILMSG(1,(TEXT("GPIO Initialize ...")));
if (!InitializeAddresses())
return (FALSE);
v_pIOPregs->GPBCON = (v_pIOPregs->GPBCON &~(3 << 10)) | (1<< 10); // GPB5 == OUTPUT.
v_pIOPregs->GPBCON = (v_pIOPregs->GPBCON &~(3 << 12)) | (1<< 12); // GPB6 == OUTPUT.
v_pIOPregs->GPBCON = (v_pIOPregs->GPBCON &~(3 << 14)) | (1<< 14); // GPB7 == OUTPUT.
v_pIOPregs->GPBCON = (v_pIOPregs->GPBCON &~(3 << 16)) | (1<< 16); // GPB8 == OUTPUT.
mInitialized = TRUE;
RETAILMSG(1,(TEXT("OK !!!/n")));
return TRUE;
}
另外为什么是这种用法呢( v_pIOPregs->GPBCON)?我们可以在F:/WINCE500/PLATFORM/S3C2440/Src/Inc的目录下找到一s3c2440a_ioport.h文件,打开可以找到:S3C2440A_IOPORT_REG
typedef struct {
UINT32 GPACON; // Port A - offset 0
UINT32 GPADAT; // Data
UINT32 PAD1[2];
UINT32 GPBCON; // Port B - offset 0x10
UINT32 GPBDAT; // Data
UINT32 GPBDN; // Pull-down disable
UINT32 PAD2;
UINT32 GPCCON; // Port C - offset 0x20
UINT32 GPCDAT; // Data
UINT32 GPCDN; // Pull-down disable
UINT32 PAD3;
UINT32 GPDCON; // Port D - offset 0x30
UINT32 GPDDAT; // Data
UINT32 GPDDN; // Pull-down disable
UINT32 PAD4;
UINT32 GPECON; // Port E - offset 0x40
UINT32 GPEDAT; // Data
UINT32 GPEDN; // Pull-down disable
UINT32 PAD5;
UINT32 GPFCON; // Port F - offset 0x50
UINT32 GPFDAT;
UINT32 GPFDN;
UINT32 PAD6;
UINT32 GPGCON; // Port G - offset 0x60
UINT32 GPGDAT;
UINT32 GPGDN;
UINT32 PAD7;
UINT32 GPHCON; // Port H - offset 0x70
UINT32 GPHDAT;
UINT32 GPHDN;
UINT32 PAD8;
UINT32 MISCCR; // misc control reg - offset 0x80
UINT32 DCLKCON; // DCLK0/1 control reg
UINT32 EXTINT0; // external interrupt control reg 0
UINT32 EXTINT1; // external interrupt control reg 1
UINT32 EXTINT2; // external interrupt control reg 2
UINT32 EINTFLT0; // reserved
UINT32 EINTFLT1; // reserved
UINT32 EINTFLT2; // external interrupt filter reg 2
UINT32 EINTFLT3; // external interrupt filter reg 3
UINT32 EINTMASK; // external interrupt mask reg
UINT32 EINTPEND; // external interrupt pending reg
UINT32 GSTATUS0; // external pin status
UINT32 GSTATUS1; // chip ID
UINT32 GSTATUS2; // reset status
UINT32 GSTATUS3; // inform register
UINT32 GSTATUS4; // inform register
UINT32 FLTOUT; // C0 - added by simon
UINT32 DSC0;
UINT32 DSC1;
UINT32 MSLCON;
UINT32 GPJCON; // D0
UINT32 GPJDAT;
UINT32 GPJDN;
UINT32 PDA9;
} S3C2440A_IOPORT_REG, *PS3C2440A_IOPORT_REG;
S3C2440A_IOPORT_REG就是个结构体数组,而他又定义了一个指定变量volatile S3C2440A_IOPORT_REG *v_pIOPregs,一次可以通过*v_pIOPregs它来访问GPIO了。
补习c语言结构体数组知识:
volatile S3C2440A_IOPORT_REG *v_pIOPregs;
volatile PS3C2440A_IOPORT_REG v_pIOPregs;
这样定义结构体是有区别的。
前者用的时候可以为:v_pIOPregs->GPACON 或者为(*v_pIOPregs).GPACON.
后者只能为:v_IOPregs.GPACON;
相关文章推荐
- Wince 下GPIO的访问方法
- 转WINCE对物理地址的访问
- AT91SAM9263 WINCE 6.0 R2驱动开发-GPIO流驱动的实现以及应用程序的调用
- WinCE下使用GPIO中断功能
- WinCE下访问物理地址
- WM/WinCE 下访问Sqlite的Native C++封装 (CppSQLite3U的使用)
- (转)c#(wince)中使用多线程访问winform中控件的问题
- 介绍一种很棒的wince驱动调试方法——在wince应用程序中直接访问硬件
- WinCE下访问Nand Flash接口
- WinCE 下进程可访问的代码页的地址获取
- wince下Gpio 驱动程序
- 【EmbeddedDev】通过mmap方法访问ADC/GPIO
- WinCE下的GPIO中断的处理
- 2440 WinCE操作GPIO
- WinCE 下进程可访问的代码页的地址获取
- WINCE 对物理地址的访问
- 解决wince与主机webservice的连接和访问问题?webservice的IIS发布问题?
- wince下访问io端口的经验
- 用ARM9 2440的GPIO口实现与温湿度传感器(AM2302)的单总线通信! WINCE 分享一下心得
- WinCE下的GPIO中断的处理