日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀]設(shè)備通常會提供一組寄存器來用于控制設(shè)備、讀寫設(shè)備和獲取設(shè)備狀態(tài),即控制寄存器、數(shù)據(jù)寄存器和狀態(tài)寄存器。這些寄存器可能位于IO空間,也可能位于內(nèi)存空間。當位于IO空間時,通常被稱為IO端口,位于內(nèi)存空間時,對

設(shè)備通常會提供一組寄存器來用于控制設(shè)備、讀寫設(shè)備和獲取設(shè)備狀態(tài),即控制寄存器、數(shù)據(jù)寄存器和狀態(tài)寄存器。這些寄存器可能位于IO空間,也可能位于內(nèi)存空間。當位于IO空間時,通常被稱為IO端口,位于內(nèi)存空間時,對應(yīng)的內(nèi)存空間成為IO內(nèi)存。

1. Linux IO端口和IO內(nèi)存訪問接口
1.1 IO端口
在Linux設(shè)備驅(qū)動中,應(yīng)使用Linux內(nèi)核提供的函數(shù)來訪問定位于IO空間的端口,這些函數(shù)包括如下幾種:
(1)讀寫字節(jié)端口(8位寬)
unsigned inb(unsigned port);
void outb(unsigned char byte , unsigned port);

(2)讀寫字端口(16位寬)
unsigned inw(unsigned port);
void outw(unsigned char byte , unsigned port);

(3)讀寫長字端口(32位寬)
unsigned inl(unsigned port);
void outl(unsigned char byte , unsigned port);

(4)讀寫一串字
void insw(unsigned port , void *addr , unsigned long count);
void outsw(unsigned port , void *addr , unsigned long count);

(5)讀寫一串長字
void insl(unsigned port , void *addr , unsigned long count);
void outsl(unsigned port , void *addr , unsigned long count);
上述各函數(shù)中IO端口號port的類型高度依賴于具體的硬件平臺,因此,只是寫出了unsigned。

1.2 IO內(nèi)存
在內(nèi)核中訪問IO內(nèi)存之前,需首先使用ioremap()函數(shù)將設(shè)備所處的物理地址映射到虛擬地址。ioremap的原型如下:
void *ioremap(unsigned long offset , unsigned long size);
ioremap()與vmalloc()類似,也需要建立新的頁表,但是它并不進行vmalloc()中所執(zhí)行的內(nèi)存分配行為。ioremap()返回一個特殊的虛擬地址,該地址可用來存取特定的物理地址范圍。通過ioremap()獲得的虛擬地址應(yīng)該被iounmap()函數(shù)釋放,其原型為:
void iounmap(void *addr);
在設(shè)備的物理地址被映射到虛擬地址之后,盡管可以直接通過指針訪問這些地址,但是可以使用Linux內(nèi)核的如下一組函數(shù)來完成設(shè)備內(nèi)存映射的虛擬地址的讀寫,這些函數(shù)如下所示。
(1)讀IO內(nèi)存
unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);
與上述函數(shù)對應(yīng)的較早版本的函數(shù)為(這些函數(shù)在Linux2.6中仍然被支持):
unsigned readb(address);
unsigned readw(address);
unsigned readl(address);

(2)寫IO內(nèi)存
void iowrite8(u8 value , void *addr);
void iowrite16(u16 value , void *addr);
void iowrite32(u32 value , void *addr);
與上述函數(shù)對應(yīng)的較早版本的函數(shù)為(這些函數(shù)在Linux2.6中仍然被支持):
unsigned writeb(address);
unsigned writew(address);
unsigned writel(address);

(3)讀一串IO內(nèi)存
void ioread8_rep(void *addr , void *buf , unsigned long count);
void ioread16_rep(void *addr , void *buf , unsigned long count);
void ioread32_rep(void *addr , void *buf , unsigned long count);

(4)寫一串IO內(nèi)存
void iowrite8_rep(void *addr , void *buf , unsigned long count);
void iowrite16_rep(void *addr , void *buf , unsigned long count);
void iowrite32_rep(void *addr , void *buf , unsigned long count);

(5)復(fù)制IO內(nèi)存
void memcpy_fromio(void *dest , void *source , unsigned int count);
void memcpy_toio(void *dest , void *source , unsigned int count);

(6)設(shè)置IO內(nèi)存
void memset_io(void *addr , u8 value , unsigned int count);

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

2. 申請與釋放設(shè)備IO端口和IO內(nèi)存
2.1 IO端口申請
Linux內(nèi)核提供了一組函數(shù)用于申請和釋放IO端口。
struct resource *request_region(resource_size_t start, resource_size_t n, const char *name);
這個函數(shù)向內(nèi)核申請了n個端口,這些端口從first開始,name參數(shù)為設(shè)備的名稱。如果分配成功返回非NULL,失敗,則返回NULL。
當用request_region()申請的IO端口使用完成后,應(yīng)當使用release_region()函數(shù)將它們還給系統(tǒng),這個函數(shù)的原型如下:
void release_region(resource_size_t start , resource_size_t n);

2.2 IO內(nèi)存申請
Linux內(nèi)核提供了一組函數(shù)用于申請和釋放IO內(nèi)存的范圍。
struct resource *request_mem_region(resource_size_t start, resource_size_t n, const char *name, const char *name);
這個函數(shù)向內(nèi)核申請n個內(nèi)存地址,這些地址從first開始,name參數(shù)為設(shè)備的名稱。如果分配成功返回值是非NULL,如果失敗,返回NULL。
當用request_mem_region()申請的IO內(nèi)存使用完成后,應(yīng)當使用release_region()函數(shù)將它們還給系統(tǒng),這個函數(shù)的原型如下:
void release_region(resource_size_t start , resource_size_t n);
上述request_region()和release_mem_region()都不是必須的,但建議使用。其任務(wù)是檢查申請的資源是否可用,如果可用則申請成功,并標志為已經(jīng)使用,其他驅(qū)動想再次申請該資源就會失敗。
查看內(nèi)核源碼可知,request_region()和request_mem_region()調(diào)用的函數(shù)是一樣的,只是傳入?yún)?shù)的不同。
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name))

3. 設(shè)備IO端口和IO內(nèi)存訪問流程
IO端口訪問的一種途徑是直接使用IO端口操作函數(shù):在設(shè)備打開或驅(qū)動模塊被加載時申請IO端口區(qū)域,之后使用inb()、outb()等進行端口訪問,最后,在設(shè)備關(guān)閉或驅(qū)動被卸載時釋放IO端口范圍。
___________________________
||
| request_region() | 在設(shè)備驅(qū)動模塊加載或open()函數(shù)中進行
|__________________________|
|
___________________________
| |
| inb()、outb()等 | 在設(shè)備驅(qū)動初始化、write()、read()、iotcl()等函數(shù)中進行
|__________________________ |
|
___________________________
| |
| release_region()等 | 在設(shè)備驅(qū)動模塊卸載或release()函數(shù)中進行
|__________________________ |
IO端口的訪問流程(不映射到內(nèi)存空間)

IO端口訪問的另一種途徑是將IO端口映射為內(nèi)存進行訪問:在設(shè)備打開或驅(qū)動模塊被加載時,申請IO端口區(qū)域并使用ioport_map()映射到內(nèi)存,之后使用IO內(nèi)存的函數(shù)進行端口訪問,最后,在設(shè)備關(guān)閉或驅(qū)動被卸載時釋放IO端口并釋放映射。整個流程如下圖所示:
___________________________
| |
| request_region()等 |
|__________________________ |
| 在設(shè)備驅(qū)動模塊加載或open()函數(shù)中進行
___________________________ /
| | /
| ioport_map()等 |
|__________________________ |
|
___________________________
| |
| ioread8、ioread16、 | 在設(shè)備驅(qū)動初始化、write()、read()、ioctl等函數(shù)中調(diào)用
| ioread32、iowrite8等|
|__________________________ |
|
___________________________
| |
| ioport_unmap()|
|__________________________ |
|
___________________________ /在設(shè)備驅(qū)動卸載或release()函數(shù)中調(diào)用
| | /
| release_region()| /
|__________________________ |
IO端口的訪問流程(映射到內(nèi)存空間)

___________________________________
| |
| request_mem_region()等|
|__________________________________ |
| 在設(shè)備驅(qū)動模塊加載或open()函數(shù)中進行
__________________________________ /
| | /
| ioremap()等 |/
|__________________________________|
|
___________________________
| |
| ioread8、ioread16、 | 在設(shè)備驅(qū)動初始化、write()、read()、ioctl等函數(shù)中調(diào)用
| ioread32、iowrite8等 |
|__________________________ |
|
______________________________
| |
| iounmap() |
|_____________________________ |
|
______________________________ /在設(shè)備驅(qū)動卸載或release()函數(shù)中調(diào)用
| | /
| release_mem_region() | /
|______________________________|

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

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉