新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > linux UART串口驅動開發文檔

        linux UART串口驅動開發文檔

        作者: 時間:2012-09-06 來源:網絡 收藏

        #define _GET_CHAR(p) ((readb((p)->membase + W83697_DR)) 0xff)

        #define _PUT_CHAR(p, c) writeb((c), (p)->membase + W83697_UARTDR)

        2>. 接收發送狀態.

        #define UART_GET_RSR(p) ((readb((p)->membase + W83697_UARTRSR)) 0xff)

        #define UART_PUT_RSR(p, c) writeb((c), (p)->membase + W83697_UARTRSR)

        3>. 發送及接收中斷狀態.

        #define UART_GET_CR(p) ((readb((p)->membase + W83697_UARTCR)) 0xff)

        #define UART_PUT_CR(p,c) writeb((c), (p)->membase + W83697_UARTCR)

        #define UART_GET_INT_STATUS(p) ((readb((p)->membase + W83697_UARTIIR)) 0xff)

        4>. 以及其它的中斷使能設置等, 在傳送時打開傳送中斷即會產生傳送中斷.

        #define UART_PUT_ICR(p, c) writeb((c), (p)->membase + W83697_UARTICR)

        5>. FIFO的狀態, 是否讀空/是否寫滿; 每次讀時必須讀至FIFO空, 寫時必須等到FIFO不滿時才能寫(要等硬件傳送完) .

        接收中斷讀空FIFO的判斷:

        status = UART_GET_FR(port);

        while (UART_RX_DATA(status) max_count--) {

        ……

        }

        發送中斷寫FIFO: 當發送緩沖區中有數據要傳送時, 置發送中斷使能, 隨后即產生傳送中斷, 此時FIFO為空, 傳送半個FIFO大小的字節, 如果發送緩沖區數據傳完,則關閉發送中斷.

        6>. 傳送時可直接寫數據口, 而不使用中斷, 但必須等待檢測FIFO的狀態

        do {

        status = UART_GET_FR(port);

        } while (!UART_TX_READY(status)); //wait for tx buffer not full...

        3. 的參數配置

        的參數主要包括如下幾個參數,全部都記錄在uart_port結構上,為靜態的賦值,本串口支持6個設備,所以中就包括了6個port,一個串口對應一個port口,他們之間除了對應的中斷號/寄存器起始基址/次設備號不同之外,其它的參數基本相同.

        √串口對應中斷, 這里六個串口,其中有3個串口使用的系統外部中斷0/1/2, 其中另外幾個中斷用提GPIO中斷,具體有關GPIO中斷的內容可參見EP93XX芯片手冊, GPIO中斷共享一個系統中斷向量,涉及中斷共享的問題,后面將詳述LINUX中的中斷共享支持.

        √串口時鐘, 串口時鐘用來轉換計算須要設置到配置寄存器當中的波特率比值,其計算方法為:quot = (port->uartclk / (16 * baud)); baud為當前設置的波特率,可為115200等值, 取決于所選的串口時鐘源, quot即為要設置到寄存器當中的比值.

        √串口基址, 即串口所有配置寄存器基礎址.

        √串口次設備號(由驅動中的最低次設備號依次累加)

        前面已經講過了六個串口中斷,這里詳細列出對應情況如下,方便查找:

        w83697的三個串口對應中斷如下:

        uart 1: 讀寫數據寄存器偏移為00x3F8, 對應系統外部中斷INT_EXT[0].

        uart 2: 讀寫數據寄存器偏移為00x2F8, 對應系統外部中斷INT_EXT[1].

        uart 3: 讀寫數據寄存器偏移為00x3e8, 對應系統外部中斷INT_EXT[2].

        uart 4: 讀寫數據寄存器偏移為00x3e8, 對應EGPIO[8].

        w83977的兩個串口對應中斷如下:

        uart 1: 讀寫數據寄存器偏移為00x3F8, 對應EGPIO[1].

        uart 2: 讀寫數據寄存器偏移為00x2F8, 對應EGPIO[2].

        下面列出其中一個具體的串口port的定義如下:

        {

        .port = {

        .membase = (void *)W83697_UART4_BASE,

        .mapbase = W83697_UART4_BASE,

        .iotype = SERIAL_IO_MEM,

        .irq = W83697_IRQ_UART4, //串口中斷號

        .uartclk = 1846100, //uart時鐘,默認.

        .fifosize = 8, //硬件fifo大小.

        .ops = amba_pops, //底層驅動的硬件操作集,如開關中斷等.

        .flags = ASYNC_BOOT_AUTOCONF,

        .line = 3, //串口在次設備數組中的索引號,須注意從0計起…

        },

        .dtr_mask = 0,

        .rts_mask = 0,

        }

        4. 串口驅動的底層接口函數

        驅動文件:-2.4.21/drivers/serial/Ep93xx_w83697.c

        相關文件: -2.4.21/drivers/serial/core.c 下面詳述.

        函數: w83697uart_rx_chars(struct uart_port *port, struct pt_regs *regs)

        描述: 串口接收數據中斷, 此函數中應當注意的要點如下:

        接收數據時,要注意判斷FIFO是否讀空(參見上述2點中說明).

        接收數據放入flip緩沖區,此緩沖區專供緩存中斷中接收到的數據,是最原始的串口數據,為更上一層中各種終端處理模式的原始數據,可以進行各種加工處理。

        接收數據到flip緩沖區中時,須根據硬件接收狀態,置每一個接收到的字符的接收標志,放在flag_buf_ptr當中, 標志類型有TTY_NORMAL/ TTY_PARITY/ TTY_FRAME等,分別表示正常/校驗出錯/幀出錯(無停止位)等.

        每接收數據之后,會通過在退出中斷前調用tty_flip_buffer_push()來往tq_timer任務列表中加一個隊列任務,串口的隊列任務主要是負責將中斷接收到flip緩沖區中的數據往上傳輸至終端終沖區, 隊列任務的機制將在后面介紹,它是一種異步執行機制,在軟中斷中觸發執行.

        函數: static void w83697uart_tx_chars(struct uart_port *port)

        描述: 串口發送數據中斷, 發送中斷中要做的事比較少,比起接收中斷簡單了好多,注意事項如下:

        當上層要發送數據時,就會打開串口發送中斷,此時FIFO為空,傳送半個FIFO大小數據即退出, 通常打開中斷是通過更上一層的uart_flush_chars()調用,最終調用的是w83697uart_start_tx().

        檢測當沒有數據要傳輸的時候,關閉傳送中斷,在傳送之前與傳送完之后都有檢測.

        最重要的一點是如果傳送緩沖區當中的字符數已經小于WAKEUP_CHARS, 則可以喚醒當前正在使用串口進行傳送的進程,這里是通過tasklet機制來完成,這也是一異步執行機制.

        linux操作系統文章專題:linux操作系統詳解(linux不再難懂)

        linux相關文章:linux教程




        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 木兰县| 通化市| 孟津县| 南丰县| 旬阳县| 崇义县| 怀化市| 博湖县| 南汇区| 信宜市| 东乡族自治县| 武强县| 吉木萨尔县| 泉州市| 延吉市| 贡觉县| 永顺县| 通道| 岗巴县| 象山县| 军事| 河南省| 历史| 通山县| 房产| 长丰县| 洛扎县| 芮城县| 修武县| 旬邑县| 屏边| 宁晋县| 青浦区| 富锦市| 信丰县| 太仆寺旗| 睢宁县| 淮安市| 尉犁县| 宝兴县| 乐平市|