亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于linux操作系統(tǒng)的多串口驅(qū)動(dòng)研究

        2012-03-14 06:02:44王巧玲陳婭荔
        關(guān)鍵詞:信息結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)內(nèi)核

        王巧玲,高 杰,陳婭荔

        ?

        基于linux操作系統(tǒng)的多串口驅(qū)動(dòng)研究

        *王巧玲1,高 杰2,陳婭荔1

        (1.井岡山大學(xué)電子與信息工程學(xué)院,江西,吉安 343009 2.南昌大學(xué)共青學(xué)院信息工程系,江西,共青城 332020)

        在介紹基于linux操作系統(tǒng)的多串口驅(qū)動(dòng)設(shè)計(jì)理論基礎(chǔ)上, 重點(diǎn)研究對(duì)多串口編程的技術(shù),實(shí)現(xiàn)基于tty的核心設(shè)計(jì),可作為實(shí)現(xiàn)串口終端設(shè)備集中管理、實(shí)時(shí)數(shù)據(jù)采集的服務(wù)器主板應(yīng)用。其特點(diǎn)是可以采用ARM平臺(tái),但完全兼容X86平臺(tái),用戶原來(lái)在X86 平臺(tái)下編寫linux操作系統(tǒng)的多串口驅(qū)動(dòng)的程序只需做一次重新編譯即可實(shí)現(xiàn)移植,達(dá)到基于Linux操作系統(tǒng)的多串口驅(qū)動(dòng)實(shí)時(shí)通訊的目的。

        linux操作系統(tǒng);多串口驅(qū)動(dòng);tty核心

        在Linux操作系統(tǒng)中串口的編程技術(shù)和DOS、Windows系統(tǒng)下的方法有所不同。本文較為詳細(xì)的敘述了在Linux操作系統(tǒng)中串口的驅(qū)動(dòng)編程技術(shù)。重點(diǎn)研究多串口驅(qū)動(dòng)通訊,本驅(qū)動(dòng)創(chuàng)新點(diǎn)可以通過(guò)自動(dòng)探測(cè)的方法測(cè)出當(dāng)前是什么類型的主板,可以讓bios往中斷狀態(tài)寄存器或其他保留的寄存器位中寫一個(gè)標(biāo)記即可,用于唯一標(biāo)記每一類主板。串口驅(qū)動(dòng)主要技術(shù)是在tty核心[1]的基礎(chǔ)上實(shí)現(xiàn)的,需要同時(shí)驅(qū)動(dòng)最多32個(gè)串口,板上的串口共用中斷號(hào),板上串口基地址連續(xù)。因此,通過(guò)合理的結(jié)構(gòu)體設(shè)計(jì)可以方便的實(shí)現(xiàn)。

        1 設(shè)計(jì)理論

        串口驅(qū)動(dòng)本質(zhì)上也是字符設(shè)備驅(qū)動(dòng)[2-3],只是內(nèi)核根據(jù)其特殊的數(shù)據(jù)傳輸過(guò)程進(jìn)行封裝,將其文件操作(file_operation)封裝到tty核心(tty_io.c)中,由tty核心提供接口給應(yīng)用程序調(diào)用,tty核心還提供接口給線路規(guī)程和驅(qū)動(dòng)程序使用;因此,在寫串口驅(qū)動(dòng)時(shí)只需要調(diào)用tty核心提供的接口,并傳入驅(qū)動(dòng)的處理函數(shù)(tty_operations)。

        向tty核心注冊(cè)驅(qū)動(dòng)時(shí),tty核心便會(huì)為該驅(qū)動(dòng)分配設(shè)備號(hào),并注冊(cè)文件操作函數(shù)(file_operations)。而在tty核心中各文件操作函數(shù)會(huì)調(diào)用驅(qū)動(dòng)傳入的處理函數(shù),可見真正實(shí)現(xiàn)應(yīng)用程序需求的函數(shù)還是驅(qū)動(dòng)程序,tty核心只是實(shí)現(xiàn)一個(gè)中轉(zhuǎn)的過(guò)程,但tty核心中封裝了很多串口驅(qū)動(dòng)實(shí)現(xiàn)的通用函數(shù),大大簡(jiǎn)化了串口驅(qū)動(dòng)的編寫。

        編寫串口驅(qū)動(dòng)主要分以下幾個(gè)步驟:

        1.1 注冊(cè)、釋放設(shè)備驅(qū)動(dòng)

        int tty_register_driver(struct tty_driver *driver);在注冊(cè)前要對(duì)tty_driver進(jìn)行賦值,在tty_driver中指定設(shè)備號(hào)、串口個(gè)數(shù)、操作函數(shù)等信息。

        int tty_unregister_driver(struct tty_driver *driver);釋放設(shè)備驅(qū)動(dòng)。

        1.2 串口操作函數(shù)

        設(shè)置驅(qū)動(dòng)提供的串口操作函數(shù),注冊(cè)時(shí)提供給tty核心使用,串口操作函數(shù)是在tty_driver中設(shè)置的。

        1.3 中斷處理函數(shù)

        中斷處理函數(shù)是串口通訊的核心,驅(qū)動(dòng)對(duì)串口進(jìn)行讀、寫都是通過(guò)中斷來(lái)實(shí)現(xiàn)的;串口內(nèi)部有2個(gè)64B的FIFO(TX和RX),分別用于發(fā)送和接收數(shù)據(jù)。

        圖1 串口數(shù)據(jù)發(fā)送

        串口發(fā)送數(shù)據(jù)過(guò)程如圖1所示,一般串口通訊都是基于異步協(xié)議的,因此數(shù)據(jù)是以字節(jié)為單位傳輸?shù)?,?dāng)驅(qū)動(dòng)將一個(gè)字節(jié)數(shù)據(jù)寫到串口時(shí),會(huì)先通過(guò)THR寄存器存入RX FIFO,然后通過(guò)TSR將數(shù)據(jù)發(fā)送出去,每一個(gè)數(shù)據(jù)的發(fā)送時(shí)間是16個(gè)時(shí)鐘周期。當(dāng)RX FIFO里的數(shù)據(jù)低于某一TRIGGER值或?yàn)榭諘r(shí),就會(huì)觸發(fā)中斷,并將LSR寄存器的bit[0]和ISR的bit[1]置1,中斷處理程序根據(jù)這些值發(fā)送數(shù)據(jù)到串口。RX FIFO的TRIGGER值由FCR寄存器的bit[6,7]設(shè)置。

        串口接收數(shù)據(jù)過(guò)程如圖2所示,和發(fā)送數(shù)據(jù)一樣,串口接收數(shù)據(jù)也是以字節(jié)為單位的,串口通過(guò)RSR寄存器接收數(shù)據(jù),然后會(huì)將數(shù)據(jù)存入TX FIFO,驅(qū)動(dòng)程序同樣以字節(jié)為單位從TX FIFO中取數(shù)據(jù)。當(dāng)TX FIFO中數(shù)據(jù)高于某個(gè)TRIGGER值就會(huì)觸發(fā)中斷,并將LSR的bit[5]和ISR的bit[2]置1,中斷處理程序根據(jù)這些值從串口TX FIFO讀取數(shù)據(jù)。TX FIFO的TRIGGER值由FCR寄存器的bit[4,5]設(shè)置。

        當(dāng)啟用了自動(dòng)RTS硬件流控制時(shí)(EFR bit[6]=1 MCR bit[1]=1),當(dāng)TX FIFO的數(shù)據(jù)大于56時(shí),串口會(huì)自動(dòng)通知發(fā)送端停止發(fā)送數(shù)據(jù);當(dāng)TX FIFO數(shù)據(jù)小于8時(shí),串口會(huì)自動(dòng)通知發(fā)送端繼續(xù)發(fā)送數(shù)據(jù)。使用RTS/CTS(請(qǐng)求發(fā)送/清除發(fā)送)流控制時(shí),應(yīng)將通訊兩端的RTS、CTS線對(duì)應(yīng)相連。

        圖2 串口數(shù)據(jù)接收

        2 設(shè)計(jì)思路

        多串口驅(qū)動(dòng)基于tty核心進(jìn)行的,主要設(shè)計(jì)以下幾個(gè)方面:

        2.1 與內(nèi)核通訊

        這里的與內(nèi)核通訊實(shí)際上是通過(guò)tty核心來(lái)實(shí)現(xiàn)的,通過(guò)向tty核心注冊(cè)驅(qū)動(dòng)告訴內(nèi)核應(yīng)該處理哪個(gè)驅(qū)動(dòng)和應(yīng)該使用哪些處理函數(shù),注冊(cè)函數(shù)如下:

        int tty_register_driver(struct tty_driver *driver);

        2.2 與應(yīng)用程序通訊

        字符設(shè)備驅(qū)動(dòng)與應(yīng)用程序通訊是通過(guò)文件操作file_operations來(lái)實(shí)現(xiàn)的,而文件操作是在tty核心中實(shí)現(xiàn)的。

        可見,應(yīng)用程序雖然是調(diào)用tty核心的文件操作函數(shù),但本質(zhì)上還是驅(qū)動(dòng)來(lái)實(shí)現(xiàn)的。因此,驅(qū)動(dòng)中可以根據(jù)需要實(shí)現(xiàn)與應(yīng)用程序通訊的函數(shù),本人在多串口驅(qū)動(dòng)中實(shí)現(xiàn)了open、release、write、ioctl等函數(shù)。

        2.3 與硬件通訊

        驅(qū)動(dòng)與硬件通訊就是操作寄存器,在串口芯片的datasheet中有詳細(xì)的說(shuō)明,多的串口芯片是ST16C654,這里介紹幾個(gè)驅(qū)動(dòng)中常用的寄存器。

        RHR:接收數(shù)據(jù)寄存器;

        THR:發(fā)送數(shù)據(jù)寄存器;

        IER:中斷使能寄存器,其中bit[0-3]分別對(duì)應(yīng)4中中斷;

        ISR:中斷狀態(tài)寄存器,其中bit[1,2]分別代表讀、寫中斷;

        FCR:FIFO控制寄存器,使能FIFO和TRIGGER等級(jí)都在這里設(shè)置;

        LCR:線路控制寄存器,設(shè)置線路規(guī)程,包括:數(shù)據(jù)位,校驗(yàn)位,停止位等;

        MCR:MODEM控制寄存器,其中bit[0,1]用于使能硬件流控制輸出;

        LSR:線路狀態(tài)寄存器,其中bit[0]標(biāo)記RHR是否有數(shù)據(jù),

        bit[5]標(biāo)記THR是否為空;

        DLL、DLM:波特率除數(shù)寄存器,用于設(shè)置波特率。

        3 數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)

        這里的數(shù)據(jù)結(jié)構(gòu)不是指上一節(jié)的數(shù)據(jù)結(jié)構(gòu),這里是指串口驅(qū)動(dòng)內(nèi)部的數(shù)據(jù)組織方式,這些數(shù)據(jù)結(jié)構(gòu)貫穿整個(gè)串口驅(qū)動(dòng)程序,合理的設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)和組織方式可以有效地提高驅(qū)動(dòng)的效率,下面分別介紹內(nèi)核和多串口驅(qū)動(dòng)的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)和組織方式,并進(jìn)行比較和分析。

        數(shù)據(jù)結(jié)構(gòu)和組織方式的設(shè)計(jì)要注意以下幾個(gè)方面:

        (a)數(shù)據(jù)結(jié)構(gòu)要能表示串口的所有信息以及運(yùn)行過(guò)程中串口的屬性;

        (b)open時(shí)要能根據(jù)數(shù)據(jù)結(jié)構(gòu)來(lái)判斷是哪一個(gè)串口,因?yàn)橛锌赡芤粔K板上有很多串口;

        (c)中斷處理函數(shù)中也需要能通過(guò)數(shù)據(jù)結(jié)構(gòu)來(lái)判斷是哪個(gè)串口產(chǎn)生的中斷。

        3.1 內(nèi)核數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)

        內(nèi)核串口驅(qū)動(dòng)主要是通過(guò)以下2個(gè)數(shù)組來(lái)實(shí)現(xiàn)的。

        struct serial_state rs_table[64];

        這是一個(gè)串口基本信息結(jié)構(gòu)體,結(jié)構(gòu)體中包括波特率、基地址、中斷號(hào)等信息,在定義時(shí)就已經(jīng)對(duì)其進(jìn)行了初始化,初始化是通過(guò)宏SERIAL_PORT_DFNS來(lái)實(shí)現(xiàn)的,這個(gè)宏初始化了每個(gè)串口的基地址、中斷號(hào),這個(gè)數(shù)組中的初始值就是默認(rèn)情況下的ttySn的值,所以可以根據(jù)主板的串口信息修改該宏的值,實(shí)現(xiàn)驅(qū)動(dòng)主板上各串口。

        struct async_struct *IRQ_ports[225];

        這是一個(gè)數(shù)組指針,數(shù)組大小為225,對(duì)應(yīng)于每個(gè)中斷號(hào),數(shù)組每個(gè)元素指向所有共享該中斷號(hào)的串口信息結(jié)構(gòu)體鏈表;async_struct是一個(gè)包含一個(gè)已打開串口所有信息的結(jié)構(gòu)體,當(dāng)打開一個(gè)串口時(shí),會(huì)動(dòng)態(tài)創(chuàng)建一個(gè)串口信息結(jié)構(gòu)體async_struct,然后根據(jù)打開設(shè)備的基本信息serial_state對(duì)這個(gè)結(jié)構(gòu)體進(jìn)行初始化,最后將其鏈入相應(yīng)IRQ鏈表的頭。

        低版本內(nèi)核串口驅(qū)動(dòng)的數(shù)據(jù)結(jié)構(gòu)模型如圖3所示,在打開設(shè)備時(shí),通過(guò)打開設(shè)備的次設(shè)備號(hào)和驅(qū)動(dòng)的起始次設(shè)備號(hào)計(jì)算出是第幾個(gè)串口,從而得到串口基本信息serial_state;在中斷處理程序中,可以直接根據(jù)中斷號(hào)獲取所有使用該中斷號(hào)的串口信息,然后對(duì)所有串口進(jìn)行處理。

        圖3 低版本內(nèi)核數(shù)據(jù)結(jié)構(gòu)模型

        高版本內(nèi)核串口驅(qū)動(dòng)的設(shè)計(jì)思想和低版本內(nèi)核類似,只是在其基礎(chǔ)上進(jìn)行了一些改進(jìn),以8250串口驅(qū)動(dòng)為例說(shuō)明,主要有以下幾個(gè)數(shù)據(jù)結(jié)構(gòu):

        struct old_serial_port old_serial_port[64];

        串口基本信息結(jié)構(gòu)體,類似于2.4內(nèi)核的serial_state結(jié)構(gòu)體,由宏SERIAL_PORT_DFNS初始化。

        struct uart_8250_port serial8250_ports[64];

        已打開串口信息結(jié)構(gòu)體,類似于低版本內(nèi)核的async_struct結(jié)構(gòu)體,與低版本內(nèi)核的不同之處在于這里的結(jié)構(gòu)體是靜態(tài)分配的。

        struct irq_info irq_lists[225];

        這是一個(gè)數(shù)組,類似于低版本內(nèi)核的IRQ_ports,數(shù)組的內(nèi)容為包含一個(gè)list_head類型變量的結(jié)構(gòu)體,用于指向相同中斷號(hào)的所有串口的鏈表頭。

        3.2 多數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)

        內(nèi)核串口驅(qū)動(dòng)的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)是一種通用的設(shè)計(jì),目的在于能應(yīng)用于各種不同的主板,而多串口驅(qū)動(dòng)的數(shù)據(jù)結(jié)構(gòu)完全是針對(duì)104串口系列主板設(shè)計(jì)的,是根據(jù)多的特性設(shè)計(jì)結(jié)構(gòu)體。

        由于每塊多主板的所有串口是有一些共用屬性的,所以設(shè)計(jì)一個(gè)主板信息結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體每塊主板一個(gè),主板各個(gè)串口信息都可以通過(guò)此結(jié)構(gòu)體來(lái)設(shè)置,結(jié)構(gòu)體定義如下:

        struct evocdrv_brdconf {/*每塊板的信息*/

        int board_type;/*主板類型1-1048COM 2-COMMON*/

        int flags;/*UART_CLEAR_FIFO | UART_USE_ FIFO |UART_HAS_EFR*

        int ports;/*串口個(gè)數(shù)*/

        int irq;/*中斷號(hào),一般為共享中斷*/

        int irq_type;/*0:串口0-7共享中斷(M1=on);1--0-3共享,4-7共享(M1=off)*/

        int vector;/*中斷狀態(tài)寄存器基地址,4塊板16個(gè)端口,板上所有串口共用*/

        int vector_mask;/*中斷狀態(tài)*/

        int uart_type;/*芯片類型*/

        char uart_name[20];/*芯片名字*/

        int ioaddr;/*每個(gè)串口的端口基地址,由sw1設(shè)置(p14)*/

        int baud_base;/*串口的波特率基數(shù)quot=baud_ base/baud*/

        int max_baud;/*最大波特率*/};

        除了主板信息結(jié)構(gòu)體之外,還定義了一個(gè)大小為32的串口信息結(jié)構(gòu)體數(shù)組,用于保存每個(gè)串口的信息,串口信息數(shù)組在初始化時(shí)根據(jù)其主板的信息設(shè)置;由于多主板的特殊性,如:主板上的所有串口是共用中斷號(hào)的,串口的基地址是連續(xù)的等等,所以可以把這些共用的屬性設(shè)置在主板信息結(jié)構(gòu)體中。串口信息數(shù)組是這樣設(shè)計(jì)的,默認(rèn)每塊主板8個(gè)串口,若主板串口個(gè)數(shù)小于8則數(shù)組的相應(yīng)位為空值。

        打開串口時(shí),根據(jù)設(shè)備的次設(shè)備號(hào)和驅(qū)動(dòng)的次設(shè)備號(hào)起始值,計(jì)算出打開的是第幾個(gè)串口,根據(jù)這個(gè)就可以直接從串口信息數(shù)組中獲取串口信息;在中斷處理程序中,這里并沒有像內(nèi)核串口驅(qū)動(dòng)中的中斷指針數(shù)組,但由于每塊板上的串口中斷號(hào)是相同的,所以只需要在發(fā)生中斷時(shí)判斷是哪塊板上的串口產(chǎn)生的,然后對(duì)該板上的串口進(jìn)行一一判斷并處理;在請(qǐng)求中斷號(hào)時(shí),將板上第一個(gè)串口信息結(jié)構(gòu)體作為參數(shù)傳入,然后在中斷處理函數(shù)中根據(jù)串口信息數(shù)組的第0,8,16,24個(gè)元素來(lái)判斷屬于哪塊主板。

        3.3 函數(shù)的實(shí)現(xiàn)

        串口驅(qū)動(dòng)中要實(shí)現(xiàn)的函數(shù)有很多,包括與tty核心的通訊函數(shù),與應(yīng)用程序的通訊函數(shù)以及中斷處理函數(shù),主要函數(shù)如下:

        struct tty_operations evocdrv_ops = {

        .open = evocdrv_open,/*打開串口*/

        .close = evocdrv_close,/*關(guān)閉串口*/

        .write = evocdrv_write,/*寫串口*/

        .put_char = evocdrv_put_char,/*寫一個(gè)字符到串口*/

        .flush_chars = evocdrv_flush_chars,/*發(fā)送寫緩沖區(qū)中數(shù)據(jù)*/

        .write_room = evocdrv_write_room,/*獲取寫緩沖區(qū)的可用空間*/

        .chars_in_buffer = evocdrv_chars_in_buffer,/*獲取寫緩沖區(qū)數(shù)據(jù)大小*/

        .flush_buffer = evocdrv_flush_buffer,/*清空寫緩沖區(qū)*/

        .ioctl = evocdrv_ioctl,/*ioctl*/

        .throttle = evocdrv_throttle,/*通知串口不要發(fā)送數(shù)據(jù)*/

        .unthrottle = evocdrv_unthrottle,/*通知串口恢復(fù)發(fā)送數(shù)據(jù)*/

        .set_termios = evocdrv_set_termios,/*設(shè)置線路規(guī)程*/

        .stop = evocdrv_stop,/*停止向串口發(fā)送數(shù)據(jù)*/

        .start = evocdrv_start,/*恢復(fù)向串口發(fā)送數(shù)據(jù)*/

        .hangup = evocdrv_hangup,/*設(shè)備掛起,等待再次被open*/

        .tiocmget = evocdrv_tiocmget,/*獲取MODEM狀態(tài)位*/

        .tiocmset = evocdrv_tiocmset,/*設(shè)置MODEM狀態(tài)位*/

        };

        這里挑一些與應(yīng)用程序聯(lián)系比較密切的函數(shù)進(jìn)行介紹。

        (1) open

        當(dāng)應(yīng)用程序調(diào)用open函數(shù)打開設(shè)備文件時(shí)就會(huì)進(jìn)入此函數(shù),此函數(shù)主要實(shí)現(xiàn)打開設(shè)備以及對(duì)設(shè)備進(jìn)行初始化等功能,主要工作如下:

        ● 找到打開串口的信息結(jié)構(gòu)體并進(jìn)行必要的初始化;

        ● 初始化串口寄存器,包括啟用FIFO、中斷等各種初始化工作;

        ● 設(shè)置波特率、停止位、流控制等線路狀態(tài)信息;

        (2) close

        當(dāng)應(yīng)用程序調(diào)用close函數(shù)關(guān)閉設(shè)備時(shí)會(huì)進(jìn)入此函數(shù),此函數(shù)實(shí)現(xiàn)的功能與open相反,主要是善后工作,包括對(duì)所有改變過(guò)的寄存器復(fù)位,還有對(duì)open后請(qǐng)求的一些資源進(jìn)行釋放。

        (3) write

        當(dāng)應(yīng)用程序調(diào)用write函數(shù)進(jìn)行寫操作時(shí)會(huì)進(jìn)入此函數(shù),此函數(shù)主要實(shí)現(xiàn)把應(yīng)用程序?qū)懭氲臄?shù)據(jù)保存到寫緩沖區(qū)xmit_buf中,這是一個(gè)4KB大小的緩沖區(qū),是在open時(shí)動(dòng)態(tài)分配的,在close是釋放。當(dāng)xmit_buf中有數(shù)據(jù)時(shí),開啟發(fā)送數(shù)據(jù)中斷IER_THRI,然后就會(huì)進(jìn)入中斷處理程序?qū)mit_buf的數(shù)據(jù)發(fā)送給串口。

        (4) ioctl

        當(dāng)應(yīng)用程序調(diào)用ioctl函數(shù)時(shí)會(huì)進(jìn)入此函數(shù),此函數(shù)主要提供應(yīng)用程序一些設(shè)置的方法和獲取驅(qū)動(dòng)信息的方法,這里有一個(gè)很重要的方法TIOCSSERIAL,當(dāng)調(diào)用setserial命令設(shè)置設(shè)備節(jié)點(diǎn)信息時(shí)會(huì)調(diào)用ioctl并傳入TIOCSSERIAL參數(shù),在處理程序中,根據(jù)用戶傳入的基礎(chǔ)波特率、中斷號(hào)、基地址等串口信息修改串口信息結(jié)構(gòu)體,如果中斷號(hào)或基地址改變了,則重新設(shè)置串口各寄存器,否則只要重新設(shè)置串口的線路信息就可以了。

        (5) set_termios

        當(dāng)應(yīng)用程序調(diào)用tcsetattr函數(shù)時(shí)進(jìn)入此函數(shù),主要功能是設(shè)置線路規(guī)程信息,函數(shù)tcsetattr調(diào)用后tty核心會(huì)更新tty_struct->termios,并將原來(lái)的線路規(guī)程保存在old_termios中作為參數(shù)傳入set_termios中,程序根據(jù)tty_struct中的線路規(guī)程值對(duì)串口進(jìn)行重新設(shè)置。

        (6) tiocmset

        設(shè)置MODEM狀態(tài),主要是設(shè)置DTR/RTS線的狀態(tài),主要應(yīng)用于硬件流控制中。

        (7) 中斷處理函數(shù)

        串口驅(qū)動(dòng)程序的數(shù)據(jù)傳輸和接收都是通過(guò)中斷來(lái)實(shí)現(xiàn)的,觸發(fā)中斷的情況有很多,這里列出幾個(gè)常用的中斷觸發(fā)。當(dāng)出現(xiàn)以下幾種情況時(shí)會(huì)觸發(fā)中斷:

        ①若設(shè)置了IER寄存器的RDI位,當(dāng)FIFO值到達(dá)TRIGGER值時(shí)觸發(fā)讀中斷,并將ISR寄存器的bit[1]和LSR寄存器的bit[0]置1;

        ②若設(shè)置了IER寄存器的THRI位,當(dāng)FIFO值低于TRIGGER值或FIFO為空時(shí)觸發(fā)寫中斷,并將ISR寄存器的bit[0]和LSR寄存器的bit[5]置1;

        ③若設(shè)置了IER寄存器的TLSI位,當(dāng)出現(xiàn)RX break、RX framing error、RX parity error、overrun error的任意一個(gè)時(shí)將觸發(fā)一個(gè)中斷;

        ④若設(shè)置了IER寄存器的MSI位,當(dāng)CTS線、DSR線、RI響鈴控制器、CD數(shù)據(jù)載波檢測(cè)線中任意一個(gè)狀態(tài)改變時(shí)將觸發(fā)一個(gè)中斷;

        由于有很多中情況會(huì)觸發(fā)中斷,所以在中斷處理函數(shù)中要對(duì)各種可能產(chǎn)生中斷的情況進(jìn)行判斷并處理,這里最重要的當(dāng)然是對(duì)讀、寫中斷的處理了,可以通過(guò)讀取寄存器的值來(lái)判斷進(jìn)行哪種操作。

        當(dāng)ISR寄存器的bit[1]或LSR寄存器的bit[0]為1時(shí),執(zhí)行讀操作,即從串口讀取數(shù)據(jù),由于串口內(nèi)部有個(gè)64B的RX FIFO,而且串口數(shù)據(jù)傳輸是以字節(jié)為單位的,所以在讀取數(shù)據(jù)操作函數(shù)(receive_chars)中,每次以字節(jié)為單位從串口RHR寄存器讀取64B的數(shù)據(jù);先將讀取的數(shù)據(jù)保存到tty_buffer中(tty_insert_flip_char),然后在將tty_ buffer中的數(shù)據(jù)發(fā)送到read_buf中(tty_flip_buffer _push),應(yīng)用程序就是從read_buf中讀取數(shù)據(jù)的。

        當(dāng)ISR寄存器的bit[0]或LSR寄存器的bit[5]為1時(shí),執(zhí)行寫操作,即向串口寫數(shù)據(jù)(transmit_ chars),寫操作與讀操作類似,也是每次以字節(jié)為單位向串口寫入64B的數(shù)據(jù),寫入數(shù)據(jù)的寄存器為THR;這里寫入的數(shù)據(jù)并不是用戶空間傳入的數(shù)據(jù),應(yīng)用程序先將數(shù)據(jù)寫入寫緩沖區(qū)xmit_buf,函數(shù)transmit_chars從寫緩沖區(qū)發(fā)送數(shù)據(jù)到串口,寫緩沖區(qū)大小為4KB。

        4 結(jié)語(yǔ)

        可以看出內(nèi)核中數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)是一種通用的設(shè)計(jì),不論是哪種類型的主板、哪種類型的芯片都可使用內(nèi)核驅(qū)動(dòng);但正是由于這種通用性,使得內(nèi)核對(duì)串口信息的默認(rèn)值很難做一個(gè)合適的設(shè)置,因?yàn)椴煌闹靼宕谛畔⑼遣煌?,只能通過(guò)serserial命令來(lái)手動(dòng)修改。多串口驅(qū)動(dòng)的設(shè)計(jì)是將內(nèi)核中2個(gè)串口信息結(jié)構(gòu)體合為一個(gè),并實(shí)現(xiàn)一個(gè)主板信息結(jié)構(gòu)體,此結(jié)構(gòu)體包含了一塊板上所有串口共用的信息,對(duì)于中斷處理的設(shè)計(jì)是通過(guò)傳入每塊板第一個(gè)串口的信息結(jié)構(gòu)體實(shí)現(xiàn)的,這里沒有內(nèi)核方便,有待改進(jìn)。

        [1] 李萌.linux操作系統(tǒng)多串口編程技術(shù)[J].火控雷達(dá)技術(shù); 2008,29(3).

        [2] 劉海燕,荊濤.linux系統(tǒng)應(yīng)用與開發(fā)教程[M].北京:機(jī)械工業(yè)出版社,2006:44-47.

        [3] 高艷輝,龔華軍.嵌入式實(shí)時(shí)Linux在PC104平臺(tái)上的實(shí)現(xiàn)[J].儀器儀表用戶,2008,15(2).

        [4] 高艷輝.基于嵌入式實(shí)時(shí)Linux的無(wú)人機(jī)半物理仿真平臺(tái)研究[D].南京:南京航空航天大學(xué),2008.

        [5] 曾煒,沈?yàn)槿?基于RTAI-Linux的飛行仿真實(shí)時(shí)管理系統(tǒng)[J].計(jì)算機(jī)工程,2008,34(19).

        [6] 劉海燕,邵立嵩.linux系統(tǒng)應(yīng)用與開發(fā)教程[M].北京:機(jī)械工業(yè)出版社,2006:65-69.

        [7] 黃志洪,鐘耿揚(yáng).linux操作系統(tǒng)[M].北京:冶金工業(yè)出版社,2010:155-169.

        The research of multi-serial drive based on the Linux operating system

        *WANG Qiao-ling1,GAO Jie2, CHENG Ya-li1

        (1.School of Electronic Information Engineering, Jinggangshan University, Ji’an, Jiangxi 343009, China;2.Information Engineering Department of Nanchang University, Gongqing College, Gongqing City, Jiangxi 332020,China)

        We introduce the Linux operating system based on the design theory of multi-serial port drive and realize the core design based on tty with the multi-serial port programming technology, which can be used as a serial port terminal equipment to realize the centralized management, the real-time data acquisition server application motherboard. Its characteristic is can be used with ARM platform, but is fully compatible with X86 platform. Furthermore, the original X86 operating system Linux multi-serial port drive program in the workbench need only recompile to realize the transplant, which is based on Linux operating system to the serial driver real-time communication.

        Linux operating system; multi- serial driver; tty core

        1674-8085(2012)03-0069-06

        TP316

        A

        10.3969/j.issn.1674-8085.2012.03.015

        2012-02-16;

        2012-03-27

        *王巧玲(1979-),女,江西吉水人,講師,碩士,主要從事計(jì)算機(jī)軟件理論研究(Email:xinyuwql@163.com);

        高 杰(1983-),男,江西吉安人,助教,主要從事嵌入式方向研究(Email:275750383@qq.com);

        陳婭荔(1982-),女,江西南昌人,助教,碩士,主要從事人工智能和圖像處理研究(Email:30006959@qq.com).

        猜你喜歡
        信息結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)內(nèi)核
        萬(wàn)物皆可IP的時(shí)代,我們當(dāng)夯實(shí)的IP內(nèi)核是什么?
        強(qiáng)化『高新』內(nèi)核 打造農(nóng)業(yè)『硅谷』
        基于嵌入式Linux內(nèi)核的自恢復(fù)設(shè)計(jì)
        Linux內(nèi)核mmap保護(hù)機(jī)制研究
        對(duì)外漢語(yǔ)教材編寫中信息結(jié)構(gòu)知識(shí)的應(yīng)用
        “翻轉(zhuǎn)課堂”教學(xué)模式的探討——以《數(shù)據(jù)結(jié)構(gòu)》課程教學(xué)為例
        基于調(diào)節(jié)聚焦理論的生物農(nóng)藥推廣有效性研究
        高職高專數(shù)據(jù)結(jié)構(gòu)教學(xué)改革探討
        事件結(jié)構(gòu)、信息結(jié)構(gòu)與句法表征*——領(lǐng)主屬賓句的認(rèn)知語(yǔ)法分析
        TRIZ理論在“數(shù)據(jù)結(jié)構(gòu)”多媒體教學(xué)中的應(yīng)用
        国产猛男猛女超爽免费视频| 亚洲精品一区二区三区av| 中文字幕人妻av一区二区| 97色伦图片97综合影院| 国产黄在线观看免费观看不卡| 中文字幕一区二区三区乱码不卡| 国产三级视频一区二区| 国产亚洲人成在线观看| 鸭子tv国产在线永久播放| 97se在线观看| 免费的黄网站精品久久| 日本一区二区三区高清在线视频 | 日本中文字幕一区二区在线观看| 久久久精品亚洲一区二区国产av| 人妻 色综合网站| 精品欧美在线| 国产青春草在线观看视频| 夜夜爽夜夜叫夜夜高潮| 伊人色综合视频一区二区三区| 婷婷色国产精品视频一区| 亚洲日本中文字幕乱码| 欧美成人秋霞久久aa片| 国产999精品久久久久久| 国产成人精品人人做人人爽| 久久亚洲精品国产av| 国产日产综合| 人妻熟妇乱系列| 亚洲女同高清精品一区二区99| 乱子轮熟睡1区| 久久精品国产亚洲av高清色欲| 中文字幕一区二区三区在线视频| 精品一区二区在线观看免费视频| 毛片a级毛片免费观看| 国产精品一区二区久久乐下载| 性感的小蜜桃在线观看| 国产精品videossex国产高清| 亚洲av色福利天堂| 亚洲香蕉av一区二区蜜桃| 青青草成人在线免费视频| 婷婷五月综合丁香在线| 亚洲成a人片在线观看中文!!! |