女人被狂躁到高潮视频免费无遮挡,内射人妻骚骚骚,免费人成小说在线观看网站,九九影院午夜理论片少妇,免费av永久免费网址

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]以下是驅(qū)動(dòng)的源碼。#includelinux/config.h//配置頭文件#includelinux/kernel.h//用于調(diào)用kmalloc和kfree#includelinux/sched.h//調(diào)度,進(jìn)程睡眠,喚醒,中斷申請(qǐng),中斷釋放#includelinux/timer.h/#includelinux/ini

以下是驅(qū)動(dòng)的源碼。
#includelinux/config.h//配置頭文件
#includelinux/kernel.h//用于調(diào)用kmalloc和kfree
#includelinux/sched.h//調(diào)度,進(jìn)程睡眠,喚醒,中斷申請(qǐng),中斷釋放
#includelinux/timer.h/
#includelinux/init.h//用戶定義模塊初始函數(shù)名需引用的頭文件
#includelinux/module.h
#includeasm/hardware.h
#includeasm/arch/S3C2440.h

#defineDEVICE_NAMEquot;ledsquot;

staticunsignedlongled_table[]={
S3C2410_GPB(5),
S3C2410_GPB(6),
S3C2410_GPB(7),
S3C2410_GPB(8),
};

staticunsignedintled_cfg_table[]={
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
};

staticintsbc2440_leds_ioctl(
structinode*inode,
structfile*file,
unsignedintcmd,
unsignedlongarg)
{
switch(cmd){
case0:
case1:
if(arg4){
return-EINVAL;
}
s3c2410_gpio_setpin(led_table[arg],!cmd);
return0;

default:
return-EINVAL;
}
}
staticstructfile_operationsdev_fops={
.owner=THIS_MODULE,
.ioctl=sbc2440_leds_ioctl,
};

staticstructmiscdevicemisc={//雜項(xiàng)設(shè)備結(jié)構(gòu)體
.minor=MISC_DYNAMIC_MINOR,//次設(shè)備號(hào)
.name=DEVICE_NAME,
.fops=dev_fops,
};

staticint__initdev_init(void)
{
intret;
inti;

for(i=0;i4;i){
s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);
s3c2410_gpio_setpin(led_table[i],0);
}

ret=misc_register(misc);
printk(DEVICE_NAMEquot;tinitializednquot;);
returnret;
}
staticvoid__exitdev_exit(void)
{
misc_deregister(misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE(quot;GPLquot;);
MODULE_AUTHOR(quot;FriendlyARMInc.quot;);

1.misc設(shè)備
misc設(shè)備設(shè)備被譯成雜項(xiàng)設(shè)備或者是混雜設(shè)備。Linux設(shè)備驅(qū)動(dòng)主要分為字符設(shè)備,塊設(shè)備和網(wǎng)絡(luò)設(shè)備。我們把那些不屬于上述三大形式的歸為一類(lèi)叫做雜項(xiàng)設(shè)備。雜項(xiàng)設(shè)備共用相同的主設(shè)備號(hào)(MISC_MAJOR,也就是10),但次設(shè)備號(hào)不同,對(duì)于雜項(xiàng)設(shè)備,linux內(nèi)核專(zhuān)門(mén)提供了這樣的一個(gè)結(jié)構(gòu)體miscdevice,其有很強(qiáng)的包容性。結(jié)構(gòu)如下:
以下文件定義在/linux2.6.32.2/include/linux/Miscdivice.h
structmiscdevice{
intminor;
constchar*name;
conststructfile_operations*fops;
structlist_headlist;
structdevice*parent;
structdevice*this_device;
constchar*nodename;
mode_tmode;
};
同時(shí)提供的miscdevice注冊(cè)和注銷(xiāo)函數(shù)如下所示。
intmisc_register(structmiscdevice*misc);
intmisc_deregister(structmiscdevice*misc);
其實(shí),雜項(xiàng)設(shè)備的本質(zhì)仍然是字符設(shè)備,只是將這種設(shè)備驅(qū)動(dòng)增加了一層封裝而已,雜項(xiàng)設(shè)備中的主體還是file_operations結(jié)構(gòu)的實(shí)現(xiàn)。

2.LED對(duì)應(yīng)的GPIO端口列表
staticunsignedlongled_table[]={S3C2410_GPB(5),S3C2410_GPB(6),S3C2410_GPB(7),S3C2410_GPB(8),};
led設(shè)備驅(qū)動(dòng)程序中主要是對(duì)上述的幾個(gè)端口進(jìn)行s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);(配置管腳功能)
s3c2410_gpio_setpin(led_table[i],0);(設(shè)置管腳電平狀態(tài))
操作。先來(lái)弄清楚這幾個(gè)端口的定義。
以下文件定義在/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
/*S3C2410GPIOnumberdefinitions.*/
#defineS3C2410_GPA(_nr)(S3C2410_GPIO_A_START (_nr))#defineS3C2410_GPB(_nr)(S3C2410_GPIO_B_START (_nr))#defineS3C2410_GPC(_nr)(S3C2410_GPIO_C_START (_nr))#defineS3C2410_GPD(_nr)(S3C2410_GPIO_D_START (_nr))#defineS3C2410_GPE(_nr)(S3C2410_GPIO_E_START (_nr))#defineS3C2410_GPF(_nr)(S3C2410_GPIO_F_START (_nr))#defineS3C2410_GPG(_nr)(S3C2410_GPIO_G_START (_nr))#defineS3C2410_GPH(_nr)(S3C2410_GPIO_H_START (_nr))
enums3c_gpio_number{S3C2410_GPIO_A_START=0,S3C2410_GPIO_B_START=S3C2410_GPIO_NEXT(S3C2410_GPIO_A),S3C2410_GPIO_C_START=S3C2410_GPIO_NEXT(S3C2410_GPIO_B),S3C2410_GPIO_D_START=S3C2410_GPIO_NEXT(S3C2410_GPIO_C),S3C2410_GPIO_E_START=S3C2410_GPIO_NEXT(S3C2410_GPIO_D),S3C2410_GPIO_F_START=S3C2410_GPIO_NEXT(S3C2410_GPIO_E),S3C2410_GPIO_G_START=S3C2410_GPIO_NEXT(S3C2410_GPIO_F),S3C2410_GPIO_H_START=S3C2410_GPIO_NEXT(S3C2410_GPIO_G),};
#defineS3C2410_GPIO_NEXT(__gpio)((__gpio##_START) (__gpio##_NR) CONFIG_S3C_GPIO_SPACE 0)
CONFIG_S3C_GPIO_SPAC是內(nèi)核配置選項(xiàng),在.config中可以找到,我的配置為:
CONFIG_S3C_GPIO_SPACE=0
因此,以S3C2410_GPB(5)為例,其宏展開(kāi)為:
S3C2410_GPIO_NEXT(S3C2410_GPIO_A) 5=
(S3C2410_GPIO_A_START S3C2410_GPIO_A_NR CONFIG_S3C_GPIO_SPACE 0) 5=
很顯然,S3C2410_GPB(5)就是從GPA的首地址 GPA個(gè)數(shù) GPB的offset就是當(dāng)前GPB的IO偏移量,即
0 32 5=37,同理
S3C2410_GPB(0)相當(dāng)于32
S3C2410_GPB(5)相當(dāng)于37
S3C2410_GPB(6)相當(dāng)于38
S3C2410_GPB(7)相當(dāng)于39
S3C2410_GPB(8)相當(dāng)于40
到這里我們應(yīng)該明白,這個(gè)宏的作用就是對(duì)端口進(jìn)行編號(hào),對(duì)于GPA其端口編號(hào)的范圍是0~31,GPB端口編號(hào)范圍是32~63,以此類(lèi)推,當(dāng)然這里所有的編號(hào)不一定都被使用。因?yàn)槊拷M的端口的個(gè)數(shù)不一樣,所以給每組都定義32個(gè),以保證每組都?jí)蛴?。在得到端口?hào)后,除以32得到的結(jié)果就可以確定這個(gè)端口是哪組的了。比如得到端口編號(hào)38,除以32后得到1就知道是屬于GPB里面的I/O口了。這在后面進(jìn)一步分析中會(huì)看到。

3.LED對(duì)應(yīng)端口將要輸出的狀態(tài)列表分析
staticunsignedintled_cfg_table[]={
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
};
S3C2410_GPIO_OUTPUT定義在mach/regs-gpio.h
這里主要看最后的兩位,表示了端口的狀態(tài)。
00代表輸入,01代表輸出,10代表功能2,,1代表功能3.注意提示,GPA是沒(méi)有輸入功能的。

#defineS3C2410_GPIO_LEAVE(0xFFFFFFFF)
#defineS3C2410_GPIO_INPUT(0xFFFFFFF0)/*notavailableonA*/
#defineS3C2410_GPIO_OUTPUT(0xFFFFFFF1)
#defineS3C2410_GPIO_IRQ(0xFFFFFFF2)/*notavailableforall*/
#defineS3C2410_GPIO_SFN2(0xFFFFFFF2)/*bankA=addr/cs/nand*/
#defineS3C2410_GPIO_SFN3(0xFFFFFFF3)/*notavailableonA*/

4.s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i])分析
函數(shù)源碼定義在linux/arch/arm/plat-s3c24xx/gpio.c
函數(shù)原型:
voids3c2410_gpio_cfgpin(unsignedintpin,unsignedintfunction)
{
void__iomem*base=S3C24XX_GPIO_BASE(pin);
unsignedlongmask;
unsignedlongcon;
unsignedlongflags;

if(pinS3C2410_GPIO_BANKB){//判斷I/O口是不是屬于GPA,
mask=1S3C2410_GPIO_OFFSET(pin);
}else{
mask=3S3C2410_GPIO_OFFSET(pin)*2;
}

switch(function){//根據(jù)要設(shè)置的管腳的功能進(jìn)行相應(yīng)的操作
caseS3C2410_GPIO_LEAVE:
mask=0;
function=0;
break;

caseS3C2410_GPIO_INPUT:
caseS3C2410_GPIO_OUTPUT:
caseS3C2410_GPIO_SFN2:
caseS3C2410_GPIO_SFN3:
if(pinS3C2410_GPIO_BANKB){
function-=1;
function=1;
function=S3C2410_GPIO_OFFSET(pin);
}else{
function=3;
function=S3C2410_GPIO_OFFSET(pin)*2;
}
}

/*modifythespecifiedregisterwwithIRQsoff*/

local_irq_save(flags);

con=__raw_readl(base 0x00);
con=~mask;
con|=function;

__raw_writel(con,base 0x00);

local_irq_restore(flags);
}
先看一下主體框架,主體通過(guò)switch(function)找到要設(shè)置的相應(yīng)的功能進(jìn)行對(duì)應(yīng)的操作。這個(gè)估計(jì)很容易看懂。下面將里面幾個(gè)不好搞懂的地方具體說(shuō)一下。
對(duì)于void__iomem*base=S3C24XX_GPIO_BASE(pin);先來(lái)看它的實(shí)現(xiàn)
以下內(nèi)容定義在/linux-2.6.32.2/arch/arm/mach-s3c2410includemachRegs-gpio.h
#defineS3C24XX_GPIO_BASE(x)S3C2410_GPIO_BASE(x)
#defineS3C2410_GPIO_BASE(pin)((((pin)~31)1) S3C24XX_VA_GPIO)
以下內(nèi)容定義在/linux-2.6.32.2/arch/arm/plat-s3c24xx/include/plat/map.h
#defineS3C24XX_VA_GPIO((S3C24XX_PA_GPIO-S3C24XX_PA_UART) S3C24XX_VA_UART)
以下內(nèi)容定義在/linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach/map.h
#defineS3C24XX_PA_GPIOS3C2410_PA_GPIO
#defineS3C24XX_PA_UARTS3C2410_PA_UART
以下內(nèi)容定義在/linux-2.6.32.2/arch/arm/plat-s3c24xx/include/plat/map.h
#defineS3C2410_PA_GPIO(0x56000000)
#defineS3C2410_PA_UART(0x50000000)
以下內(nèi)容定義在linux-2.6.32.2/arch/arm/plat-s3c24xx/include/plat/map.h
#defineS3C24XX_VA_UARTS3C_VA_UART
以下內(nèi)容定義在linux-2.6.32.2/arch/arm/plat-s3c/include/plat/map.h
#defineS3C_VA_UARTS3C_ADDR(0x01000000)/*UART*/
以下內(nèi)容定義在linux-2.6.32.2/arch/arm/plat-s3c/include/plat/Map-base.h
#ifndef__ASSEMBLY__
#defineS3C_ADDR(x)((void__iomem__force*)S3C_ADDR_BASE (x))
#else
#defineS3C_ADDR(x)(S3C_ADDR_BASE (x))
#endif
#defineS3C_ADDR_BASE(0xF4000000)

到這找出了定義S3C24XX_GPIO_BASE(x)全部的宏,從此處可以發(fā)現(xiàn),linux中文件的定義分布是比較散亂的,這也是讓很多初學(xué)者頭疼的地方。接著分析
S3C24XX_VA_GPIO=((S3C24XX_PA_GPIO-S3C24XX_PA_UART) S3C24XX_VA_UART)
=((0x56000000-0x50000000) (0xF4000000 0x01000000))
=(0x06000000 0xF5000000)
=(0xFB000000)
#defineS3C_VA_UARTS3C_ADDR(0x01000000)/*UART*/
這句話看出在虛擬地址的基地址上偏移0x01000000
對(duì)下面兩個(gè)進(jìn)行解釋?zhuān)?br/>#defineS3C_ADDR_BASE(0xF4000000)所有寄存器虛擬地址首地址
#S3C24XX_VA_GPIOGPIO的虛擬地址首地址
S3C2410_GPB(5)通過(guò)上面的計(jì)算其數(shù)值為37,
S3C24XX_GPIO_BASE(S3C2410_GPB(5))=S3C24XX_GPIO_BASE(37)
=((((37)~31)1) S3C24XX_VA_GPIO)
=((((37)~31)1) (0xFB000000))=0xFB000010
所以最終*base=0xFB000010,這個(gè)就是GPBCON的虛擬地址,查看其手冊(cè)我們知道GPBCON物理地址為0X56000010,GPACON的虛擬地址0xFB000000,查看其手冊(cè)我們知道GPACON物理地址為0X56000000,下面的程序通過(guò)訪問(wèn)這個(gè)虛擬地址,來(lái)訪問(wèn)控制寄存器,實(shí)現(xiàn)對(duì)I/O端口的配置。
還一個(gè)問(wèn)題,((((pin)~31)1)到底是神馬意思?這個(gè)主要靠理解,剛才上面說(shuō)了每組端口定義為32個(gè),((pin)~31)相當(dāng)于就是把低五位全部清零,而第五位所能代表的范圍正好是32,有點(diǎn)以大小32進(jìn)行對(duì)其的意思。如果將得到的數(shù)值右移5位的話,得到的數(shù)值(設(shè)為ppvalue)能正好代表是哪組I/O口。這里為什么右移1位呢,我們看下
幾個(gè)GPXCON寄存器的物理地址。
GPACON0X56000000
GPBCON0X56000010
GPCCON0X56000020
GPDCON0X56000030
其他的以此類(lèi)推,可以看出這個(gè)I/O口控制寄存器的規(guī)律,如果將ppvalue左移四位,加上GPIO虛擬基地址,就能得到GPXCON控制寄存器的虛擬地址了。順便說(shuō)下,這里的虛實(shí)地址的映射只是相差了一個(gè)偏移量。

分析:if(pinS3C2410_GPIO_BANKB)
S3C2410_GPIO_BANKB的定義如下
#defineS3C2410_GPIO_BANKA(32*0)
#defineS3C2410_GPIO_BANKB(32*1)
#defineS3C2410_GPIO_BANKC(32*2)
#defineS3C2410_GPIO_BANKD(32*3)
#defineS3C2410_GPIO_BANKE(32*4)
#defineS3C2410_GPIO_BANKF(32*5)
#defineS3C2410_GPIO_BANKG(32*6)
#defineS3C2410_GPIO_BANKH(32*7)
用于判斷此I/O口是否為GPA端口,這是為了區(qū)分開(kāi)GPA與其他各組端口,因?yàn)镚PA控制寄存器的操作和其他的有點(diǎn)區(qū)別,另外要注意,它是沒(méi)有輸入功能的??磀atasheet能夠更好的了解。

分析:S3C2410_GPIO_OFFSET(pin)
#defineS3C2410_GPIO_OFFSET(pin)((pin)31)//用此宏能得出偏移量
if(pinS3C2410_GPIO_BANKB){//判斷I/O口是不是屬于GPA,mask=1S3C2410_GPIO_OFFSET(pin);//設(shè)置屏蔽碼
}else{
mask=3S3C2410_GPIO_OFFSET(pin)*2;//設(shè)置屏蔽碼
}

分析:local_irq_save(flags);
這個(gè)與下面出現(xiàn)的local_irq_restore(flags);成對(duì)使用,用于關(guān)閉、打開(kāi)中斷,同時(shí)將中斷的標(biāo)志存儲(chǔ)在flags中。
分析:__raw_readl(base 0x00);__raw_writel(con,base 0x00);
con=__raw_readl(base 0x00);//讀取控制寄存器數(shù)據(jù)
con=~mask;//屏蔽掉相應(yīng)的位
con|=function;//設(shè)置要設(shè)置的位

__raw_writel(con,base 0x00);//把改變后的數(shù)據(jù)寫(xiě)回控制寄存器

上面的是兩個(gè)函數(shù)宏,定義如下
#define__raw_writeb(v,a)(__chk_io_ptr(a),*(volatileunsignedchar__force*)(a)=(v))#define__raw_writew(v,a)(__chk_io_ptr(a),*(volatileunsignedshort__force*)(a)=(v))#define__raw_writel(v,a)(__chk_io_ptr(a),*(volatileunsignedint__force*)(a)=(v))PS(ZXX):先檢查指針a是否合法,然后將數(shù)值v寫(xiě)入a所指向的空間。
三種類(lèi)型分別對(duì)應(yīng)char,short,int#define__raw_readb(a)(__chk_io_ptr(a),*(volatileunsignedchar__force*)(a))#define__raw_readw(a)(__chk_io_ptr(a),*(volatileunsignedshort__force*)(a))#define__raw_readl(a)(__chk_io_ptr(a),*(volatileunsignedint__force*)(a))PS(ZXX):先檢查指針a是否合法,然后讀取a所指向的空間的數(shù)值。三種類(lèi)型分別對(duì)應(yīng)char,short,int

5.分析s3c2410_gpio_setpin(led_table[i],0)
voids3c2410_gpio_setpin(unsignedintpin,unsignedintto)
{
void__iomem*base=S3C24XX_GPIO_BASE(pin);
unsignedlongoffs=S3C2410_GPIO_OFFSET(pin);
unsignedlongflags;
unsignedlongdat;

local_irq_save(flags);

dat=__raw_readl(base 0x04);
dat=~(1offs);
dat|=tooffs;
__raw_writel(dat,base 0x04);
local_irq_restore(flags);
}
有了上述的對(duì)s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i])的分析,上面的代碼大同小異罷了,只是說(shuō)一下__raw_readl(base 0x04);這個(gè),這是對(duì)數(shù)據(jù)寄存器進(jìn)行操作,看datasheet就知道,每組的GPXDAT的地址值都比GPXCON的地址值大4。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

樹(shù)莓派,(英語(yǔ):Raspberry Pi,簡(jiǎn)寫(xiě)為RPi,別名為RasPi / RPI)是為學(xué)習(xí)計(jì)算機(jī)編程教育而設(shè)計(jì),只有信用卡大小的微型電腦,其系統(tǒng)基于Linux。隨著Windows 10 IoT的發(fā)布,用戶可以用上運(yùn)行...

關(guān)鍵字: 樹(shù)莓派 gpio gpio編程

現(xiàn)在的LED越來(lái)越多,不斷地裝飾著我們的生活,那么你知道LED驅(qū)動(dòng)嗎?它有什么作用?LED技術(shù)推動(dòng)照明領(lǐng)域的一場(chǎng)革命。因結(jié)合小型、低功耗、高可靠性和低成本,使得照明可以在不可能使用白熾燈或熒光燈技術(shù)的地方實(shí)現(xiàn)。因此,LE...

關(guān)鍵字: LED 驅(qū)動(dòng)led 照明

串行外設(shè)接口(SPI)是微控制器和外圍IC(如傳感器、ADC、DAC、移位寄存器、SRAM等)之間使用最廣泛的接口之一。本文先簡(jiǎn)要說(shuō)明SPI接口,然后介紹ADI公司支持SPI的模擬開(kāi)關(guān)與多路轉(zhuǎn)換器,以及它們?nèi)绾螏椭鷾p少系...

關(guān)鍵字: gpio spi 串行外設(shè)接口

利用AT89S51單片機(jī)的P0端口的P0.0-P0.7連接到一個(gè)共陰數(shù)碼管的a-h的筆段上,數(shù)碼管的公共端接地。在數(shù)碼管上循環(huán)顯示0-9數(shù)字,時(shí)間間隔0.2秒。

關(guān)鍵字: 51單片機(jī) io口 數(shù)碼管 驅(qū)動(dòng)led

一、什么是GPIO? GPIO,英文全稱(chēng)為General-Purpose IO ports,也就是通用IO口。嵌入式系統(tǒng)中常常有數(shù)量眾多,但是結(jié)構(gòu)卻比較簡(jiǎn)單的外部設(shè)備/電路,對(duì)這些設(shè)備/電路有的需要C

關(guān)鍵字: gpio 通用io口

移植環(huán)境1,主機(jī)環(huán)境:VMare下CentOS 5.5 ,1G內(nèi)存。2,集成開(kāi)發(fā)環(huán)境:Elipse IDE3,編譯編譯環(huán)境:arm-linux-gcc v4.4.3,arm-none-eabi-gcc v4.5.1。4,...

關(guān)鍵字: mini2440 u-boot 移植 dm9000驅(qū)動(dòng)

移植環(huán)境1,主機(jī)環(huán)境:VMare下CentOS 5.5 ,1G內(nèi)存。2,集成開(kāi)發(fā)環(huán)境:Elipse IDE3,編譯編譯環(huán)境:arm-linux-gcc v4.4.3,arm-none-eabi-gcc v4.5.1。4,...

關(guān)鍵字: eeprom i2c mini2440 u-boot 移植

//**********************************************************************//************************************...

關(guān)鍵字: gpio STM32

GPIO(General Purpose I/O Ports)意思為通用輸入/輸出端口,通俗地說(shuō),就是一些引腳,可以通過(guò)它們輸出高低電平或者通過(guò)它們讀入引腳的狀態(tài)-是高電平或是低電平。 S3C2410共有117個(gè)I...

關(guān)鍵字: ARM gpio 硬件介紹

Ⅰ、寫(xiě)在前面完事開(kāi)頭難,只要肯努力;師傅領(lǐng)進(jìn)門(mén),修行看個(gè)人;當(dāng)你看到本文,說(shuō)明你是幸運(yùn)的,作者接下來(lái)推出的一系列STM8S教程,將助你踏入STM8S的世界。本文是STM8S教程的開(kāi)始,寫(xiě)給剛?cè)腴T(mén)STM8S的朋友。學(xué)習(xí)本文

關(guān)鍵字: gpio stm8s 基礎(chǔ)知識(shí)
關(guān)閉