www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 芯聞號(hào) > 充電吧
[導(dǎo)讀]TTY驅(qū)動(dòng)程序架構(gòu) 1. TTY感念解析 在Linux系統(tǒng)中,終端是一類字符型設(shè)備,它包括多種類型,通常使用tty來簡稱各種類型的終端設(shè)備。 ? 串口終端(/dev/ttyS*) 串口終

TTY驅(qū)動(dòng)程序架構(gòu)
1. TTY感念解析
在Linux系統(tǒng)中,終端是一類字符型設(shè)備,它包括多種類型,通常使用tty來簡稱各種類型的終端設(shè)備。 ? 串口終端(/dev/ttyS*) 串口終端是使用計(jì)算機(jī)串口連接的終端設(shè)備。Linux把每個(gè)串行端口都看作是一個(gè)字符設(shè)備。這些串行端口所對(duì)應(yīng)的設(shè)備名稱是 /dev/ttySAC0; /dev/ttySAC1……
? 控制臺(tái)終端(/dev/console) 在Linux系統(tǒng)中,計(jì)算機(jī)的輸出設(shè)備通常被稱為控制臺(tái)終端(Console),這里特指printk信息輸出到的設(shè)備。
/dev/console是一個(gè)虛擬的設(shè)備,它需要映射到真正的tty上,比如通過內(nèi)核啟動(dòng)參數(shù)” console=ttySAC0”就把console映射到了串口0。
? 虛擬終端(/dev/tty*) 當(dāng)用戶登錄時(shí),使用的是虛擬終端。使用Ctcl+Alt+[F1—F6]組合鍵時(shí),我們就可以切換到tty1、tty2、tty3等上面去。tty1–tty6等稱為虛擬終端,而tty0則是當(dāng)前所使用虛擬終端的一個(gè)別名.

串口終端和控制臺(tái)終端是從內(nèi)核啟動(dòng)時(shí)就關(guān)聯(lián)的,內(nèi)核通過printk來調(diào)用控制臺(tái)終端,從而在串口中顯示。
串口終端又有多種虛擬終端tty1,tty2,tty3...等用來個(gè)應(yīng)用程序使用。

2.TTY架構(gòu)分析?
Linux tty子系統(tǒng)包含:tty核心,tty線路規(guī)程和tty驅(qū)動(dòng)。
①?tty核心是對(duì)整個(gè)tty設(shè)備的抽象,對(duì)用戶提供統(tǒng)一的接口。
②?tty線路規(guī)程是對(duì)傳輸數(shù)據(jù)的格式化。
③?tty驅(qū)動(dòng)則是面向tty設(shè)備的硬件驅(qū)動(dòng)。


3.查看tty調(diào)用流程(回溯dump_stack())
linux-tq2440/drivers/serial/samsung.c:
在s3c24xx_serial_start_tx()中添加一行:
dump_stack();
目的是調(diào)用回溯函數(shù)。然后編譯內(nèi)核make uImage ARCH=arm CROSS_COMPILE=arm-linux-,啟動(dòng)開發(fā)板調(diào)試:
Backtrace: [] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c) r7:c394c802 r6:00000000 r5:c38bda00 r4:c04caf20 [] (dump_stack+0x0/0x1c) from [] (s3c24xx_serial_start_tx+0x14/0x64) [] (s3c24xx_serial_start_tx+0x0/0x64) from [] (uart_start+0x68/0x6c) r5:c38bda00 r4:60000013 [] (uart_start+0x0/0x6c) from [] (uart_write+0xc0/0xe4) r5:c38bda00 r4:00000000 [] (uart_write+0x0/0xe4) from [] (n_tty_write+0x1d8/0x448) [] (n_tty_write+0x0/0x448) from [] (tty_write+0x14c/0x244) [] (tty_write+0x0/0x244) from [] (redirected_tty_write+0x88/0x98) [] (redirected_tty_write+0x0/0x98) from [] (vfs_write+0xb4/0xe8) r9:c39ca000 r8:c0045008 r7:00000004 r6:c39cbf78 r5:40000000 r4:c3953680 [] (vfs_write+0x0/0xe8) from [] (sys_write+0x4c/0x84) r7:00000004 r6:c3953680 r5:00000000 r4:00000000 [] (sys_write+0x0/0x84) from [] (ret_fast_syscall+0x0/0x2c) r6:001d27f8 r5:40000000 r4:00000002 redirected_tty_write:
ssize_t redirected_tty_write(struct file *file, const char __user *buf,
????????????????????????size_t count, loff_t *ppos)
{
????struct file *p = NULL;

????spin_lock(&redirect_lock);
????if (redirect) {
????????get_file(redirect);
????????p = redirect;
????}
????spin_unlock(&redirect_lock);

????if (p) {
????????ssize_t res;
????????res = vfs_write(p, buf, count, &p->f_pos);
????????fput(p);
????????return res;
????}
????return tty_write(file, buf, count, ppos); ? ? ? ? ? ? ? ? ? ?//這里調(diào)用了tty_write
} tty_write:
static ssize_t tty_write(struct file *file, const char __user *buf,
????????????????????????size_t count, loff_t *ppos)
{
????struct tty_struct *tty;
????struct inode *inode = file->f_path.dentry->d_inode;
????ssize_t ret;
????struct tty_ldisc *ld;

????tty = (struct tty_struct *)file->private_data;
????if (tty_paranoia_check(tty, inode, "tty_write"))
????????return -EIO;
????if (!tty || !tty->ops->write ||
????????(test_bit(TTY_IO_ERROR, &tty->flags)))
????????????return -EIO;
????/* Short term debug to catch buggy drivers */
????if (tty->ops->write_room == NULL)
????????printk(KERN_ERR "tty driver %s lacks a write_room method.n",
????????????tty->driver->name);
????ld = tty_ldisc_ref_wait(tty);
????if (!ld->ops->write)
????????ret = -EIO;
????else
????????ret = do_tty_write(ld->ops->write, tty, file, buf, count); ? ? ?//這里調(diào)用了do_tty_write,ld就是結(jié)構(gòu)體tty_ldisc(tty線路規(guī)程)
????tty_ldisc_deref(ld);
????return ret;
} tty_write>>struct tty_ldisc:
struct tty_ldisc {
????struct tty_ldisc_ops *ops; ? ? ? ? ? ? ? ? ? //此處就是它調(diào)用的tty_ldisc_ops結(jié)構(gòu)
????int refcount;
}; 然后tty_ldisc中的tty_ldisc_ops在n_tty.c中被定義好了:
struct tty_ldisc_ops tty_ldisc_N_TTY = {
????.magic = TTY_LDISC_MAGIC,
????.name = "n_tty",
????.open = n_tty_open,
????.close = n_tty_close,
????.flush_buffer = n_tty_flush_buffer,
????.chars_in_buffer = n_tty_chars_in_buffer,
????.read = n_tty_read,
????.write = n_tty_write, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//在這,所以調(diào)用do_tty_write其實(shí)就是調(diào)用了n_tty_write
????.ioctl = n_tty_ioctl,
????.set_termios = n_tty_set_termios,
????.poll = n_tty_poll,
????.receive_buf = n_tty_receive_buf,
????.write_wakeup = n_tty_write_wakeup
}; n_tty_write:
/**
?*????n_tty_write????????-????write function for tty
?*????@tty: tty device
?*????@file: file object
?*????@buf: userspace buffer pointer
?*????@nr: size of I/O
?*
?*????Write function of the terminal device. This is serialized with
?*????respect to other write callers but not to termios changes, reads
?*????and other such events. Since the receive code will echo characters,
?*????thus calling driver write methods, the output_lock is used in
?*????the output processing functions called here as well as in the
?*????echo processing function to protect the column state and space
?*????left in the buffer.
?*
?*????This code must be sure never to sleep through a hangup.
?*
?*????Locking: output_lock to protect column state and space left
?*???????? (note that the process_output*() functions take this
?*???????? ?lock themselves)
?*/

static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
???????????? const unsigned char *buf, size_t nr)
{
????const unsigned char *b = buf;
????DECLARE_WAITQUEUE(wait, current);
????int c;
????ssize_t retval = 0;

????/* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
????if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) {
????????retval = tty_check_change(tty);
????????if (retval)
????????????return retval;
????}

????/* Write out any echoed characters that are still pending */
????process_echoes(tty);

????add_wait_queue(&tty->write_wait, &wait);
????while (1) {
????????set_current_state(TASK_INTERRUPTIBLE);
????????if (signal_pending(current)) {
????????????retval = -ERESTARTSYS;
????????????break;
????????}
????????if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
????????????retval = -EIO;
????????????break;
????????}
????????if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
????????????while (nr > 0) {
????????????????ssize_t num = process_output_block(tty, b, nr);
????????????????if (num < 0) {
????????????????????if (num == -EAGAIN)
????????????????????????break;
????????????????????retval = num;
????????????????????goto break_out;
????????????????}
????????????????b += num;
????????????????nr -= num;
????????????????if (nr == 0)
????????????????????break;
????????????????c = *b;
????????????????if (process_output(c, tty) < 0)
????????????????????break;
????????????????b++; nr--;
????????????}
????????????if (tty->ops->flush_chars)
????????????????tty->ops->flush_chars(tty);
????????} else {
????????????while (nr > 0) {
????????????????c = tty->ops->write(tty, b, nr); ? ? ? ? //這里的tty->ops->write和上面的類似,tty_struct結(jié)構(gòu),調(diào)用了uart_write。
????????????????if (c < 0) {
????????????????????retval = c;
????????????????????goto break_out;
????????????????}
????????????????if (!c)
????????????????????break;
????????????????b += c;
????????????????nr -= c;
????????????}
????????}
????????if (!nr)
????????????break;
????????if (file->f_flags & O_NONBLOCK) {
????????????retval = -EAGAIN;
????????????break;
????????}
????????schedule();
????}
break_out:
????__set_current_state(TASK_RUNNING);
????remove_wait_queue(&tty->write_wait, &wait);
????if (b - buf != nr && tty->fasync)
????????set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
????return (b - buf) ? b - buf : retval;
} serial_core.c:
static int
uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
????struct uart_state *state = tty->driver_data;
????struct uart_port *port;
????struct circ_buf *circ;
????unsigned long flags;
????int c, ret = 0;

????/*
???? * This means you called this function _after_ the port was
???? * closed. No cookie for you.
???? */
????if (!state) {
????????WARN_ON(1);
????????return -EL3HLT;
????}

????port = state->port;
????circ = &state->info.xmit;

????if (!circ->buf)
????????return 0;

????spin_lock_irqsave(&port->lock, flags);
????while (1) {
????????c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
????????if (count < c)
????????????c = count;
????????if (c <= 0)
????????????break;
????????memcpy(circ->buf + circ->head, buf, c);
????????circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
????????buf += c;
????????count -= c;
????????ret += c;
????}
????spin_unlock_irqrestore(&port->lock, flags);

????uart_start(tty); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//這里調(diào)用了uart_start
????return ret;
} 同一個(gè)文件:
static void __uart_start(struct tty_struct *tty)
{
????struct uart_state *state = tty->driver_data;
????struct uart_port *port = state->port;

????if (!uart_circ_empty(&state->info.xmit) && state->info.xmit.buf &&
???? !tty->stopped && !tty->hw_stopped)
????????port->ops->start_tx(port); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//這里的port->ops->start_tx,估計(jì)就是指向s3c24xx_serial_start_tx }

static void uart_start(struct tty_struct *tty)
{
????struct uart_state *state = tty->driver_data;
????struct uart_port *port = state->port;
????unsigned long flags;

????spin_lock_irqsave(&port->lock, flags);
????__uart_start(tty); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//這里調(diào)用了__uart_start
????spin_unlock_irqrestore(&port->lock, flags);
}

? ? ? ? ??

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉