新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM體系結構下面內存和i/o映射區別

        ARM體系結構下面內存和i/o映射區別

        作者: 時間:2016-11-20 來源:網絡 收藏
        (1)關于IO與內存空間:

        在X86處理器中存在著I/O空間的概念,I/O空間是相對于內存空間而言的,它通過特定的指令in、out來訪問。端口號標識了外設的寄存器地址。Intel語法的in、out指令格式為:
        IN 累加器, {端口號│DX}
        OUT {端口號│DX},累加器
        目前,大多數嵌入式微控制器ARM、PowerPC等中并不提供I/O空間,而僅存在內存空間。內存空間可以直接通過地址、指針來訪問,程序和程序運行中使用的變量和其他數據都存在于內存空間中。
        即便是在X86處理器中,雖然提供了I/O空間,如果由我們自己設計電路板,外設仍然可以只掛接在內存空間。此時,CPU可以像訪問一個內存單元那樣訪問外設I/O端口,而不需要設立專門的I/O指令。因此,內存空間是必須的,而I/O空間是可選的。

        本文引用地址:http://www.104case.com/article/201611/318962.htm

        (2)inb和outb:

        在Linux設備驅動中,宜使用Linux內核提供的函數來訪問定位于I/O空間的端口,這些函數包括:
        · 讀寫字節端口(8位寬)
        unsigned inb(unsigned port);
        void outb(unsigned char byte, unsigned port);
        · 讀寫字端口(16位寬)
        unsigned inw(unsigned port);
        void outw(unsigned short word, unsigned port);
        · 讀寫長字端口(32位寬)
        unsigned inl(unsigned port);
        void outl(unsigned longword, unsigned port);
        · 讀寫一串字節
        void insb(unsigned port, void *addr, unsigned long count);
        void outsb(unsigned port, void *addr, unsigned long count);
        · insb()從端口port開始讀count個字節端口,并將讀取結果寫入addr指向的內存;outsb()將addr指向的內存的count個字節連續地寫入port開始的端口。
        · 讀寫一串字
        void insw(unsigned port, void *addr, unsigned long count);
        void outsw(unsigned port, void *addr, unsigned long count);
        · 讀寫一串長字
        void insl(unsigned port, void *addr, unsigned long count);
        void outsl(unsigned port, void *addr, unsigned long count);
        上述各函數中I/O端口號port的類型高度依賴于具體的硬件平臺,因此,只是寫出了unsigned。

        (3)readb和writeb:
        在設備的物理地址被映射到虛擬地址之后,盡管可以直接通過指針訪問這些地址,但是工程師宜使用Linux內核的如下一組函數來完成設備內存映射的虛擬地址的讀寫,這些函數包括:
        · 讀I/O內存
        unsigned int ioread8(void *addr);
        unsigned int ioread16(void *addr);
        unsigned int ioread32(void *addr);
        與上述函數對應的較早版本的函數為(這些函數在Linux 2.6中仍然被支持):
        unsigned readb(address);
        unsigned readw(address);
        unsigned readl(address);
        · 寫I/O內存
        void iowrite8(u8 value, void *addr);
        void iowrite16(u16 value, void *addr);
        void iowrite32(u32 value, void *addr);
        與上述函數對應的較早版本的函數為(這些函數在Linux 2.6中仍然被支持):
        void writeb(unsigned value, address);
        void writew(unsigned value, address);
        void writel(unsigned value, address);

        (4)把I/O端口映射到“內存空間”:
        void *ioport_map(unsigned long port, unsigned int count);
        通過這個函數,可以把port開始的count個連續的I/O端口重映射為一段“內存空間”。然后就可以在其返回的地址上像訪問I/O內存一樣訪問這些I/O端口。當不再需要這種映射時,需要調用下面的函數來撤消:
        void ioport_unmap(void *addr);
        實際上,分析ioport_map()的源代碼可發現,所謂的映射到內存空間行為實際上是給開發人員制造的一個“假象”,并沒有映射到內核虛擬地址,僅僅是為了讓工程師可使用統一的I/O內存訪問接口訪問I/O端口。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 高尔夫| 留坝县| 武强县| 吴川市| 团风县| 沁源县| 府谷县| 广饶县| 炉霍县| 密山市| 临湘市| 宣汉县| 沧源| 东乡| 九龙城区| 抚顺市| 崇明县| 海宁市| 安远县| 卫辉市| 颍上县| 闻喜县| 故城县| 靖边县| 保靖县| 南康市| 微博| 遂溪县| 兰西县| 贵德县| 全椒县| 留坝县| 宝应县| 富宁县| 方正县| 恩施市| 漾濞| 河曲县| 舒城县| 罗山县| 云安县|