Linux內(nèi)核IO內(nèi)存使用思路分析-學(xué)到牛牛

在嵌入式開發(fā)中,所有芯片對外設(shè)進(jìn)行處理都是通過讀寫設(shè)備上的寄存器進(jìn)行的奖恰。外設(shè)的寄存器在內(nèi)存中單獨分出一部分作為特殊功能寄存器進(jìn)行編址崭闲。在低級嵌入式設(shè)備中茬斧,我們通過直接操作外設(shè)寄存器即可控制外設(shè)的工作。在高級設(shè)備中玻粪,設(shè)備加載了操作系統(tǒng)隅津,操作系統(tǒng)中的內(nèi)存管理單元(MMU)對設(shè)備內(nèi)存進(jìn)行重新管理,從而無法直接進(jìn)行操作劲室。目前市面上伦仍,根據(jù)不同CPU體系架構(gòu),CPU對外設(shè)端口的編址方式一般有兩種:IO映射方式(IO mapped)和內(nèi)存映射方式(memory mapped)很洋。

IO映射方式充蓝,主要指外設(shè)地址空間和內(nèi)存地址空間是獨立開的,根據(jù)不同的訪問指令進(jìn)行對應(yīng)操作喉磁。典型的如x86處理器的設(shè)備谓苟。

圖 1 IO映射方式

內(nèi)存映射方式,主要指內(nèi)存地址空間和外設(shè)地址空間的訪問時一樣的协怒。只是訪問的地址不同涝焙。典型的如RISC指令系統(tǒng)的嵌入式設(shè)備CPU(如ARM、PowerPC等)斤讥。

圖 2 內(nèi)存映射方式

通常情況纱皆,外設(shè)的IO內(nèi)存資源的物理地址在硬件設(shè)計的時候已經(jīng)確定,并且該物理地址是已知的芭商。但是操作系統(tǒng)通過內(nèi)存管理單元(MMU)管理系統(tǒng)的虛擬地址到物理地址的訪問派草。在設(shè)備運(yùn)行時,對于驅(qū)動開發(fā)人員來說铛楣,可以被直接用于編程的是虛擬地址近迁,開發(fā)人員需要使用內(nèi)存映射機(jī)制將物理地址映射到虛擬地址,從而通過虛擬地址訪問外設(shè)IO簸州。

Linux內(nèi)核源碼中io.h文件聲明了函數(shù)ioremap()和iounmap()鉴竭,該函數(shù)主要用于將IO內(nèi)存資源的物理地址到虛擬地址的映射和解除映射。

// ioremap宏定義在asm/io.h內(nèi):

#define? ioremap(cookie,size)? ? __ioremap(cookie,size,0)

// __ioremap函數(shù)原型為(arm/mm/ioremap.c):

void__iomem * __ioremap(unsigned long phys_addr, size_t size, unsigned long flags);

參數(shù):

phys_addr:映射的起始IO地址

size:映射的空間大小

flags:映射的IO空間和權(quán)限有關(guān)的標(biāo)志

返回值:映射后的內(nèi)核虛擬地址(3G-4G)

iounmap函數(shù)用于解除ioremap()所做的映射岸浑,原型如下:

void iounmap(void * addr);

? ? 在將I/O外設(shè)的寄存器物理地址映射成虛擬地址后搏存,我們就可以象讀寫內(nèi)存那樣直接對I/O內(nèi)存資源進(jìn)行讀寫了。Linux內(nèi)核為了保證驅(qū)動程序的跨平臺的可移植性矢洲,提供了特定的讀寫函數(shù)來訪問I/O內(nèi)存資源璧眠。

讀寫I/O的函數(shù)如下所示:

// IO內(nèi)存讀取函數(shù),參數(shù)p為讀取的虛擬地址。分別可以讀取8位责静、16位和32位

#define ioread8(p)? ? ? ({ unsigned int __v = __raw_readb(p); __iormb(); __v; })

#define ioread16(p)? ? ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __iormb(); __v; })

#define ioread32(p)? ? ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __iormb(); __v; })

// IO內(nèi)存寫入函數(shù)袁滥,參數(shù)p為寫入的虛擬地址,v為寫入值灾螃。分別可以寫入8位题翻、16位和32位

#define iowrite8(v,p)? ({ __iowmb(); __raw_writeb(v, p); })

#define iowrite16(v,p)? ({ __iowmb(); __raw_writew((__force __u16)cpu_to_le16(v), p); })

#define iowrite32(v,p)? ({ __iowmb(); __raw_writel((__force __u32)cpu_to_le32(v), p); })

以下示例程序以tiny4412開發(fā)板為例,對開發(fā)板LED燈進(jìn)行IO控制腰鬼。

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/module.h>

#include <linux/sched.h>

#include <asm/io.h>

MODULE_LICENSE("GPL");

//? 內(nèi)核IO映射后的虛擬地址

unsigned int virt ;

int test_init()

{

// 映射的物理地址范圍:0x11000 000? - 0x11000 fff

virt = ioremap( 0x11000000, 4096 );?

// 通過指針讀寫內(nèi)存

// unsigned int *gpm4con = (unsigned int *)(virt + 0x02e0);

// unsigned int *gpm4dat = (unsigned int *)(virt + 0x02e4);

// *gpm4con = 0x1111;

// *gpm4dat &= ~0xf;

// *gpm4dat |= 0xf;

// 通過IO函數(shù)操作

iowrite32( 0x1111, virt + 0x02e0 );

unsigned int val = ioread32( virt + 0x02e4 );

iowrite32( val | 0xf , virt +0x02e4 );

return 0;

}

void test_exit()

{

iounmap( virt );

}

module_init( test_init );

module_exit( test_exit );

文章來源:學(xué)到牛牛 www.xuedaon.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嵌赠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子垃喊,更是在濱河造成了極大的恐慌猾普,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件本谜,死亡現(xiàn)場離奇詭異初家,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)乌助,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門溜在,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人他托,你說我怎么就攤上這事掖肋。” “怎么了赏参?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵志笼,是天一觀的道長。 經(jīng)常有香客問我把篓,道長纫溃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任韧掩,我火速辦了婚禮紊浩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疗锐。我一直安慰自己坊谁,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布滑臊。 她就那樣靜靜地躺著口芍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雇卷。 梳的紋絲不亂的頭發(fā)上阶界,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天虹钮,我揣著相機(jī)與錄音聋庵,去河邊找鬼膘融。 笑死,一個胖子當(dāng)著我的面吹牛祭玉,可吹牛的內(nèi)容都是我干的氧映。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼脱货,長吁一口氣:“原來是場噩夢啊……” “哼岛都!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起振峻,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤臼疫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扣孟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烫堤,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年凤价,在試婚紗的時候發(fā)現(xiàn)自己被綠了鸽斟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡利诺,死狀恐怖富蓄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慢逾,我是刑警寧澤立倍,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站侣滩,受9級特大地震影響口注,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胜卤,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一疆导、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧葛躏,春花似錦澈段、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至摩窃,卻和暖如春兽叮,著一層夾襖步出監(jiān)牢的瞬間芬骄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工鹦聪, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留账阻,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓泽本,卻偏偏與公主長得像淘太,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子规丽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容