標籤:
彭東林
郵箱:[email protected]
開發板:tiny4412ADK+S700 4GB Flash
主機:Wind7 64位
虛擬機器:Vmware+Ubuntu12_04
u-boot:U-Boot 2010.12
Linux核心版本:linux-3.0.31
Android版本:android-4.1.2
在上面我們知道了/dev/ttySACx是如何產生的,此外還可以看到在/dev下還有裝置結點/dev/console,以及/dev/tty等裝置結點。
可以看到向/dev/ttySAC0、/dev/console和/dev/tty輸入字元,然後這些字元會輸出到串口終端上:
但是如果使用adb shell登陸後,現象不同:
其中,左邊的視窗是在adb shell下,右邊的視窗是串口終端的顯示,可以看到如果在adb shell下向 /dev/ttySAC0和 /dev/console下寫入字元的話,這個字元並沒有在adb shell終端下顯示,相反卻在串口終端中顯示出來,當在adb shell終端下向/dev/tty下寫入字元時,就在adb shell終端下顯示出來了,並沒有影響到串口終端的顯示。
上面的這些現象背後的原因是什麼呢?下面我們開始分析核心源碼來解釋。
首先需要知道這些裝置結點是怎麼產生的:
late_initcall(chr_dev_init);
---- tty_init() (drivers/tty/tty_io.c)
int __init tty_init(void){ cdev_init(&tty_cdev, &tty_fops); if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) panic("Couldn‘t register /dev/tty driver\n"); device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); cdev_init(&console_cdev, &console_fops); if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) panic("Couldn‘t register /dev/console driver\n"); consdev = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); if (IS_ERR(consdev)) consdev = NULL; else WARN_ON(device_create_file(consdev, &dev_attr_active) < 0); return 0;}
在這裡會在/dev/下產生console和tty兩個裝置結點,他們對應的fops分別是tty_fops和console_fops。
在上面分析的tty_register_device函數會產生/dev/ttySACx,它對應的fops在函數tty_register_driver中設定為了tty_fops。所以這裡的關鍵是分析tty_fops和console_fops是如何?的。
對比發現,console_fops和tty_fops是一樣的:
static const struct file_operations tty_fops = { .llseek = no_llseek, .read = tty_read, .write = tty_write, .poll = tty_poll, .unlocked_ioctl = tty_ioctl, .compat_ioctl = tty_compat_ioctl, .open = tty_open, .release = tty_release, .fasync = tty_fasync,};static const struct file_operations console_fops = { .llseek = no_llseek, .read = tty_read, .write = redirected_tty_write, .poll = tty_poll, .unlocked_ioctl = tty_ioctl, .compat_ioctl = tty_compat_ioctl, .open = tty_open, .release = tty_release, .fasync = tty_fasync,};
執行echo “peng” > /dev/ttySAC0的時候,會先調用tty_open然後調用tty_write,最後調用tty_release。
tiny4412 串口驅動分析九 --- shell終端