中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Linux的設(shè)備驅(qū)動工程師之路

2019-02-26    來源:多智時代

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

一、重要知識點(diǎn)

1.I/O端口和I/O內(nèi)存寄存器和常規(guī)內(nèi)存的區(qū)別:寄存器和RAM主要不同在于寄存器有邊際效果,讀取某個地址時可能導(dǎo)致該地址的內(nèi)容發(fā)生變化,比如說很多設(shè)備的中斷狀態(tài)寄存器只要一讀取,便自動清0.所以硬件寄存器不能直接訪問,而要通過I/O端口和I/O內(nèi)存兩種方式訪問。

在硬件層,I/O內(nèi)存區(qū)域和I/O端口區(qū)域沒有概念上的區(qū)別:它們都是通過向地址總線和控制總線發(fā)生電平信號進(jìn)行訪問,再通過數(shù)據(jù)總線讀寫數(shù)據(jù)。

a.I/O端口:一些CPU制造廠在它們的芯片中使用單一的地址空間,而一些則為外設(shè)保留獨(dú)立的地址空間,以便和內(nèi)存區(qū)間分開來,這段獨(dú)立與內(nèi)存地址空間的地址空間就叫I/O端口。在/proc/ioport中可以看到。嵌入式處理器大部分不支持I/O端口。

訪問I/O端口有兩步:1.申請I/O端口2.讀寫I/O端口申請I/O端口:structresource *request_region(unsigned long first, unsigned long n, const char *name)

申請從first開始的n個端口。參數(shù)name為設(shè)備名稱。如果分配成功則返回非NULL值。

釋放I/O端口:voidrelease_region(unsigned long start, unsigned long n)

讀寫I/O端口:讀寫一個字節(jié)unsignedinb(unsigned port)

voidoutb(usigned char byte, unsigned port)

讀寫二個字節(jié)unsignedinb(unsigned port)

voidoutb(usigned short byte, unsigned port)

讀寫四個字節(jié)unsignedinb(unsigned port)

voidoutb(usigned long byte, unsigned port)

b.I/O內(nèi)存通過將外設(shè)寄存器映射到內(nèi)存空間來進(jìn)行訪問叫做I/O內(nèi)存,嵌入式大多只支持這種操作。

訪問I/O內(nèi)存有三步:1.申請I/O內(nèi)存區(qū)域2.映射I/O內(nèi)存區(qū)域3.讀寫I/O內(nèi)存申請I/O內(nèi)存區(qū)域structresource *request_mem_region(unsigned long start, unsigned long len, char *name)

申請?jiān)L問從start(I/O物理地址)開始的len長度的I/O內(nèi)存區(qū)域,如成功則返回非NULL值。在/proc/iomem中可可以查看到已經(jīng)被申請的I/O內(nèi)存區(qū)域。在后面的我寫的驅(qū)動程序中并沒用使用申請這一步,是因?yàn)槲沂褂玫腉PIO內(nèi)存區(qū)域已經(jīng)被申請,如果在申請會導(dǎo)致失敗。但是這樣做法是不安全的做法,因?yàn)橥籌/O內(nèi)存區(qū)域域被多個模塊使用。

釋放I/O內(nèi)存區(qū)域voidrelease_mem_region(unsigned long start, unsigned long len)

映射I/O內(nèi)存區(qū)域void*ioremap(unsigned long phy_addr, unsigned long size)

映射從物理地址phy_addr開始的size長度的的地址空間。返回可以訪問I/O內(nèi)存地址。由ioreamp返回的地址不應(yīng)該直接引用,必須通過下面一些列的讀寫函數(shù)完成。

讀寫操作I/O內(nèi)存讀1、2、4個字節(jié):unsignedint read8(void *addr);unsignedint read16(void *addr)

unsignedint read32(void *addr)

寫讀1、2、4個字節(jié):voidiowrite8(u8 value, void *addr)

voidiowrite16(u8 value, void *addr)

voidiowrite32(u8 value, void *addr)

2.混雜設(shè)備驅(qū)動在Linux系統(tǒng)中,存在一類字符設(shè)備,他們共享一個主設(shè)備號(10),但此設(shè)備號不同,我們稱這類設(shè)備為混雜設(shè)備(miscdeivce),查看/proc/device中可以看到一個名為misc的主設(shè)備號為10.所有的混雜設(shè)備形成一個鏈表,對設(shè)備訪問時內(nèi)存根據(jù)次設(shè)備號找到對應(yīng)的miscdevice設(shè)備。

Linux內(nèi)核使用structmiscdeivce來描述一個混雜設(shè)備structmiscdevice{ int minor;conststruct file_opreations *fops;structlist_head list;structdevice *parent;structdevice *this_device;}使用時只需填寫minor次設(shè)備號,*name設(shè)備名,*fops文件操作函數(shù)集即可。

Linux內(nèi)核使用misc_register函數(shù)注冊一個混雜設(shè)備。注冊成功后,linux內(nèi)核為自動為該設(shè)備創(chuàng)建設(shè)備文件。

intmisc_register(struct miscdevice *misc)

二、驅(qū)動代碼

1.驅(qū)動代碼一這段LED驅(qū)動代碼采用手動I/O內(nèi)存映射的方式訪問。沒有使用申請內(nèi)存區(qū)域函數(shù),這樣使不安全的。直接訪問I/O內(nèi)存地址而不是通過讀寫函數(shù)訪問也是不安全。同時驅(qū)動代碼包含硬件相關(guān)代碼也是移植性不好的。寫這段代碼是為了幫助理解I/O內(nèi)存映射的過程。

view plain #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

volatile unsigned int long *gpb_con = NULL;volatile unsigned int long *gpb_data = NULL;

static int leds_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)

{

if((cmd>1) |(arg>3))

return-EINVAL;

switch(cmd)

{ case 0:*gpb_data&= ~(1

default:return-EINVAL;

}

return 0;}

static const struct file_operations leds_fops = {。owner = THIS_MODULE,。ioctl = leds_ioctl,};

static struct miscdevice misc = {。minor =MISC_DYNAMIC_MINOR,。name ="my_leds",。fops =&leds_fops,};

static int __init leds_init(void)

{ int ret;

//注冊混雜設(shè)備ret =misc_register(&misc);

//映射I/O內(nèi)存gpb_con = (volatileunsigned long *)ioremap(0x56000010, 16); //0x56000010為GPIOB控制寄存器的物理地址gpb_data = gpb_con+1;

//配置LED對應(yīng)的GPIOB 5、6、7、8口為輸出并初始化為1,LED滅*gpb_con |=(1

printk("ledsinit. ");return ret;}

static void leds_exit(void)

{

misc_deregister(&misc);

printk("leds_exit ");}

module_init(leds_init);module_exit(leds_exit);

MODULE_AUTHOR("Y-Kee");MODULE_LICENSE("GPL");

2.驅(qū)動代碼二:采用內(nèi)核定義好的GPIO接口(S3C2410_GPB5和S3C2410_GPB5_OUTP)和GPIO操作函數(shù)(s3c2410_gpio_setpin和s3c2410_gpio_cfgpin)?梢浦残院,也是正確的做法。內(nèi)核的GPIO操作函數(shù)也是通過一些的運(yùn)算將GPIO接口換算成虛擬內(nèi)存地址然后進(jìn)行訪問的。

view plain #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

static unsigned long led_table[] = { S3C2410_GPB5,S3C2410_GPB6,S3C2410_GPB7,S3C2410_GPB8,};

static unsigned long led_cfg_table[] = { S3C2410_GPB5_OUTP,S3C2410_GPB6_OUTP,S3C2410_GPB7_OUTP,S3C2410_GPB8_OUTP,};

static int leds_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)

{ if((cmd>1) |(arg>3))

return-EINVAL;

switch(cmd)

{ case 0:s3c2410_gpio_setpin(led_table[arg],0);break;case 1:s3c2410_gpio_setpin(led_table[arg],1);break;

default:return-EINVAL;

}

return 0;}

static const struct file_operations leds_fops = {。owner = THIS_MODULE,。ioctl = leds_ioctl,};

static struct miscdevice misc = {。minor =MISC_DYNAMIC_MINOR,。name ="my_leds",。fops =&leds_fops,};

static int __init leds_init(void)

{ int ret, i;

//注冊混雜設(shè)備ret =misc_register(&misc);

//配置LED對應(yīng)的GPIOB 5、6、7、8口為輸出并初始化為1,LED滅for(i=0; i

{ s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);s3c2410_gpio_setpin(led_table[i],1);}

printk("ledsinit. ");return ret;}

static void leds_exit(void)

{

misc_deregister(&misc);printk("leds_exit ");}

module_init(leds_init);module_exit(leds_exit);

MODULE_AUTHOR("Y-Kee");MODULE_LICENSE("GPL");

原文出自【比特網(wǎng)】,轉(zhuǎn)載請保留原文鏈接:http://soft.chinabyte.com/os/488/12166488.shtml

在不久的將來,云計算一定會徹底走入我們的生活,有興趣入行未來前沿產(chǎn)業(yè)的朋友,可以收藏云計算,及時獲取人工智能、大數(shù)據(jù)、云計算和物聯(lián)網(wǎng)的前沿資訊和基礎(chǔ)知識,讓我們一起攜手,引領(lǐng)人工智能的未來!

標(biāo)簽: linux 安全 大數(shù)據(jù) 代碼 云計算

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:用友推出開放云平臺等九大云服務(wù)方案

下一篇:我國研制出新一代云計算操作系統(tǒng)