<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux UART串口驅(qū)動(dòng)開發(fā)文檔

          linux UART串口驅(qū)動(dòng)開發(fā)文檔

          作者: 時(shí)間:2012-09-06 來源:網(wǎng)絡(luò) 收藏

          W83697/W83977 super I/O

          本文引用地址:http://www.ex-cimer.com/article/148457.htm

          內(nèi)容簡(jiǎn)介: 介紹了Linux下的的設(shè)計(jì)層次及接口, 并指出與TTY終端之間的關(guān)聯(lián)層次(串口可作TTY終端使用), 以及Linux下的中斷處理機(jī)制/中斷共享機(jī)制, 還有串口緩沖機(jī)制當(dāng)中涉及的軟中斷機(jī)制; 其中有關(guān)w83697/w83977 IC方面的知識(shí), 具體參考相關(guān)手冊(cè), 對(duì)串口的配置寄存器有詳細(xì)介紹, 本文不再進(jìn)行說明.

          目錄索引:

          一. Linux的串口接口及層次.

          二. Linux的中斷機(jī)制及中斷共享機(jī)制.

          三. Linux的軟中斷機(jī)制.

          四. TTY與串口的具體關(guān)聯(lián).

          一. Linux的串口接口及層次.

          串口是使用已經(jīng)非常廣的設(shè)備了, 因此在下面的支持已經(jīng)很完善了, 具有統(tǒng)一的編程接口, 者所要完整的工作就是針對(duì)不同的串口IC來做完成相應(yīng)的配置宏, 這此配置宏包括讀與寫, 中斷打開與關(guān)閉(如傳送與接收中斷), 接收狀態(tài)處理, 有FIFO時(shí)還要處理FIFO的狀態(tài). 如下我們就首先切入這一部分, 具體了解一下與硬件串口IC相關(guān)的部分在驅(qū)動(dòng)中的處理, 這一部分可以說是串口驅(qū)動(dòng)中的最基礎(chǔ)部分, 直接與硬件打交道, 完成最底層具體的串口數(shù)據(jù)傳輸.

          1. 串口硬件資源的處理.

          W83697及W83977在ep93xx板子上的映射的硬件物理空間如下:

          W83697: 0x20000000起1K空間.

          W83977: 0x30000000起1K空間.

          因?yàn)榇谠O(shè)備的特殊性, 可以當(dāng)作終端使用, 但是終端的使用在內(nèi)核還未完全初始化之前(關(guān)于串口與終端的關(guān)聯(lián)及層次在第四節(jié)中詳細(xì)), 此時(shí)還沒有通過mem_init()建立內(nèi)核的虛存管理機(jī)制, 所以不能通過ioreamp來進(jìn)行物理內(nèi)存到虛存的映射(物理內(nèi)存必須由內(nèi)核映射成系統(tǒng)管理的虛擬內(nèi)存后才能進(jìn)行讀寫訪問), 這與先前所講的frAMEbuffer的物理內(nèi)存映射是不同的, 具體原因如下:

          √終端在注冊(cè)并使用的調(diào)用路徑如下:

          STart_kernel→cONsole_init→uart_console_init→ep93xxuart_console_init→register_console→csambuart_console_write.

          √FrameBuffer顯卡驅(qū)動(dòng)中的物理內(nèi)存映射調(diào)用路徑如下:

          start_kernel→ rest_init→init(內(nèi)核初始線程)→ do_basic_setup→ do_initcalls→fbmem_init→lanrryfb_init

          (Linux下用__setup啟動(dòng)初期初始機(jī)制與__initcall系統(tǒng)初始化完成后的調(diào)用機(jī)制, 這兩個(gè)機(jī)制本質(zhì)沒有什么差別,主要是執(zhí)行時(shí)所處的系統(tǒng)時(shí)段)

          √串口物理內(nèi)存映射到虛存的時(shí)機(jī):

          依據(jù)上面所介紹的兩條執(zhí)行路徑,再看內(nèi)核的內(nèi)存初始化的調(diào)用時(shí)期,只有完成這個(gè)初始化后才能進(jìn)行物理內(nèi)存到虛存的映射,內(nèi)存的初始化主要是在start_kernel中調(diào)用的mem_init,這個(gè)調(diào)用明顯在uart_console_init之后,在fbmem_init之后,到此就全部說明了為何不能在對(duì)串口使用ioremap進(jìn)行物理內(nèi)存的映射了。那么究竟要在什么時(shí)機(jī)用什么方法進(jìn)行串口物理內(nèi)存的映射呢?

          √串口物理內(nèi)存的映射方式:

          參考ep93xx的板載I/O的映射處理,它的處理方式是一次性將所有的物理I/O所在的內(nèi)存空間映射到虛存空間,映射的基址是IO_BASE_VIRT,大小是IO_SIZE.

          /* Where in virtual memory the IO devices (TImers, system controllers

          * and so on). This gets used in arch/ARM/mach-ep93xx/mm.c.*/

          #define IO_BASE_VIRT 0xFF000000 // Virtual addrESS of IO

          #define IO_BASE_PHYS 0x80000000 // Physical address of IO

          #define IO_SIZE 0x00A00000 // How much?

          完成映射的函數(shù)是ep93xx_map_io, 所有要進(jìn)行映射內(nèi)存都在ep93xx_io_desc結(jié)構(gòu)當(dāng)中描述,我們的串口映射也加在這個(gè)地方,基址分別如下:

          文件: -2.4.21/include/asm-arm/arch-ep93xx/regmap.h

          #define IO_W83697__BASE 0x20000000

          #define IO_W83697__SIZE 0x1000

          #define IO_W83977__BASE 0x30000000

          #define IO_W83977_UART_SIZE 0x1000

          #define IO_SIZE_2 (IO_SIZE+0x100000)

          #define IO_BASE83697_VIRT IO_BASE_VIRT+IO_SIZE

          #define IO_BASE83977_VIRT IO_BASE_VIRT+IO_SIZE_2

          ep93xx_map_io完成是在arch初始化中賦值給struct machine_desc mdesc這個(gè)機(jī)器描述結(jié)構(gòu)體,主要由位于mach-ep93xxarch.c文件中如下宏完成此結(jié)構(gòu)的初始化:

          MACHINE_START(EDB9302, edb9302)

          …..

          MAPIO(ep93xx_map_io) //初始化. map_io= ep93xx_map_io….

          MACHINE_END

          最終這個(gè)函數(shù)在調(diào)用路徑如下:

          start_kernel→setup_arch→paging_init→(mdesc->map_io())

          至此完成串口物理內(nèi)存的映射,這個(gè)過程在console_init調(diào)用之前,因此不會(huì)有問題, 此種方法建立映射是直接創(chuàng)建物理內(nèi)存頁與虛存頁的對(duì)應(yīng),大小為4k一頁,最終調(diào)用的是create_mapping(), 建立頁表映射是與具體的平臺(tái)相關(guān)的,位于mach_ep93xx/mm/ proc-arm920.S文件中提供了與具體平臺(tái)相關(guān)的頁表建立函數(shù),其中包括TLB表操作/Cache操作/頁表操作等:

          在上層的start_kernel→setup_arch→ setup_processor調(diào)用下,會(huì)在proc-arm920.S文件中查找.proc.info節(jié)的__arm920_proc_info,并從中找到配置的process相關(guān)的操作函數(shù),具體的arm頁表建立的詳情須要參看ARM內(nèi)存管理的相關(guān)手冊(cè).

          .section .proc.info, #alloc, #execinstr

          .type __arm920_proc_info,#object

          __arm920_proc_info:

          .long 0x41009200

          ……

          .long arm920_processor_functions

          .size __arm920_proc_info, . - __arm920_proc_info

          在arm920_processor_functions中包含的頁表操作如下:

          /* pgtable */

          .word CPU_arm920_set_pgd

          .word cpu_arm920_set_pmd

          .word cpu_arm920_set_pte

          2. 與串口硬件相關(guān)的宏主.

          如下, 下面將詳術(shù)如下, 并指出其具體被使用的環(huán)境上下文:

          1>. 讀寫數(shù)據(jù).

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

          linux相關(guān)文章:linux教程



          上一頁 1 2 3 4 5 6 下一頁

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();