linux UART串口驅(qū)動(dòng)開(kāi)發(fā)文檔
發(fā)布時(shí)間:2009/2/2 0:00:00 訪問(wèn)次數(shù):888
w83697/w83977 super i/o串口驅(qū)動(dòng)開(kāi)發(fā)
內(nèi)容簡(jiǎn)介: 介紹了linux下的串口驅(qū)動(dòng)的設(shè)計(jì)層次及接口, 并指出串口與tty終端之間的關(guān)聯(lián)層次(串口可作tty終端使用), 以及l(fā)inux下的中斷處理機(jī)制/中斷共享機(jī)制, 還有串口緩沖機(jī)制當(dāng)中涉及的軟中斷機(jī)制; 其中有關(guān)w83697/w83977 ic方面的知識(shí), 具體參考相關(guān)手冊(cè), 對(duì)串口的配置寄存器有詳細(xì)介紹, 本文不再進(jìn)行說(shuō)明.
目錄索引:
一. linux的串口接口及層次.
二. linux的中斷機(jī)制及中斷共享機(jī)制.
三. linux的軟中斷機(jī)制.
四. tty與串口的具體關(guān)聯(lián).
一. linux的串口接口及層次.
串口是使用已經(jīng)非常廣的設(shè)備了, 因此在linux下面的支持已經(jīng)很完善了, 具有統(tǒng)一的編程接口, 驅(qū)動(dòng)開(kāi)發(fā)者所要完整的工作就是針對(duì)不同的串口ic來(lái)做完成相應(yīng)的配置宏, 這此配置宏包括讀與寫(xiě), 中斷打開(kāi)與關(guān)閉(如傳送與接收中斷), 接收狀態(tài)處理, 有fifo時(shí)還要處理fifo的狀態(tài). 如下我們就首先切入這一部分, 具體了解一下與硬件串口ic相關(guān)的部分在驅(qū)動(dòng)中的處理, 這一部分可以說(shuō)是串口驅(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í)還沒(méi)有通過(guò)mem_init()建立內(nèi)核的虛存管理機(jī)制, 所以不能通過(guò)ioreamp來(lái)進(jìn)行物理內(nèi)存到虛存的映射(物理內(nèi)存必須由內(nèi)核映射成系統(tǒng)管理的虛擬內(nèi)存后才能進(jìn)行讀寫(xiě)訪問(wè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ì)沒(méi)有什么差別,主要是執(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之后,到此就全部說(shuō)明了為何不能在對(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è)地方,基址分別如下:
文件: linux-2.4.21/include/asm-arm/arch-ep93xx/regmap.h
#define io_w83697_uart_base 0x20000000
#define io_w83697_uart_size 0x1000
#define io_w83977_uart_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è)過(guò)程在console
w83697/w83977 super i/o串口驅(qū)動(dòng)開(kāi)發(fā)
內(nèi)容簡(jiǎn)介: 介紹了linux下的串口驅(qū)動(dòng)的設(shè)計(jì)層次及接口, 并指出串口與tty終端之間的關(guān)聯(lián)層次(串口可作tty終端使用), 以及l(fā)inux下的中斷處理機(jī)制/中斷共享機(jī)制, 還有串口緩沖機(jī)制當(dāng)中涉及的軟中斷機(jī)制; 其中有關(guān)w83697/w83977 ic方面的知識(shí), 具體參考相關(guān)手冊(cè), 對(duì)串口的配置寄存器有詳細(xì)介紹, 本文不再進(jìn)行說(shuō)明.
目錄索引:
一. linux的串口接口及層次.
二. linux的中斷機(jī)制及中斷共享機(jī)制.
三. linux的軟中斷機(jī)制.
四. tty與串口的具體關(guān)聯(lián).
一. linux的串口接口及層次.
串口是使用已經(jīng)非常廣的設(shè)備了, 因此在linux下面的支持已經(jīng)很完善了, 具有統(tǒng)一的編程接口, 驅(qū)動(dòng)開(kāi)發(fā)者所要完整的工作就是針對(duì)不同的串口ic來(lái)做完成相應(yīng)的配置宏, 這此配置宏包括讀與寫(xiě), 中斷打開(kāi)與關(guān)閉(如傳送與接收中斷), 接收狀態(tài)處理, 有fifo時(shí)還要處理fifo的狀態(tài). 如下我們就首先切入這一部分, 具體了解一下與硬件串口ic相關(guān)的部分在驅(qū)動(dòng)中的處理, 這一部分可以說(shuō)是串口驅(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í)還沒(méi)有通過(guò)mem_init()建立內(nèi)核的虛存管理機(jī)制, 所以不能通過(guò)ioreamp來(lái)進(jìn)行物理內(nèi)存到虛存的映射(物理內(nèi)存必須由內(nèi)核映射成系統(tǒng)管理的虛擬內(nèi)存后才能進(jìn)行讀寫(xiě)訪問(wè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ì)沒(méi)有什么差別,主要是執(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之后,到此就全部說(shuō)明了為何不能在對(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è)地方,基址分別如下:
文件: linux-2.4.21/include/asm-arm/arch-ep93xx/regmap.h
#define io_w83697_uart_base 0x20000000
#define io_w83697_uart_size 0x1000
#define io_w83977_uart_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è)過(guò)程在console
熱門(mén)點(diǎn)擊
- ARM通用寄存器
- PIE中斷向量的映射方式
- PIE模塊級(jí)中斷
- ARM復(fù)位原理
- FIQ異常的描述
- ARM硬件電路設(shè)計(jì)
- ARM程序狀態(tài)寄存器
- ARM時(shí)序
- 什么是嵌入式實(shí)時(shí)操作系統(tǒng)
- 計(jì)算機(jī)操作系統(tǒng)調(diào)度策略(箅法)
推薦技術(shù)資料
- DFRobot—玩的就是
- 如果說(shuō)新車間的特點(diǎn)是“靈動(dòng)”,F(xiàn)QPF12N60C那么... [詳細(xì)]
- 100A全集成電源模塊R
- Teseo-VIC6A GNSS車用精準(zhǔn)定位
- 高效先進(jìn)封裝工藝
- 模數(shù)轉(zhuǎn)換器 (Analog-to-Digit
- 集成模數(shù)轉(zhuǎn)換器(ADC)
- 128 通道20 位電流數(shù)字轉(zhuǎn)換器̴
- 多媒體協(xié)處理器SM501在嵌入式系統(tǒng)中的應(yīng)用
- 基于IEEE802.11b的EPA溫度變送器
- QUICCEngine新引擎推動(dòng)IP網(wǎng)絡(luò)革新
- SoC面世八年后的產(chǎn)業(yè)機(jī)遇
- MPC8xx系列處理器的嵌入式系統(tǒng)電源設(shè)計(jì)
- dsPIC及其在交流變頻調(diào)速中的應(yīng)用研究