linux系統中,硬體通路實質就是對寄存器的通路,或者說是對外部ram的通路。
1、硬體通路的實質
驅動程式控制裝置,主要是通過通路裝置内的寄存器來達到控制目的,是以我們讨論如何通路硬體,就成了如何通路這些寄存器了。
2、位址映射
在linux系統中,無論是核心程式還是應用程式,都隻有使用虛拟位址,而晶片手冊中給出的硬體寄存器位址或者RAM位址則是實體位址,無法直接使用,是以,我們讀寫寄存器的第一步就是将它的實體位址映射為虛拟位址。
2.1動态映射
所謂的動态映射,是指在驅動程式中采用ioremap函數将實體位址映射為虛拟位址。
原型:void * ioremap(physaddr, size)
參數:
Physaddr:待映射的實體位址
Size:映射的區域長度
傳回值:映射後的虛拟位址
2.2、靜态映射
所謂靜态映射,是指linux系統根據使用者事先指定的映射關系,在核心啟動時,自動地将實體位址映射為虛拟位址。
在靜态映射中,使用者是通過map_desc結構來指明實體位址與虛拟位址的映射關系。
struct map_desc
{
unsigned long virtual; //映射後的虛拟位址
unsigned long pfn; //實體位址所在的頁幀号
unsigned long length; // 映射長度
unsigned int type; //映射的裝置類型
};
pfn:利用_phys_to_pfn(實體位址)可以計算出實體位址所在的實體頁幀号(除以2^12(4k),因為一個頁有4k)。
3、寄存器的讀寫
在完成位址映射後,就可以讀寫寄存器了,linux核心提供了一系列函數,來讀寫寄存器。
unsigned ioread8(void *addr)
unsigned ioread16(void *addr)
unsigned ioread32(void *addr)
unsigned readb(address)
unsigned readw(address)
unsigned readl(address)
void iowrite8(u8 value, void *addr)
void iowrite16(u16 value, void *addr)
void iowrite32(u32 value, void *addr)
void writeb(unsigned value, address)
void writew(unsigned value, address)
void writel(unsigned value, address)