WINCE驱动开发-寄存器的使用

WINCE驱动开发-寄存器的使用

 

一:寄存器的使用:

1、wince内部对物理地址的访问:

可以有3个途径。

1:直接使用g_oalAddressTable(oemaddrtab_cfg.inc)的已经定义好的,物理地址对应的虚拟地址。

如:

DCD     0x80000000, 0x30000000, 128     ;

访问虚拟地址0x80000000实际就是访问物理地址0x30000000。

 

2:在OAL层,使用OALPAtoVA函数。

如:

volatile S3C2410X_IOPORT_REG *pIOCTR;

pIOCTR = (volatile S3C2410X_IOPORT_REG *)OALPAtoVA(S3C2410X_BASE_REG_PA_IOPORT, FALSE);

那么在访问pIOCTR指向的首地址,实际就是访问被映射后S3C2410X_BASE_REG_PA_IOPORT定义的物理地址。

VOID* OALPAtoVA( 
    UINT32 pa,                         参数1:需要映射的物理地址
    BOOL cached                            参数2:是否使用cache(驱动中要使用uncached)

)

 

3:在kernel里,使用MmMapIoSpace函数。

如:

pBaseAddress = (PUCHAR)MmMapIoSpace(ioPhysicalBase, Size, FALSE);

同上,访问pBaseAddress的指向地址,就为访问被映射后ioPhysicalBase定义的物理地址。

PVOID MmMapIoSpace( 
    PHYSICAL_ADDRESS PhysicalAddress,     参数1:需要映射的物理地址
    ULONG NumberOfBytes,                   参数2:映射的地址长度
    BOOLEAN CacheEnable                    参数3:是否使用cache(驱动中要使用uncached)

);

与OALPAtoVA不同,在使用MmMapIoSpace后,必须使用MmUnmapIoSpace。

  VOID MmUnmapIoSpace( 
   PVOID BaseAddress,                      参数1:被映射后的虚拟地址
   ULONG NumberOfBytes                     参数2:映射的地址长度

);

 

在一般的NK驱动编写中,为了规范编程风格,请勿直接使用g_oalAddressTable中的虚拟地址。统一使用MmMapIoSpace、MmUnmapIoSpace函数。

 

2、wince标准的寄存器访问

定义一个结构体。此结构包含某功能模块的寄存器地址。

如:

typedef struct {

    UINT32 GPACON;                  // Port A - offset 0

    UINT32 GPADAT;                  // Data

    UINT32 PAD1[2];

        ……

        ……

    UINT32 GSTATUS0;                // external pin status

    UINT32 GSTATUS1;                // chip ID

    UINT32 GSTATUS2;                // reset status

    UINT32 GSTATUS3;                // inform register

    UINT32 GSTATUS4;                // inform register

   

} S3C2410X_IOPORT_REG, *PS3C2410X_IOPORT_REG; 

 

volatile S3C2410X_IOPORT_REG *pIOCTR;

pIOCTR = (volatile S3C2410X_IOPORT_REG *)OALPAtoVA(S3C2410X_BASE_REG_PA_IOPORT, FALSE);

这样,访问pIOCTR的各个成员,就为访问被映射后S3C2410X_BASE_REG_PA_IOPORT定义的物理偏移地址。

 

为了统一、兼容平台的驱动代码,我们加入了寄存器操作宏(oal_io.h):

#define REG8(_register_)    (*(volatile unsigned char  *)(_register_))

#define REG16(_register_)   (*(volatile unsigned short *)(_register_))

#define REG32(_register_)   (*(volatile unsigned long *)(_register_))

       访问模块中的功能寄存器,使用加上偏移地址的方式。

#define USB_REG_FADDR_OFFSET             (0x0000)

#define USB_REG_POWER_OFFSET             (0x0001)

      

      

       例子:

要编写某个模块的驱动,首先使用MmMapIoSpace或OALPAtoVA建立物理地址映射关系。

volatile BYTE *pUSBCtrlAddr;

       pUSBCtrlAddr= (volatile BYTE *)OALPAtoVA(AK3224_BASE_REG_PA_USB, FALSE);

这样,usb模块的首地址就为pUSBCtrlAddr的指向地址。然后,使用REGXX的宏来访问各个功能寄存器。

       REG8(pUSBCtrlAddr + USB_REG_POWER_OFFSET) = USB_POWER_ENSUSPEND;

ucIntStatusR  =  REG16(pUSBCtrlAddr + USB_REG_INTRRX1_OFFSET);

REG32(pUSBCtrlAddr + USB_DMA_COUNT_1_OFFSET) = 256;

你可能感兴趣的:(c,cache,struct,byte,WinCE,PS3)