wordpress二維碼用戶登錄/長(zhǎng)沙網(wǎng)站優(yōu)化
文章目錄
- 一、底層串行硬件驅(qū)動(dòng)程序
- 二、Console支持
- 三、鎖支持
- 四、核心數(shù)據(jù)結(jié)構(gòu)
- 1、struct uart_driver
- 2、struct uart_port
- 3、struct uart_ops
- 四、常用API總結(jié)
- 五、uart驅(qū)動(dòng)示例剖析
- 1、原廠設(shè)計(jì)的uart驅(qū)動(dòng)
- 2、8250標(biāo)準(zhǔn)uart驅(qū)動(dòng)
- 六、總結(jié)
??【linux內(nèi)核系列文章】
??對(duì)一些文章內(nèi)容進(jìn)行了勘誤,本系列文章長(zhǎng)期不定時(shí)更新,希望能分享出優(yōu)質(zhì)的文章!
- 1、《linux內(nèi)核數(shù)據(jù)結(jié)構(gòu)分析之哈希表》
- 2、《一文總結(jié)linux內(nèi)核通知鏈》
- 3、《linux內(nèi)核中的debugfs》
- 4、《linux內(nèi)核數(shù)據(jù)結(jié)構(gòu)分析之鏈表》
- 5、《linux media子系統(tǒng)分析之media控制器設(shè)備》
- 6、《V4L2-PCI驅(qū)動(dòng)程序樣例分析(上)》
- 7、《v4l2框架分析之v4l2_fh》
- 8、《 v4l2框架分析之v4l2_subdev》
- 9、《 v4l2框架分析之v4l2_device》
- 10、《v4l2框架分析之video_device》
- 11、《linux內(nèi)核重要函數(shù) | do_initcalls》
- 12、《Linux設(shè)備驅(qū)動(dòng)模型 | bus》
- 13、《linux內(nèi)核裁剪隨想》
- 14、《基于ARM64分析linux內(nèi)核的鏈接腳本vmlinux.lds.S》
- 15、《linux內(nèi)核start_kernel函數(shù)的早期操作》
- 16、《start_kernel函數(shù)詳解系列之proc_caches_init》
- 17、《start_kernel函數(shù)詳解系列之fork_init》
- 18、《start_kernel函數(shù)詳解系列之rcu_init》
- 19、《start_kernel函數(shù)詳解系列之proc_root_init》
- 20、《start_kernel詳解系列之【setup_arch】》
- 21、《linux內(nèi)核如何啟動(dòng)用戶空間進(jìn)程(上)》
- 22、《linux內(nèi)核如何啟動(dòng)用戶空間進(jìn)程(下)》
- 23、《一文總結(jié)linux內(nèi)核的完成量機(jī)制》
- 24、《一文總結(jié)linux內(nèi)核設(shè)備驅(qū)動(dòng)的注冊(cè)和卸載》
- 25、《linux內(nèi)核的啟動(dòng)加載程序的總結(jié)》
- 26、《linux內(nèi)核入口:head.o》
- 27、《掛載根文件系統(tǒng)之rootfs》
- 28、《mount系統(tǒng)調(diào)用剖析》
- 29、《devtmpfs文件系統(tǒng)分析》
- 30、《linux內(nèi)核的kthreadd線程》
- 31、《linux內(nèi)核的進(jìn)程調(diào)度—調(diào)度策略》
- 32、《linux系統(tǒng)調(diào)用實(shí)踐(Arm架構(gòu))》
- 33、《對(duì)linux內(nèi)核__init機(jī)制的實(shí)踐》
- 34、《linux 內(nèi)核中EXPORT_SYMBOL()分析與實(shí)踐》
- 35、《linux內(nèi)核如何掛載根文件系統(tǒng)》
- 36、《linux內(nèi)核如何喚醒線程》
- 37、《linux內(nèi)核的init線程》
- 38、《linux內(nèi)核偽文件系統(tǒng)—sysfs分析》
- 39、《linux 內(nèi)核設(shè)備模型的初始化(上)》
- 40、《linux 內(nèi)核設(shè)備模型的初始化(下)》
- 41、《linux內(nèi)核偽文件系統(tǒng)—proc分析》
- 42、《linux中斷管理—workqueue工作隊(duì)列》
- 43、《linux中斷管理—軟中斷》
- 44、《linux中斷管理 | tasklet》
- 45、《linux中斷管理 | 中斷管理框架(01)》
- 46、《linux內(nèi)存管理 | 分配物理內(nèi)存頁(yè)面》
- 47、《linux內(nèi)存管理 | 釋放內(nèi)存頁(yè)面》
- 48、《對(duì)linux內(nèi)核設(shè)備的注冊(cè)機(jī)制和查找機(jī)制分析》
- 49、《linux內(nèi)核設(shè)備驅(qū)動(dòng)的注冊(cè)機(jī)制》
linux源碼相關(guān)文件:
- serial-core.c
- include/linux/serial_core.h
一、底層串行硬件驅(qū)動(dòng)程序
底層串行硬件的驅(qū)動(dòng)程序負(fù)責(zé)向serial核心驅(qū)動(dòng)程序提供由struct uart_port
定義的端口信息和一組由struct uart_ops
定義的控制方法,底層驅(qū)動(dòng)程序還負(fù)責(zé)處理端口的中斷,并提供對(duì)控制臺(tái)的支持。
二、Console支持
serial核心提供了一些助手函數(shù):
uart_get_console()
識(shí)別正確的端口結(jié)構(gòu)。uart_parse_options()
解析命令行參數(shù)。uart_console_write()
用于執(zhí)行逐字符寫入,將換行符轉(zhuǎn)換為CRLF序列。在驅(qū)動(dòng)程序編寫的時(shí)候建議使用此函數(shù),而不是實(shí)現(xiàn)新的寫入接口。
三、鎖支持
底層硬件驅(qū)動(dòng)程序負(fù)責(zé)使用port->lock
執(zhí)行必要的鎖定。支持兩把鎖:一個(gè)是端口自旋鎖,另一個(gè)是overall
信號(hào)量。從uart核心驅(qū)動(dòng)程序的角度來(lái)看,port->lock
用于鎖定以下的數(shù)據(jù):
port->mctrl
port->icount
port->state->xmit.head (circ_buf->head)
port->state->xmit.tail (circ_buf->tail)
底層驅(qū)動(dòng)程序可以自由地使用該鎖來(lái)實(shí)現(xiàn)額外的鎖定,port_mutex
互斥量用于防止在不適當(dāng)?shù)臅r(shí)間添加、刪除或重新配置端口。
四、核心數(shù)據(jù)結(jié)構(gòu)
1、struct uart_driver
struct uart_driver
結(jié)構(gòu)表示具體UART驅(qū)動(dòng)。該結(jié)構(gòu)定義如下(/include/linux/serial_core.h):
struct uart_driver {struct module *owner; //驅(qū)動(dòng)模塊的擁有者const char *driver_name; //驅(qū)動(dòng)名稱const char *dev_name; //設(shè)備名稱int major; //主設(shè)備號(hào)int minor; //從設(shè)備號(hào)int nr;struct console *cons; //console/** these are private; the low level driver should not* touch these; they should be initialised to NULL*/struct uart_state *state; //uart狀態(tài)struct tty_driver *tty_driver; //描述ttydriver
};
2、struct uart_port
struct uart_port
表示一個(gè)具體的port,該結(jié)構(gòu)定義如下(include/linux/serial_core.h):
struct uart_port {spinlock_t lock; /* port 鎖 */unsigned long iobase; /* 輸入/輸出地址 */unsigned char __iomem *membase; /* read/write[bwl] */unsigned int (*serial_in)(struct uart_port *, int);void (*serial_out)(struct uart_port *, int, int);void (*set_termios)(struct uart_port *,struct ktermios *new,struct ktermios *old);void (*set_mctrl)(struct uart_port *, unsigned int);int (*startup)(struct uart_port *port);void (*shutdown)(struct uart_port *port);void (*throttle)(struct uart_port *port);void (*unthrottle)(struct uart_port *port);int (*handle_irq)(struct uart_port *);void (*pm)(struct uart_port *, unsigned int state,unsigned int old);void (*handle_break)(struct uart_port *);int (*rs485_config)(struct uart_port *,struct serial_rs485 *rs485);unsigned int irq; /* irq number */unsigned long irqflags; /* irq flags */unsigned int uartclk; /* base uart clock */unsigned int fifosize; /* tx fifo size */unsigned char x_char; /* xon/xoff char */unsigned char regshift; /* reg offset shift */unsigned char iotype; /* io access style */unsigned char unused1;unsigned int read_status_mask; /* driver specific */unsigned int ignore_status_mask; /* driver specific */struct uart_state *state; /* 指向父狀態(tài)的指針 */struct uart_icount icount; /* 通信信息 */struct console *cons; /* struct console, if any */
#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)unsigned long sysrq; /* sysrq timeout */
#endif/* flags must be updated while holding port mutex */upf_t flags;#if __UPF_CHANGE_MASK > ASYNC_FLAGS
#error Change mask not equivalent to userspace-visible bit defines
#endif/** Must hold termios_rwsem, port mutex and port lock to change;* can hold any one lock to read.*/upstat_t status;int hw_stopped; /* sw-assisted CTS flow state */unsigned int mctrl; /* 當(dāng)前調(diào)制解調(diào)器CTRL設(shè)置 */