skip to main |
skip to sidebar
下面提到的範例平台為Samsung S3C2410
實際操作還是需要要查閱ARM的datasheet以及使用中的BSP代碼
要操作一個平臺的GPIO,在其對應BSP中按照基底位址,找到虛擬位址,並且找到方便操作這個位址的資料結構就可以了,關鍵函數就是VirtualAlloc和VirtualCopy。並且CE的方便之處就是user mode的應用程式仍然可以使用這兩個函數來訪問所有這些虛擬空間,對於不太複雜的程式,甚至可以省略寫驅動直接在應用程式中操作。
下面以操作Samsung S3C2410的GPIO為例,講述這個步驟:
1.首先在BSP中的s2410.h檔,找到虛擬位址映射以及操作GPIO的寄存器結構體(這個在自己製作一些特殊設備的BSP時,會依據需而不同)
//
// 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; // AC
unsigned int rGSTATUS1; // B0
unsigned int rGSTATUS2; // B4
unsigned int rGSTATUS3; // B8
unsigned int rGSTATUS4; // BC
}IOPreg;
//將這些複製備用。
2.在EVC中建立一個應用程式工程,由於VirtualCopy函數沒有在頭檔中定義,但是在coredll.lib裏面提供了符號連接,所以我們這裏直接添加一個函數定義就OK了。
#ifdef __cplusplus
extern "C"
{
#endif
BOOL VirtualCopy( LPVOID, LPVOID, DWORD, DWORD );
#ifdef __cplusplus
}
#endif
同時將步驟1裏面的定義複製到這裏。
3.按照驅動程式裏面操作的方法在應用程式中寫GPIO操作函數
(1)定義一個寄存器結構體變數
volatile IOPreg *v_pIOPRegs;
(2)給這個變數分配空間並且映射到寄存器的空間上
v_pIOPRegs = (volatile IOPreg*)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPRegs == NULL)
{
DEBUGMSG (1,(TEXT("v_pIOPRegs is not allocated\n\r")));
return TRUE;
}
if (!VirtualCopy((PVOID)v_pIOPRegs, (PVOID)IOP_BASE, sizeof(IOPreg), PAGE_READWRITEPAGE_NOCACHE)) {
DEBUGMSG (1,(TEXT("v_pIOPRegs is not mapped\n\r")));
return TRUE;
}
DEBUGMSG (1,(TEXT("v_pIOPRegs is mapped to %x\n\r"), v_pIOPRegs));
這3個步驟之後,對v_pIOPRegs的操作將直接和GPIO的寄存器關聯
例如:設置GPB的控制寄存器為全部Output
v_pIOPRegs->rGPBCON=0x155555;
設置GPB的資料寄存器輸出高電平
v_pIOPRegs->rGPBDAT=0x3FF;