在裸奔代碼中,如果要控制gpio,直接控制gpio寄存器地址即可;
在linux系統中,所有操作的地址都是虛擬地址,都是由linux內核去管理,所以需要將物理地址轉換成內核可識別的虛擬地址。
1、ioremap 和 iounmap
// 功能:將物理地址映射為虛擬地址
// 參數1:需要映射的物理地址
// 參數2:需要映射的地址長度
// 返回值:映射后的虛擬地址(例:void*reg_base = ioremap(0x12345678, 4);)
void *ioremap(cookie, size);
// 功能:取消映射
// 參數:需要取消的虛擬地址
void iounmap(cookie);
2、虛擬地址操作
// 功能:將虛擬地址中的值讀出來
// 參數:需要讀取的虛擬地址
__raw_readl(addr); 等同於 readl(addr);
// 功能:將數據寫入虛擬地址
// 參數1:數據
// 參數2:需要寫入的虛擬地址
__raw_writel(data, addr); 等同於 writel(data, addr);
// 從虛擬地址讀取4個字節數據
unsigned int readl(unsigned int addr);
// 往虛擬地址寫入4個字節數據
void writel(unsigned int data, unsigned int addr);
// 從虛擬地址讀取2個字節數據
unsigned short readw(unsigned int addr);
// 往虛擬地址寫入2個字節數據
void writew(unsigned short data, unsigned int addr);
// 從虛擬地址讀取1個字節數據
unsigned char readb(unsigned int addr);
// 往虛擬地址寫入1個字節數據
void writeb(unsigned char data, unsigned int addr);
void led_on(void) { void *reg_base; unsigned int temp; reg_base = ioremap(0x12345678, 4); temp = __raw_readl(reg_base); temp &= ~(0xff<<12); temp |= (0x11<<12); __raw_writel(temp, reg_base); }