wang_jiayou 发表于 2013-11-19 08:54:22

S3C6410请教虚拟空间映射物理地址方法

小弟我做过wince6下6410项目,要求IO读写速度非常快,我简单写了流驱动方式发现速度慢,达不到要求,后来参考 wince.he大侠的方法搞个虚拟空间映射物理地址方法,想通过这个方法加快速度,但是总是不成功,希望高手路过小弟发帖的地方,多多的指教。我现在用到的程序:#include "stdafx.h"
#include "bsp.h"
#include <s3c6410.h>
#include <DrvLib.h>
#include <winuser.h>
#include "pkfuncs.h"
#include "BEE.h"
// GPIO virtual address
static volatile S3C6410_GPIO_REG*v_pIOPregs;

unsigned int k_value;

unsigned int l_value;
unsigned intiResult;




extern "C" _declspec(dllexport) DWORD JSJ_Init(LPCTSTR pContext, LPCVOID lpvBusContext) ;

extern "C" _declspec(dllexport) BOOL JSJ_Deinit(DWORD hDeviceContext);

extern "C" _declspec(dllexport) VOID JSJopen(BYTE num );

extern "C" _declspec(dllexport) VOID JSJclose(BYTE num );

extern "C" _declspec(dllexport) DWORD JSJ_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode);

extern "C" _declspec(dllexport) BOOL JSJ_Close(DWORD hOpenContext);


extern "C" _declspec(dllexport)BOOL JSJ_Close(DWORD hOpenContext);

extern "C" _declspec(dllexport)DWORD JSJ_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count);

extern "C" _declspec(dllexport)DWORD JSJ_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count);


extern "C" _declspec(dllexport)VOID JSJ_PowerDown(DWORD hDeviceContext);

extern "C" _declspec(dllexport)DWORD JSJ_Seek(DWORD hOpenContext, long Amount, DWORD Type);

extern "C" _declspec(dllexport)void write_kai( void );

extern "C" _declspec(dllexport)void IOW_shezhi( void );
extern "C" _declspec(dllexport)void IOW_HIGH( void );
extern "C" _declspec(dllexport)void IOW_LOW( void ) ;
extern "C" _declspec(dllexport)void IOR_shezhi( void );


extern "C" _declspec(dllexport)void IOR_HIGH(void);
extern "C" _declspec(dllexport)void IOR_LOW(void);

extern "C" _declspec(dllexport)void read_kai(void);

extern "C" _declspec(dllexport)void control_su(void);

extern "C" _declspec(dllexport)void write_configuration(void);

extern "C" _declspec(dllexport)DWORD WRITE(DWORD AD , unsigned short DATA);

extern "C" _declspec(dllexport)DWORD READ(DWORD AD , unsigned short DATA);

extern "C" _declspec(dllexport)volatile LPVOID GetVirtual(DWORD dwPhyBaseAddress, DWORD dwSize);






#define IOCTL_VIRTUAL_COPY_EX CTL_CODE (FILE_DEVICE_UNKNOWN,3333,METHOD_BUFFERED,FILE_ANY_ACCESS)

typedef struct {
      void*    pvDestMem;
      DWORD    dwPhysAddr;
      DWORD    dwSize;
}


VIRTUAL_COPY_EX_DATA;

volatile LPVOID GetVirtual(DWORD dwPhyBaseAddress, DWORD dwSize)
{
      volatile LPVOID pVirtual;
      VIRTUAL_COPY_EX_DATA vced;
      
      if(dwPhyBaseAddress&0xFFF)
      {
          return NULL;
      }
   vced.dwPhysAddr = dwPhyBaseAddress>>8;
   pVirtual = VirtualAlloc(0,dwSize,MEM_RESERVE,PAGE_NOACCESS);
   vced.pvDestMem = pVirtual;
   vced.dwSize = dwSize;
   KernelIoControl(IOCTL_VIRTUAL_COPY_EX,&vced, sizeof(vced), NULL, NULL, NULL);
   return pVirtual;
}




//----------------------------------------------------------------------------//
//        BUZZER initial                                                                                                                                                                                                                                                                //
//----------------------------------------------------------------------------//
DWORD JSJ_Init(LPCTSTR pContext, LPCVOID lpvBusContext) {
//Virtual address mapping
        //v_pIOPregs = (volatile S3C6410_GPIO_REG*)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_GPIO,
        //                                                                          sizeof(S3C6410_GPIO_REG),
        //                                                                                                                FALSE);
        PBYTE pLCDBuf = (PBYTE)GetVirtual(S3C6410_BASE_REG_PA_GPIO,sizeof(S3C6410_GPIO_REG));
   


   //memset(pLCDBuf,0,sizeof(S3C6410_GPIO_REG));
   v_pIOPregs =(volatile S3C6410_GPIO_REG*)pLCDBuf;




      v_pIOPregs->GPMCON&=(~(0x0f<<0));//SA0 判断GPM0
                v_pIOPregs->GPMCON|=(0x1<<0);
                v_pIOPregs->GPMCON&=(~(0x0f<<4));//SA1 判断   GPM1
                v_pIOPregs->GPMCON|=(0x1<<4);
                v_pIOPregs->GPMCON&=(~(0x0f<<8));//SA2 判断   GPM2
                v_pIOPregs->GPMCON|=(0x1<<8);
                v_pIOPregs->GPMCON&=(~(0x0f<<12)); //SA3 判断   GPM3
                v_pIOPregs->GPMCON|=(0x1<<12);
                v_pIOPregs->GPNCON&=(~(0x03<<0));//SA4 判断   GPN0
                v_pIOPregs->GPNCON|=(0x1<<0);
                v_pIOPregs->GPNCON&=(~(0x03<<2));//SA5 判断   GPN1
                v_pIOPregs->GPNCON|=(0x1<<2);
                v_pIOPregs->GPNCON&=(~(0x03<<4));//SA6 判断GPN2
                v_pIOPregs->GPNCON|=(0x1<<4);
                v_pIOPregs->GPNCON&=(~(0x03<<6));//SA7 判断GPN3
                v_pIOPregs->GPNCON|=(0x1<<6);
                v_pIOPregs->GPNCON&=(~(0x03<<8));//SA8 判断   GPN4
                v_pIOPregs->GPNCON|=(0x1<<8);
                v_pIOPregs->GPNCON&=(~(0x03<<10)); //SA9 判断   GPN5
                v_pIOPregs->GPNCON|=(0x1<<10);
                v_pIOPregs->GPCCON&=(~(0x0f<<8));//SA10 判断   GPC2
                v_pIOPregs->GPCCON|=(0x1<<8);




v_pIOPregs->GPKCON1&=(~(0x0f<<0));//SD0 判断GPK8
v_pIOPregs->GPKCON1&=(~(0x0f<<4));//SD1 判断GPK9
v_pIOPregs->GPKCON1&=(~(0x0f<<8));//SD2 判断GPK10
v_pIOPregs->GPKCON1&=(~(0x0f<<12)); //SD3 判断GPK11
v_pIOPregs->GPKCON1&=(~(0x0f<<16)); //SD4 判断GPK12
v_pIOPregs->GPKCON1&=(~(0x0f<<20)); //SD5 判断GPK13
v_pIOPregs->GPKCON1&=(~(0x0f<<24)); //SD6 判断GPK14
v_pIOPregs->GPKCON1&=(~(0x0f<<28)); //SD7 判断GPK15
v_pIOPregs->GPLCON0&=(~(0x0f<<0));//SD8 判断GPL0
v_pIOPregs->GPLCON0&=(~(0x0f<<4));//SD9 判断GPL1
v_pIOPregs->GPLCON0&=(~(0x0f<<8));//SD10 判断GPL2
v_pIOPregs->GPLCON0&=(~(0x0f<<12)); //SD11 判断GPL3
v_pIOPregs->GPLCON0&=(~(0x0f<<16)); //SD12 判断GPL4
v_pIOPregs->GPLCON0&=(~(0x0f<<20)); //SD13 判断GPL5
v_pIOPregs->GPLCON0&=(~(0x0f<<24)); //SD14 判断GPL6
v_pIOPregs->GPLCON0&=(~(0x0f<<28)); //SD15判断GPL7




//锁
                v_pIOPregs->GPCCON&=(~(0x0f<<24)); //地址方向设置2   A到B 置1   GPC6
                v_pIOPregs->GPCCON|=(0x1<<24);
                v_pIOPregs->GPCCON&=(~(0x0f<<20)); //地址方向设置1   A到B 置1   GPC5
                v_pIOPregs->GPCCON|=(0x1<<20);
                v_pIOPregs->GPCCON&=(~(0x0f<<16)); //数据方向 1DIR   B到A置0 GPC4
                v_pIOPregs->GPCCON|=(0x1<<16);
                v_pIOPregs->GPCCON&=(~(0x0f<<0)); //数据方向 2DIR   B到A置0 GPC0
                v_pIOPregs->GPCCON|=(0x1<<0);

   //w开

      v_pIOPregs->GPCCON&=(~(0x0f<<24)); //地址方向设置2   A到B 置1   GPC6
                v_pIOPregs->GPCCON|=(0x1<<24);
                v_pIOPregs->GPCCON&=(~(0x0f<<20)); //地址方向设置1   A到B 置1   GPC5
                v_pIOPregs->GPCCON|=(0x1<<20);
                v_pIOPregs->GPCCON&=(~(0x0f<<16)); //数据方向 1DIR   A到B置1GPC4
                v_pIOPregs->GPCCON|=(0x1<<16);
                v_pIOPregs->GPCCON&=(~(0x0f<<0)); //数据方向 2DIR   A到B置1GPC0
                v_pIOPregs->GPCCON|=(0x1<<0);

                //r开

                v_pIOPregs->GPCCON&=(~(0x0f<<24)); //地址方向设置2   A到B 置1   GPC6
                v_pIOPregs->GPCCON|=(0x1<<24);
                v_pIOPregs->GPCCON&=(~(0x0f<<20)); //地址方向设置1   A到B 置1   GPC5
                v_pIOPregs->GPCCON|=(0x1<<20);
                v_pIOPregs->GPCCON&=(~(0x0f<<16)); //数据方向 1DIR   B到A置0 GPC4
                v_pIOPregs->GPCCON|=(0x1<<16);
                v_pIOPregs->GPCCON&=(~(0x0f<<0)); //数据方向 2DIR   B到A置0 GPC0
                v_pIOPregs->GPCCON|=(0x1<<0);


      v_pIOPregs->GPCCON&=(~(0x0f<<28)); //IOR   读低电平有效   GPC7读的时候读必须置0 当前置1为下降沿 产生做准备

       v_pIOPregs->GPCCON&=(~(0x0f<<4));   //IOW   写低电平有效   GPC1写必须置0   当前置1 为产生下降沿做准备
   


        return 1;
}

//----------------------------------------------------------------------------//
//        BUZZER deinit          替换104                                                                                                                                                                                                                                                        //
//----------------------------------------------------------------------------//
BOOL JSJ_Deinit(DWORD hDeviceContext) {
        VirtualFree((PVOID)v_pIOPregs, 0, MEM_RELEASE);
        v_pIOPregs = NULL;
        return TRUE;
}

//不同点替换

VOID JSJoutputconfiguration(BYTE num ) {
v_pIOPregs->GPMCON=(v_pIOPregs->GPMCON&(~(0x0f<<num)))|0x1;

v_pIOPregs->GPNCON=(v_pIOPregs->GPNCON&(~(0x03<<num)))|0x1;//2013.7 .10

v_pIOPregs->GPCCON=(v_pIOPregs->GPCCON&(~(0x0f<<num)))|0x1;//2013.7 .10

v_pIOPregs->GPLCON0=(v_pIOPregs->GPLCON0&(~(0x0f<<num)))|0x1;//2013.7 .10

v_pIOPregs->GPKCON1=(v_pIOPregs->GPKCON1&(~(0x0f<<num)))|0x1;//2013.7 .10


        //OutputDebugString(L"PCC set output\n");
}
//----------------------------------------------------------------------------//
//        LED put output bit ,set high                                                                                                                                               
//----------------------------------------------------------------------------//
VOID JSJopen(BYTE num ) {
v_pIOPregs->GPMDAT|=1<<num;

v_pIOPregs->GPNDAT|=1<<num;//2013.7.10

v_pIOPregs->GPCDAT|=1<<num;//2013.7.10


      v_pIOPregs->GPLDAT|=1<<num;//2013.7.10


      v_pIOPregs->GPKDAT|=1<<num;//2013.7.10



        //OutputDebugString(L"PCC set high\n");
}
//----------------------------------------------------------------------------//
//        LED put output bit ,set lower                                                                                                                       
//----------------------------------------------------------------------------//
VOID JSJclose(BYTE num ) {
v_pIOPregs->GPMDAT&=~(1<<num);

v_pIOPregs->GPNDAT&=~(1<<num);//2013.7.10

v_pIOPregs->GPCDAT&=~(1<<num);//2013.7.10

       v_pIOPregs->GPLDAT&=~(1<<num);//2013.7.10

       v_pIOPregs->GPKDAT&=~(1<<num);//2013.7.10

}




void write_kai( void )   
{

                v_pIOPregs->GPCDAT|=(0x01<<6);
                v_pIOPregs->GPCDAT|=(0x01<<5);
                v_pIOPregs->GPCDAT|=(0x01<<4);
                v_pIOPregs->GPCDAT|=(0x01<<0);

}



void IOW_shezhi( void )    //写选通输出格式设置
{
                v_pIOPregs->GPCCON|=(0x1<<4);


}

void IOW_HIGH( void )   //x写高电平
{
                v_pIOPregs->GPCDAT|=(0x01<<1);

}


void IOW_LOW( void )   // 写低电平
{
      v_pIOPregs->GPCDAT&=(~(0x01<<1));       

}


void IOR_shezhi( void )    //读选通输出格式设置
{
                v_pIOPregs->GPCCON|=(0x1<<28);

}



void IOR_HIGH( void )   //读高电平
{
                v_pIOPregs->GPCDAT|=(0x01<<7);//读高电平
}


void IOR_LOW( void )//读低电平
{       
                v_pIOPregs->GPCDAT&=(~(0x01<<7)); //读低电平

}


void read_kai(void)
{

                v_pIOPregs->GPCDAT|=(0x01<<6);
                v_pIOPregs->GPCDAT|=(0x01<<5);
                v_pIOPregs->GPCDAT&=(~(0x01<<4));
                v_pIOPregs->GPCDAT&=(~(0x01<<0));
               
}



void control_su(void)
{

                v_pIOPregs->GPCDAT&=(~(0x01<<6));
                v_pIOPregs->GPCDAT&=(~(0x01<<5));
                v_pIOPregs->GPCDAT&=(~(0x01<<4));
                v_pIOPregs->GPCDAT&=(~(0x01<<0));               

}

void read_configuration(void)
{
      v_pIOPregs->GPKCON1=0x00000000;   //GPK设置成输入       

      v_pIOPregs->GPLCON0=0x00000000;   //GPLCON0   设置成输入

}

void write_configuration(void)
{
    v_pIOPregs->GPKCON1=0x11111111; //GPKCON1设置输出
    v_pIOPregs->GPLCON0=0x11111111;//GPLCON0输出               

}


DWORD WRITE(DWORD AD , unsigned short DATA)
{
   
       
        unsigned inttmp;
       
        IOW_shezhi();          //写选通输出格式设置
      IOW_HIGH();             //再次拉高为连续写作准备

          write_configuration();

      control_su();


                if(AD&0x00000400)       //SA10 判断   GPC2
                {
               

                v_pIOPregs->GPCDAT|=(0x01<<2);
               
                }else
                {
                v_pIOPregs->GPCDAT&=(~(0x01<<2));       
               
                }

      tmp =AD&0x000f;
      v_pIOPregs->GPMDAT &=~0x003f;
      v_pIOPregs->GPMDAT |=tmp;

      tmp =(AD>>4)&0x003f;
      v_pIOPregs->GPNDAT &=~0x003f;
      v_pIOPregs->GPNDAT |=tmp;



      tmp =DATA&0x00ff;
      v_pIOPregs->GPKDAT&=0x00ff;
      v_pIOPregs->GPKDAT|=tmp<<8;

      tmp =DATA&0xff00;
      v_pIOPregs->GPLDAT&=0xff00;
      v_pIOPregs->GPLDAT|=tmp>>8;


       write_kai();



           v_pIOPregs->GPCDAT&=(~(0x01<<1));

           v_pIOPregs->GPCDAT|=(0x01<<1);

       return TRUE;   

}


DWORD READ(DWORD AD , unsigned short DATA)
{

    unsigned inttmp;


      IOR_shezhi();   //读选通输出格式设置
      IOR_HIGH();    //再次拉高为连续读准备

      control_su();

               read_configuration();
               
       

//读地址下传*************************************

                if(AD&0x00000400)       //SA10 判断   GPC2
                {
               

                v_pIOPregs->GPCDAT|=(0x01<<2);
               
                }else
                {
                v_pIOPregs->GPCDAT&=(~(0x01<<2));       
               
                }



      tmp =AD&0x000f;
      v_pIOPregs->GPMDAT &=~0x003f;
      v_pIOPregs->GPMDAT |=tmp;

      tmp =(AD>>4)&0x003f;
      v_pIOPregs->GPNDAT &=~0x003f;
      v_pIOPregs->GPNDAT |=tmp;

       read_kai();

       v_pIOPregs->GPCDAT&=(~(0x01<<7)); //读低电平
       k_value=v_pIOPregs->GPKDAT;

       l_value=v_pIOPregs->GPLDAT;

                v_pIOPregs->GPCDAT|=(0x01<<7);//读高电平


         BYTE hiValue = HIBYTE(k_value);///取高8位
         BYTE loValue = LOBYTE(l_value);///取低8位

          DATA=(loValue<<8)|hiValue;

         returnDATA;


}

这些程序生成.lib 静态链接库供应用程序去调用。现在的情况是,根本没有反映,映射没有成功。请高手指教。

wang_jiayou 发表于 2013-11-19 08:57:53

wince.he用到的oalioctl文件在附件中,我直接拷贝按照步骤来的操作,原博客地址http://www.cnblogs.com/we-hjb/archive/2010/02/25/1673815.html 我就按照这思路去操作,请教大侠吗我现在映射不成功是啥原因啊?
页: [1]
查看完整版本: S3C6410请教虚拟空间映射物理地址方法