www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式硬件
[導(dǎo)讀]引 言在32位微處理器逐漸成為嵌入式系統(tǒng)主流的同時(shí),嵌入式應(yīng)用也變得越來(lái)越復(fù)雜。許多嵌入式系統(tǒng)都不得不借助于專用的操作系統(tǒng)來(lái)支撐自己的應(yīng)用。uClinux作為類Unix操作系

引 言

在32位微處理器逐漸成為嵌入式系統(tǒng)主流的同時(shí),嵌入式應(yīng)用也變得越來(lái)越復(fù)雜。許多嵌入式系統(tǒng)都不得不借助于專用的操作系統(tǒng)來(lái)支撐自己的應(yīng)用。uClinux作為類Unix操作系統(tǒng),繼承了Linux的各種優(yōu)秀的品質(zhì),成為首選的嵌入式系統(tǒng)的操作系統(tǒng)。

為自己的設(shè)備在操作系統(tǒng)下添加驅(qū)動(dòng)程序,是嵌入式設(shè)計(jì)必不可少的部分。針對(duì)不同的設(shè)備類型,選擇合適的驅(qū)動(dòng)程序的模式,同樣也是十分重要的。通常的設(shè)備驅(qū)動(dòng)采用直接I/O的方式,如存儲(chǔ)器、看門(mén)狗等;而對(duì)于象網(wǎng)絡(luò)這樣的數(shù)據(jù)流設(shè)備的驅(qū)動(dòng),則應(yīng)該用到中斷機(jī)制。

本文以u(píng)Clinux為背景,以一種數(shù)據(jù)流設(shè)備為目標(biāo),介紹中斷驅(qū)動(dòng)的I/O設(shè)備驅(qū)動(dòng)的開(kāi)發(fā)。

1 應(yīng)用背景

1.1 硬件描述

本文介紹的驅(qū)動(dòng)程序是應(yīng)用在一種電信E1線路和以太網(wǎng)互聯(lián)設(shè)備上的。它是旁路接收E1數(shù)據(jù)并將其發(fā)送到以太網(wǎng)的某一臺(tái)服務(wù)器上,在服務(wù)器上對(duì)E1的話路和信令時(shí)隙分析。

該設(shè)備中的處理器是采用三星公司出品的網(wǎng)絡(luò)型ARM處理器S3C4510B。E1線路接口采用Dallas半導(dǎo)體公司的專用El接口單元(LIU)芯片 DS2148,它完成波形整理、時(shí)鐘恢復(fù)和HDB3解碼。DS2148將整理后的E1數(shù)據(jù)流送給一片Altera公司的Cyclone系列的 FPGA(EPlC3T144C8),它將串行的E1數(shù)據(jù)流存入到FIFO,再通過(guò)ARM的32位外部總線將數(shù)據(jù)傳送給ARM。ARM將數(shù)據(jù)打包通過(guò)以太網(wǎng)發(fā)送到服務(wù)器上。圖l所示是本系統(tǒng)的硬件框圖。本文主要介紹接在ARM的外部總線上的FPGA,在uClinux下的驅(qū)動(dòng)程序中斷機(jī)制的設(shè)計(jì)。

1.2硬件連接

S3C4510B處理器和FPGA的連接電路如圖2所示。

 

 

1.3 FPGA內(nèi)FIFO的結(jié)構(gòu)

在FPGA內(nèi)部設(shè)置了兩個(gè)FIFO。為了防止ARM和FPGA操作的沖突,ARM和FPGA對(duì)兩個(gè)FIFO操作采用乒乓方式,這樣ARM和FPGA就可以同時(shí)操作不同的FIFO,而不需要等待。FIFO的大小是4096位,能容納一個(gè)E1復(fù)幀的數(shù)據(jù)量。當(dāng)FPGA將一個(gè)FIFO填滿后,會(huì)用中斷的方式通知ARM來(lái)讀FIFO,同時(shí)FPGA會(huì)置內(nèi)部的F1FO狀態(tài)寄存器。 FIFO)狀態(tài)寄存器命名為fpga_imf,是一個(gè)32位的寄存器,用其中某幾位置“l”,表示對(duì)應(yīng)的FIFO需要讀取。

2 軟件設(shè)計(jì)

中斷驅(qū)動(dòng)的I/O是指,輸人數(shù)據(jù)在中斷期間被填充到緩沖區(qū)內(nèi),并由讀取該設(shè)備的進(jìn)程取走緩沖區(qū)內(nèi)的數(shù)據(jù);輸出緩沖區(qū)由寫(xiě)設(shè)備的進(jìn)程填充,并在中斷期間取走數(shù)據(jù)。數(shù)據(jù)緩沖可以將數(shù)據(jù)的發(fā)送和接收與write及read系統(tǒng)調(diào)用分離開(kāi)來(lái),提高系統(tǒng)的整體性能。下面是uCllnux下的中斷程序的設(shè)計(jì)。

2.1 uClinux下的中斷程序

在uClinux系統(tǒng)中,通過(guò)調(diào)用下面這個(gè)函數(shù)向系統(tǒng)申請(qǐng)一個(gè)中斷通道(或中斷請(qǐng)求IRQ),并在處理完以后釋放掉它。

mt reqLIest_irq(unsigned int irq,void(*handler)(int,vold*,

struct pt_regs*),unsigned 10ng flags,const chat*device,

vold*dev_id);

void free_irq(unstgned int lrq,VOid*dev_id);

其中,irq是中斷號(hào)。在本系統(tǒng)中它對(duì)應(yīng)于S3C4510B的21個(gè)中斷源。這里用的是中斷源O。handler指向要安裝的中斷處理函數(shù)的指針。 flags是一個(gè)與中斷管理有關(guān)的各種選項(xiàng)的字節(jié)掩碼。device傳遞給request_irq的字符串,在/proc/interrupts中用于顯示中斷的擁有者。dev_id指針用于共享的中斷信號(hào)線。函數(shù)的返回值為O時(shí)表示成功,或者返回一個(gè)負(fù)的錯(cuò)誤碼。函數(shù)返回一EBUJSY通知另一個(gè)設(shè)備驅(qū)動(dòng)程序已經(jīng)使用了要申請(qǐng)的中斷信號(hào)線。下面是FPGA的設(shè)備中斷申請(qǐng)函數(shù)。這個(gè)函數(shù)是在驅(qū)動(dòng)中的fpga_open函數(shù)中被調(diào)用的。

int fpga_open(struct inode*inocle,stuct_file*file){

int result;

result=request_irq(FPGA_IRQ,δfpga_isr,SA_INTER-RUPT,″fpga″,NULL);

if(resuIt!=O){

printk(KERN_INFO”Can not register FPGA ISR!n”);}else{

printk(KERN_INFO″FPGA ISR Register successfully!n”);

}

}

在申請(qǐng)了中斷通道后,系統(tǒng)會(huì)響應(yīng)外部中斷0,而進(jìn)入中斷處理程序。中斷處理程序的第一步是要先清除S3C4510B的中斷懸掛寄存器的外部中斷O位。這是為了讓FPGA可以產(chǎn)生新的中斷。在uClinux系統(tǒng)中是調(diào)用下面的宏來(lái)實(shí)現(xiàn)的。

#deflne CLEAR_PEND_INT(n) IntPend=(1<<(n))

中斷處理程序功能就是將有關(guān)中斷接收的信息反饋給設(shè)備,并根據(jù)要服務(wù)的中斷的不同含義相應(yīng)地對(duì)數(shù)據(jù)進(jìn)行讀寫(xiě)。所以FPGA的中斷處理的主要任務(wù)是,讀取 FPGA中FIFO狀態(tài)寄存器的值,獲取需要讀取的FIFO的信息并安排接收數(shù)據(jù)。在程序中用到了系統(tǒng)提供的inl函數(shù)。

unmgned mt status

status=inl(FPGA_IMF);

中斷處理程序的執(zhí)行應(yīng)盡可能的短,而從FPGA中接收數(shù)據(jù),一次必須讀完一個(gè)FIFO及128字。這是一個(gè)需要較長(zhǎng)時(shí)間的外部I/O操作,所以把這個(gè)操作放到中斷處理的底半部(bottom-haIf)來(lái)完成。下面介紹中斷處理的底半部的設(shè)計(jì)。

2.2 BH機(jī)制

底半部處理程序和上半部最大的不同就在于,在執(zhí)行BH時(shí)所有的中斷都是打開(kāi)的,所以說(shuō)它是在“更安全”時(shí)間內(nèi)運(yùn)行。2.4版本的uClinux內(nèi)核有三種機(jī)制來(lái)實(shí)現(xiàn)底半部的處理:軟中斷、tasklet和BH。在這里選用了較為簡(jiǎn)單的BH機(jī)制。

BH機(jī)制實(shí)際上是一個(gè)任務(wù)隊(duì)列,中斷處理程序?qū)⒁幚淼娜蝿?wù)插到特定的任務(wù)隊(duì)列中等待內(nèi)核執(zhí)行。內(nèi)核維護(hù)著多個(gè)任務(wù)隊(duì)列,但驅(qū)動(dòng)程序只能用前三種:

①tq_scheduler隊(duì)列。當(dāng)調(diào)度器被運(yùn)行時(shí),該隊(duì)列就會(huì)被處理。因?yàn)榇藭r(shí)調(diào)度器在被調(diào)度出的進(jìn)程的上下文中運(yùn)行,所以該隊(duì)列中的任務(wù)幾乎可以做任何事。它們不會(huì)在中斷時(shí)運(yùn)行。

②tq_timer隊(duì)列。該隊(duì)列由定時(shí)器隊(duì)列處理程序(timertick)運(yùn)行,因?yàn)樵撎幚沓绦蚴窃谥袛鄷r(shí)問(wèn)運(yùn)行的。該隊(duì)列中的所有任務(wù)就也是在中斷時(shí)間內(nèi)運(yùn)行的。[!--empirenews.page--]

③tu_lmmediate隊(duì)列。立即隊(duì)列在系統(tǒng)調(diào)用返回時(shí)或調(diào)度器運(yùn)行時(shí)盡快得到處理的(不管兩種情況誰(shuí)先發(fā)生了)。該隊(duì)列是在中斷時(shí)間內(nèi)得到處理的。

隊(duì)列元素由下面的結(jié)構(gòu)來(lái)描述:

structtq_struct

structq_struct*mext  /*激活的BH的鏈接表*/

unsigned 1ong sync;  /*必須初始化為零*/

void(*outine)(vold*);  /*調(diào)用的函數(shù)*/

void*data;       /*傳遞給函數(shù)的參數(shù)*/

};

上面的數(shù)據(jù)結(jié)構(gòu)中最重要的字段是rotltine和data。將要延遲的任務(wù)插入隊(duì)列,必須先設(shè)置好結(jié)構(gòu)的這些字段,并把next和sync兩個(gè)字段清零。結(jié)構(gòu)中的sync標(biāo)志位用于避免同一任務(wù)被插人多次,這會(huì)破壞next指針。一旦任務(wù)被排人隊(duì)列,該數(shù)據(jù)結(jié)構(gòu)就被認(rèn)為是內(nèi)核“擁有”了,不能再被修改。

在FPGA的驅(qū)動(dòng)中,定義了一個(gè)任務(wù)隊(duì)列元素用于完成底半部分:

struct tq_struct el_task;

unsigned int el_line;

el_line數(shù)組用來(lái)保存?zhèn)鬟f給任務(wù)的參數(shù)。在打開(kāi)FPGA時(shí)要對(duì)任務(wù)隊(duì)列結(jié)構(gòu)賦值:

el_task.routine=fpga_bh;

e1 task.data=&e1_line:

上面的fpga_bh是底半部分處理函數(shù)void fpga_bh(unsigned int*line)的函數(shù)名,el_line是傳遞給fpga_bh函數(shù)的實(shí)參。

與任務(wù)隊(duì)列有關(guān)的還有下面的函數(shù):

void queue_task(struct tq_struet*task,task_queue*List);

正如該函數(shù)的名字,本函數(shù)用于將任務(wù)排進(jìn)隊(duì)列中。它關(guān)閉了中斷,避免了競(jìng)爭(zhēng),因此可以被模塊中任一函數(shù)調(diào)用。FPGA的任務(wù)被插入到tq_immediate隊(duì)列中,所以,list被賦值為&tq_immediate。

當(dāng)某段代碼需要調(diào)度運(yùn)行下半部處理時(shí),只要調(diào)用mark_bh即可:

void mark_bh(int nr);

這里,nr是激活的BH的類型。這個(gè)數(shù)是在頭文件中定義的一個(gè)符號(hào)常數(shù)。每個(gè)下半部BH相應(yīng)的處理函數(shù)由擁有它的那個(gè)驅(qū)動(dòng)程序提供。

完成任務(wù)隊(duì)列元素設(shè)置后,中斷處理函數(shù)中就可以啟用BH機(jī)制。在讀得fpga_imf的值后將其賦給el_line,然后調(diào)用queue_task將任務(wù)插入到tq_immediate隊(duì)列中,再調(diào)用mark_bh(IMMEDIATE_BH),啟動(dòng)底半部分處理。到此,中斷處理程序就可以退出了。

2.3底半部分處理程序和緩沖區(qū)

uClinux操作系統(tǒng)退出中斷處理程序后,會(huì)立即將tq_immediate隊(duì)列中任務(wù)投入運(yùn)行,其中也有fpga_bh函數(shù)。在進(jìn)入fpga_bh 同時(shí),系統(tǒng)會(huì)將el_line的地址作為實(shí)參傳遞給形參line。也就是將FIFO狀態(tài)寄存器(fpga_imf)的值間接傳給了底半部處理程序。底半部分程序中會(huì)檢查這個(gè)值的每一位,據(jù)此決定需要讀的FIFO。

從FIFO中讀上來(lái)的數(shù)據(jù)都是存放在內(nèi)核的緩沖區(qū)中的。因?yàn)槊恳粋€(gè)FIFO的容量是一個(gè)E1的復(fù)幀,所以內(nèi)核的緩沖也是以E1復(fù)幀的大小為一個(gè)緩沖塊。緩沖塊用鏈表串連起來(lái)。緩沖單元的數(shù)據(jù)結(jié)構(gòu)如下:

struct buf_struct{

struct list_head list;  /*鏈表頭*/

unsigned int buf_size;  /*數(shù)據(jù)塊的大小*/

unsigned int*buLhead;  /*緩沖塊的指針*/

unsigned int*buL_curl  /*緩沖塊當(dāng)前指針*/

};

buf_size說(shuō)明了數(shù)據(jù)塊的大小。這是一個(gè)以“字”為單位的數(shù)值。緩沖塊在內(nèi)核堆區(qū)開(kāi)辟,buf_head指向?qū)嶋H的緩沖塊的首地址,而buf_cur指向緩沖塊中正在操作的單元。為了使用鏈表機(jī)制,驅(qū)動(dòng)必須包含頭文件。其中定義了list_head類型結(jié)構(gòu):

struct list_head{

struct list_head*next.*prev;

為了訪問(wèn)緩沖塊鏈表,還要建立一個(gè)鏈表頭,在驅(qū)動(dòng) 中定義全局變量:?

struct list_head read_list;

鏈表頭必須是一個(gè)獨(dú)立的list_head結(jié)構(gòu)。在使用之前,必須用INIT_LIST_HEAD宏來(lái)初始化鏈表頭:

INIT_LIST_HEAD(&readlist); I

Linux系統(tǒng)提供了鏈表的操作函數(shù),在頭文件中:

list_add(struet list_head*new,struct list_head*head);  /*在鏈表頭后插入一個(gè)新項(xiàng)*/

list_add_tail(stuot list_head*new,struet list_head*head); /*在鏈表尾部添加一個(gè)新項(xiàng)*/

list_del(struet_list_head*entry);     /*將給定項(xiàng)從鏈表中刪除*/

list_empty(struct list_head*head)    /*判斷鏈表是否為空*/

list_entry(struct list_head。ptr,type_of_struet,field_ name); /*訪問(wèn)包含鏈表頭的結(jié)構(gòu)*/

其中l(wèi)ist_entry的作用是一個(gè)1ist_head結(jié)構(gòu)指針映射回一個(gè)指向包含它的大結(jié)構(gòu)的指針。ptr是指向structlist_head結(jié)構(gòu)的指針,type_of_struct是包含ptr的結(jié)構(gòu)類型,field_name是結(jié)構(gòu)中鏈表字段的名字。如可以用這個(gè)宏將指向數(shù)據(jù)緩沖塊的鏈表指針(readl)映射為緩沖塊結(jié)構(gòu)指針(buf):

struet buf_strcut*buf=list_entry(real,struct buf_struct,list);

底半部分處理程序中,內(nèi)核緩沖塊是動(dòng)態(tài)分配的。因?yàn)轵?qū)動(dòng)程序是內(nèi)核的一部分,所以在內(nèi)核堆區(qū)開(kāi)辟緩沖區(qū)就要用專用的函數(shù),在頭文件定義了如下函數(shù):

void*kmalloc(size t size,int flags);/*在內(nèi)核堆中分配size大小的空問(wèn)*/

void kfree(void*obi/*釋放kmalloc分配的空間*/

kmalloc函數(shù)的第1個(gè)參數(shù)是size(大小),第2個(gè)參數(shù)是優(yōu)先權(quán)。最常用的優(yōu)先權(quán)是GFP_KERNEL,它的意思是該內(nèi)存分配是由運(yùn)行在內(nèi)核態(tài)的進(jìn)程調(diào)用的。有時(shí)kmalloc是在進(jìn)程上下文之外調(diào)用的,比如在中斷處理、任務(wù)隊(duì)列處理和內(nèi)核定時(shí)器處理時(shí)發(fā)生。這些情況下,current進(jìn)程就不應(yīng)該進(jìn)入睡眠狀態(tài),這時(shí)應(yīng)該就使用優(yōu)先權(quán)GFP_ATOMIC。

不要過(guò)于頻繁地用kmalloc在內(nèi)核堆中分配空間,因?yàn)樵诜峙淇臻g時(shí)可能有中斷到來(lái),這樣是不安全的。在驅(qū)動(dòng)中建立另一個(gè)鏈表用于回收使用過(guò)的緩沖塊。在驅(qū)動(dòng)中用free_1ist作為回收緩沖塊的鏈表頭:

struct list_head free_list;

這樣就存在兩個(gè)鏈表:一個(gè)是裝載著數(shù)據(jù)的鏈表,一個(gè)是已經(jīng)使用過(guò)的緩沖塊的鏈表(稱為自由鏈表)。那么只要自由鏈表中還有表項(xiàng),在需要緩沖塊時(shí)就可以直接從自由鏈表中取出一個(gè)使用,而不用kmalloc再去分配。

2.4 阻塞型I/O和自旋鎖的使用

在驅(qū)動(dòng)程序中,read的工作是將內(nèi)核緩沖區(qū)中拷貝到用戶空間。在進(jìn)行這種操作時(shí)有兩種情況是應(yīng)該注意的:[!--empirenews.page--]

①當(dāng)read時(shí)發(fā)現(xiàn)讀鏈表是空,也就是還沒(méi)有數(shù)據(jù)可讀。

這種情況下,可以讓read立即返回一EAGAIN,告知用戶進(jìn)程沒(méi)有讀到數(shù)據(jù);另一個(gè)辦法就是實(shí)現(xiàn)阻塞型I/O,在沒(méi)有數(shù)據(jù)可讀時(shí)讓用戶進(jìn)程進(jìn)入睡眠狀態(tài)并等待數(shù)據(jù)。

有幾種處理和喚醒的方法,都要處理同一個(gè)基本的數(shù)據(jù)類型——等待隊(duì)列(walt_queue_head_t),就是由正在等待某事件發(fā)生的進(jìn)程組成的一個(gè)隊(duì)列。使用之前必須聲明和初始化,在驅(qū)動(dòng)程序中是如下聲明的:

wait_queue_head_t read_Jqueue;

init_waitqueue_head(&read_queue);

可以調(diào)用如下函數(shù)之一讓進(jìn)程進(jìn)入睡眠狀態(tài):

void wait_evet(wait_queue_head_ queue,int condition);

int wait_evem_interruptible(Walt_queue_hean_t queue,int condition);

這兩個(gè)函數(shù)把等待事件和測(cè)試事件是否發(fā)生合并起來(lái)。調(diào)用之后,進(jìn)程會(huì)一直睡眠到C布爾表達(dá)式condition為真時(shí)為止。在驅(qū)動(dòng)中的read函數(shù)中,判斷讀鏈表為空,就調(diào)用它進(jìn)入睡眠:

while(1ist_efnpty(&read_list)){

If(filp一>f_flags δO_NoNBLOCK)/*如果設(shè)置成非阻塞I/o*/

return—EAGAIN;

if(wait_evert_interruptible(read_queue,!list_empty(δread_list))) return—ERESTARTSYS;

}

對(duì)應(yīng)上面的函數(shù),要喚醒進(jìn)程可以調(diào)用下面的函數(shù):

wake_up(wait_queue_gead_t*queue);

wake_up_jnterruptlbk(wait_queue_head_t*queue);

驅(qū)動(dòng)程序應(yīng)該在數(shù)據(jù)到來(lái)后及時(shí)喚醒進(jìn)程,也就是從FIFO讀取數(shù)據(jù)后,在退出底半部處理程序前執(zhí)行:

wake_up_mterIuptible(&read_queue);

要指出的是被喚醒并不保證等待的事件發(fā)生了,所以從睡眠態(tài)返回后,應(yīng)該循環(huán)測(cè)試condition。

②當(dāng)read操作正在訪問(wèn)某一個(gè)鏈表時(shí),底半程序也要訪問(wèn)同一個(gè)鏈表。這樣是比較危險(xiǎn)的,應(yīng)該避免。

為了避免這種情況的發(fā)生,這里使用自旋鎖。在read操作訪問(wèn)鏈表前獲得鎖,訪問(wèn)結(jié)束時(shí)解鎖。底半部要訪問(wèn)鏈表時(shí)先要檢查自旋鎖是否已上鎖,如果有,則等待到鎖可用。

自旋鎖使用類型spinlock_t來(lái)描述。自旋鎖被聲明和初始化為不加鎖狀態(tài)方式如下:

spinlock_t1ist_10ck=SPIN_LoCK_UNLOCKED;

處理自旋鎖的函數(shù)如下:

spill_1ock_bh(Spllalock-t*1ock);

spin_unloek_bh(splnlock_t*lock);

這里使用獲得自旋鎖并且阻止底半部執(zhí)行的函數(shù),就可以完全保證底半部程序不會(huì)在read操作訪問(wèn)鏈表時(shí)來(lái)訪問(wèn)鏈表。程序中如下實(shí)現(xiàn):

spln_lock_bh(&list_lock);

list_del(readl); /*將使用后的緩沖塊從讀鏈表中刪除*/

list_add_tail(readI,&free_list);/*將使用后的緩沖塊插入自由鏈表中*/

spin_unlock_bh(&list_lock);

2.5中斷驅(qū)動(dòng)的I/O

至此,可以完整地描述ARM與FPGA之間數(shù)據(jù)流動(dòng)的過(guò)程:當(dāng)FPGA的一個(gè)FIFO滿后,向ARM發(fā)出中斷,ARM進(jìn)入中斷處理程序后,讀取FPGA 中的FlFO狀態(tài)寄存器(fpga_imf)的值,然后把一個(gè)任務(wù)插到立即隊(duì)列(tq_imrnediate)中,啟動(dòng)底半部分(BH),同時(shí)將 FIFO)狀態(tài)寄存器的值傳遞給底半部分處理程序(fpga_bh),完成這些工作后退出中斷處理程序。進(jìn)入底半部分處理程序后,根據(jù)FIFO狀態(tài)寄存器的值確定要處理的F1F0。從FIFO中將數(shù)據(jù)讀出存人到內(nèi)核緩沖塊中,這個(gè)緩沖塊可能是從自由隊(duì)列(free_list)中取出來(lái)的一個(gè)。如果自由隊(duì)列中是空的,就新分配一個(gè)緩沖塊。接下來(lái)將填好的緩沖塊加到讀隊(duì)列(read-list)中,并喚醒睡眠的進(jìn)程,這樣底半部分的工作也完成了。當(dāng)用戶進(jìn)程對(duì) FPGA設(shè)備進(jìn)行讀操作時(shí),驅(qū)動(dòng)中的read函數(shù)檢查讀鏈表。如果讀鏈表為空,則進(jìn)入睡眠并等待數(shù)據(jù)到來(lái)。有數(shù)據(jù)后將從讀隊(duì)列中取出的緩沖塊的數(shù)據(jù)拷貝到用戶空間,然后將使用過(guò)的緩沖塊插到自由隊(duì)列中,等待以后再次使用。內(nèi)核緩沖區(qū)的操作過(guò)程如圖3所示。圖3上半部分是在底半部分程序中,下半部分是在 read函數(shù)中。

 

結(jié)語(yǔ)

連續(xù)數(shù)據(jù)流設(shè)備在uClinux下的驅(qū)動(dòng),通常會(huì)用到中斷機(jī)制。本文討論的中斷驅(qū)動(dòng)的I/O式為這種應(yīng)用提供了一種實(shí)用的方法。文中所涉及的鏈表、阻塞型I/O、自旋鎖等技術(shù)在驅(qū)動(dòng)程序的開(kāi)發(fā)中也經(jīng)常得到使用。

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

在數(shù)字化浪潮席卷全球的今天,F(xiàn)PGA技術(shù)正成為驅(qū)動(dòng)創(chuàng)新的核心引擎。2025年8月21日,深圳將迎來(lái)一場(chǎng)聚焦FPGA技術(shù)與產(chǎn)業(yè)應(yīng)用的盛會(huì)——2025安路科技FPGA技術(shù)沙龍。本次沙龍以“定制未來(lái) 共建生態(tài)”為主題,匯聚行業(yè)...

關(guān)鍵字: FPGA 核心板 開(kāi)發(fā)板

在現(xiàn)代電子系統(tǒng)中,現(xiàn)場(chǎng)可編程門(mén)陣列(FPGA)憑借其開(kāi)發(fā)時(shí)間短、成本效益高以及靈活的現(xiàn)場(chǎng)重配置與升級(jí)等諸多優(yōu)點(diǎn),被廣泛應(yīng)用于各種產(chǎn)品領(lǐng)域。從通信設(shè)備到工業(yè)控制,從汽車電子到航空航天,F(xiàn)PGA 的身影無(wú)處不在。為了充分發(fā)揮...

關(guān)鍵字: 可編程門(mén)陣列 FPGA 數(shù)字電源

2025年8月4日 – 提供超豐富半導(dǎo)體和電子元器件?的業(yè)界知名新品引入 (NPI) 代理商貿(mào)澤電子 (Mouser Electronics) 即日起開(kāi)售Altera?的Agilex? 3 FPGA C系列開(kāi)發(fā)套件。此開(kāi)...

關(guān)鍵字: FPGA 邊緣計(jì)算 嵌入式應(yīng)用

內(nèi)窺鏡泛指經(jīng)自然腔道或人工孔道進(jìn)入體內(nèi),并對(duì)體內(nèi)器官或結(jié)構(gòu)進(jìn)行直接觀察和對(duì)疾病進(jìn)行診斷的醫(yī)療設(shè)備,一般由光學(xué)鏡頭、冷光源、光導(dǎo)纖維、圖像傳感器以及機(jī)械裝置等構(gòu)成。文章介紹了一款基于兩片圖像傳感器和FPGA組成的微型3D內(nèi)...

關(guān)鍵字: 微創(chuàng) 3D內(nèi)窺鏡 OV6946 FPGA

運(yùn)用單片機(jī)和FPGA芯片作為主控制器件 , 單片機(jī)接收從PC機(jī)上傳過(guò)來(lái)的顯示內(nèi)容和顯示控制命令 , 通過(guò)命令解釋和數(shù)據(jù)轉(zhuǎn)換 , 生成LED顯示屏所需要的數(shù)據(jù)信號(hào)和同步的控制信號(hào)— 數(shù)據(jù)、時(shí)鐘、行同步和面同步 。FPGA芯...

關(guān)鍵字: 單片機(jī) FPGA LED顯示屏

FIFO 中斷狀態(tài)位的輪詢和中斷機(jī)制各有優(yōu)劣,適用于不同的應(yīng)用場(chǎng)景。輪詢實(shí)現(xiàn)簡(jiǎn)單但效率低下,中斷實(shí)時(shí)性好但復(fù)雜度高。在實(shí)際設(shè)計(jì)中,應(yīng)根據(jù)系統(tǒng)需求、性能指標(biāo)和資源限制,選擇合適的機(jī)制或混合方案。隨著硬件技術(shù)的發(fā)展,現(xiàn)代處理...

關(guān)鍵字: FIFO

FIFO 發(fā)送器憑借其獨(dú)特的工作原理和結(jié)構(gòu)特點(diǎn),在眾多領(lǐng)域中發(fā)揮著不可或缺的作用。它為數(shù)據(jù)的有序傳輸和高效處理提供了有力支持,盡管面臨一些挑戰(zhàn),但通過(guò)不斷的技術(shù)創(chuàng)新和優(yōu)化,F(xiàn)IFO 發(fā)送器將在未來(lái)的科技發(fā)展中繼續(xù)展現(xiàn)其強(qiáng)...

關(guān)鍵字: FIFO

在異構(gòu)計(jì)算系統(tǒng)中,ARM與FPGA的協(xié)同工作已成為高性能計(jì)算的關(guān)鍵架構(gòu)。本文基于FSPI(Fast Serial Peripheral Interface)四線模式,在150MHz時(shí)鐘頻率下實(shí)現(xiàn)10.5MB/s的可靠數(shù)據(jù)...

關(guān)鍵字: ARM FPGA FSPI

在全球FPGA市場(chǎng)被Xilinx(AMD)與Intel壟斷的格局下,國(guó)產(chǎn)FPGA廠商高云半導(dǎo)體通過(guò)構(gòu)建自主IP核生態(tài)與智能時(shí)序約束引擎,走出差異化高端化路徑。本文深入解析高云半導(dǎo)體FPGA工具鏈的兩大核心技術(shù)——全棧IP...

關(guān)鍵字: FPGA 高云半導(dǎo)體

2025年6月12日,由安路科技主辦的2025 FPGA技術(shù)沙龍?jiān)谀暇┱秸匍_(kāi),深圳市米爾電子有限公司(簡(jiǎn)稱:米爾電子)作為國(guó)產(chǎn)FPGA的代表企業(yè)出席此次活動(dòng)。米爾電子發(fā)表演講,并展出米爾基于安路飛龍派的核心板和解決方案...

關(guān)鍵字: FPGA 核心板 開(kāi)發(fā)板
關(guān)閉