S3C2410-GPIO驱动(WINCE)

    

    在WINCE下能够直接访问的都是虚拟地址,不能直接访问GPIO端口,因此首先需要使用VirtualAlloc和VirtualCopy这两个函数将GPIO口的物理地址映射到虚拟地址上来。

   函数原型分别是: 

LPVOID VirtualAlloc( LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect ); 
BOOL VirtualCopy( LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect ); 

   如果这两个函数执行成功,VirtualAlloc将返回一个指针。使用这个指针就可以直接访问GPIO,通过读写相关地址寄存器,来控制GPIO端口! 
   
v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS); 
if (v_pIOPregs == NULL){ 
          RetValue = FALSE; 
} 
else { 
      if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE)) { 
          RetValue = FALSE; 
      } 
 } 
     if (!RetValue){ 
                    //PIO_InitializeAddresses - Failed !! 
          if (v_pIOPregs){ 
                             VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE); 
                    } 
                    v_pIOPregs = NULL; 
          } 
          //else RETAILMSG (1, (TEXT("::: PBT_InitializeAddresses - Success\r\n") )); 
          return(RetValue); 

v_pIOPregs是一个IOPreg结构,在s2410.h中定义, 
// Registers : I/O port 
#define IOP_BASE       0xB1600000 // 0x56000000 
typedef struct   { 
     unsigned int   rGPACON;                   // 00 
     unsigned int   rGPADAT; 
     unsigned int   rPAD1[2]; 
     
     unsigned int   rGPBCON;                   // 10 
     unsigned int   rGPBDAT; 
     unsigned int   rGPBUP; 
     unsigned int   rPAD2; 
     
     unsigned int   rGPCCON;                   // 20 
     unsigned int   rGPCDAT; 
     unsigned int   rGPCUP; 
     unsigned int   rPAD3; 
     
     unsigned int   rGPDCON;                   // 30 
     unsigned int   rGPDDAT; 
     unsigned int   rGPDUP; 
     unsigned int   rPAD4; 
     
     unsigned int   rGPECON;                   // 40 
     unsigned int   rGPEDAT; 
     unsigned int   rGPEUP; 
     unsigned int   rPAD5; 
     
     unsigned int   rGPFCON;                    // 50 
     unsigned int   rGPFDAT; 
     unsigned int   rGPFUP; 
     unsigned int   rPAD6; 
     
     unsigned int   rGPGCON;                   // 60 
     unsigned int   rGPGDAT; 
     unsigned int   rGPGUP; 
     unsigned int   rPAD7; 
     
     unsigned int   rGPHCON;                   // 70 
     unsigned int   rGPHDAT; 
     unsigned int   rGPHUP; 
     unsigned int   rPAD8; 
     
     unsigned int   rMISCCR;                  // 80 
     unsigned int   rDCKCON;                   
     unsigned int   rEXTINT0; 
     unsigned int   rEXTINT1;                    
     unsigned int   rEXTINT2;                 // 90 
     unsigned int   rEINTFLT0; 
     unsigned int   rEINTFLT1; 
     unsigned int   rEINTFLT2; 
     unsigned int   rEINTFLT3;                 // A0 
     unsigned int   rEINTMASK; 
     unsigned int   rEINTPEND; 
     unsigned int   rGSTATUS0; 
     unsigned int   rGSTATUS1;                 // B0 
}IOPreg;  

 4.2BSP按键驱动的例子:

/* IO Register Allocation */
v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL) 
{
   ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
   RetValue = FALSE;
}
else 
{
   if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE)) 
   {
    ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n")));
    RetValue = FALSE;
   }
}


在VirtualCopy的IOP_BASE是个虚拟地址

#define IOP_BASE      0xB1600000 // 0x56000000

但是在5.0BSP却不一样

v_pIOPregs = (volatile S3C2440A_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2440A_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE );

S3C2440A_BASE_REG_PA_IOPORT 是个物理地址

#define S3C2440A_BASE_REG_PA_IOPORT             (0x56000000)     

This function dynamically maps a virtual address to a physical address by creating a new page-table entry. Terminate the mapping by calling .

BOOL VirtualCopy( 
LPVOID , 
LPVOID , 
DWORD , 
DWORD  
);
Parameters
lpvDest
[in] Pointer to the destination memory, which must be reserved.
lpvSrc
[in] Pointer to committed memory.
cbSize
[in] Size, in bytes, of the region. The allocated pages include all pages containing one or more bytes in the range from lpAddress to lpAddress+cbSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.

fdwProtect
[in] Type of access protection. If the pages are being committed, any one of a number of flags can be specified, along with the PAGE_GUARD and PAGE_NOCACHE, protection modifier flags. The following table shows the flags that can be specified.
ValueDescription
PAGE_READONLY Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE Enables both read and write access to the committed region of pages.
PAGE_EXECUTE Enables execution access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE Enables execute, read, and write access to the committed region of pages.
PAGE_GUARD Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the operating system to raise the STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

The PAGE_GUARD flag is a page protection modifier. An application uses it with one of the other page protection flags, with one exception: it cannot be used with PAGE_NOACCESS.

When an access attempt leads the operating system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.

PAGE_NOACCESS Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as no cache. It is useful for device drivers; when, for example, mapping a video frame buffer with no caching. This flag is a page protection modifier and is valid only when used with one of the page protections other than PAGE_NOACCESS.
PAGE_PHYSICAL Used to map a physical memory region. When using this flag, divide the physical address — that is, lpvSrc — by 256. Memory mapped with PAGE_PHYSICAL is not freed until the device is rebooted. Calling VirtualFree will not free this mapped physical memory. PAGE_PHYSICAL is intended for use with dedicated hardware buffers, so it cannot be freed after being mapped.


      PAGE_PHYSICAL这个参数决定了要右移八位(除以256)。不过还有一点就是使用了PAGE_PHYSICAL之后就不要使用VirtualFree .

 

VirtualAlloc

This function reserves or commits a region of pages in the virtual address space of the calling process.

Memory allocated by VirtualAlloc is initialized to zero.

LPVOID VirtualAlloc(
LPVOID , 
DWORD , 
DWORD , 
DWORD  
);
Parameters
lpAddress
[in] Long pointer to the specified starting address of the region to be allocated.

If the memory is being reserved, the specified address is rounded down to the next 64-KB boundary.

If the memory is reserved and is being committed, the address is rounded down to the next page boundary.

To determine the size of a page on the host computer, use the function.

If this parameter is NULL, the system determines where to allocate the region.

dwSize
[in] Specifies the size, in bytes, of the region. It is an error to set this parameter to 0.

If the lpAddress parameter is NULL, this value is rounded up to the next page boundary.

Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpAddress to lpAddress+dwSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.

flAllocationType
[in] Specifies the type of allocation.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值