关系 关系2 和 关系图 怎么使用串口
/ dev/ console : 指向一个 tty 设备 , cmdline 中的 console= xxx,可以是 virtual 终端 , 串口终端, 不可以是网络终端
/ dev/ tty : 当前终端 , 可以接入 virtual 终端 , 串口终端, 网络终端
/ dev/ tty[ 0 - 63 ] : virtual 终端 (液晶显示器的虚拟终端), 所谓的vt
: 但是最多有 7 个tty啊( tty1- tty7)
: tty0 等同于 tty1
/ dev/ ttyS[ 0 - 31 ] : 9 针串口终端 (只针对x86,在arm平台,如果是三星,则是 ttySAC[ 0 - 31 ] )
在2.6 以后的内核中,部分三星芯片(例如S3C24x0等)将串口终端设备节点命名为ttySACn。
TI的Omap系列芯片从2.6 .37 开始芯片自带的UART设备开始使用专有的的omap- uart驱动,故设备节点命名为ttyOn,
以区别于使用8250 驱动时的设备名“ttySn”
/ dev/ pts/ [ 0 - 31 ] : 伪终端( Pseudo Terminal) 网络通过telnet服务或者sshd服务接入的终端
/ dev/ ttyprintk :
如果用户空间的 printf ( ) 和内核空间的 printk ( ) 同时执行,二者的输出会互相干扰,内核为此提供了 / dev/ ttyprintk 设备文件,可以将用户空间的信息打印到这个设备中,
这样用户信息与内核信息就会顺序输出,输出的消息会自带 [ U] 前缀。对于没有 / dev/ ttyprintk 设备的系统,可以用 / dev/ kmsg 代替,只是没有了 [ U] 标识,需要用户自己添加前缀。
uart_register_driver ( & stm32_usart_driver) ;
1406 static struct uart_driver stm32_usart_driver = {
1407 . driver_name = DRIVER_NAME,
1408 . dev_name = STM32_SERIAL_NAME,
1409 . major = 0 ,
1410 . minor = 0 ,
1411 . nr = STM32_MAX_PORTS,
1412 . cons = & stm32_console,
1413 } ;
1390 static struct console stm32_console = {
1391 . name = STM32_SERIAL_NAME,
1392 . device = uart_console_device,
1393 . write = stm32_console_write,
1394 . setup = stm32_console_setup,
1395 . flags = CON_PRINTBUFFER,
1396 . index = - 1 ,
1397 . data = & stm32_usart_driver,
1398 } ;
941 static const struct uart_ops stm32_uart_ops = {
942 . tx_empty = stm32_tx_empty,
943 . set_mctrl = stm32_set_mctrl,
944 . get_mctrl = stm32_get_mctrl,
945 . stop_tx = stm32_stop_tx,
946 . start_tx = stm32_start_tx,
947 . throttle = stm32_throttle,
948 . unthrottle = stm32_unthrottle,
949 . stop_rx = stm32_stop_rx,
950 . enable_ms = stm32_enable_ms,
951 . break_ctl = stm32_break_ctl,
952 . startup = stm32_startup,
953 . shutdown = stm32_shutdown,
954 . set_termios = stm32_set_termios,
955 . pm = stm32_pm,
956 . type = stm32_type,
957 . release_port = stm32_release_port,
958 . request_port = stm32_request_port,
959 . config_port = stm32_config_port,
960 . verify_port = stm32_verify_port,
961 } ;
platform_driver_register ( & stm32_serial_driver) ;
stm32_serial_probe
stm32_init_port ( stm32port, pdev) ;
struct uart_port * port = & stm32port-> port;
port-> iotype = UPIO_MEM;
port-> ops = & stm32_uart_ops;
port-> irq = platform_get_irq ( pdev, 0 ) ;
port-> membase = devm_ioremap_resource ( & pdev-> dev, res) ;
port-> mapbase = res-> start;
uart_add_one_port ( & stm32_usart_driver, & stm32port-> port) ;
stm32_startup
request_threaded_irq ( port-> irq, stm32_interrupt, stm32_threaded_interrupt, IRQF_NO_SUSPEND, name, port) ;
low level
stm32_console_write
uart_console_write ( port, s, cnt, stm32_console_putchar) ;
stm32_console_putchar
while ( ! ( readl_relaxed ( port-> membase + ofs-> isr) & USART_SR_TXE) ) cpu_relax ( ) ;
writel_relaxed ( ch, port-> membase + ofs-> tdr) ;
stm32_start_tx
stm32_transmit_chars
if ( stm32_port-> tx_ch) stm32_transmit_chars_dma
else stm32_transmit_chars_pio
while ( ! uart_circ_empty ( xmit) ) {
if ( ! ( readl_relaxed ( port-> membase + ofs-> isr) & USART_SR_TXE) ) break ;
writel_relaxed ( xmit-> buf[ xmit-> tail] , port-> membase + ofs-> tdr) ;
}
1 乍看 之下有两套 底层函数来打印东西
2
3 这分别对应了 内核态的printk 和 用户态的 printf
4
5 console 这套 , 如果是内核态调用 printk 来做的,切指定了这个console= xxx, 则都会调用到 console 的底层函数
如果是内核打印,这个console和 tty没关系
如果/ dev/ ttySTM0 恰好是 console ,那么用户态时,console就和tty有关系了 , 即 / dev/ console 和 / dev/ ttySTM0 的关系
console 只能链接到唯一的 tty , 但是 我们 可以在 多个tty上建立交互
6 stm32_uart_ops 这套,如果用户态调用 write 系统调用来做的,切指定了这个tty(/ dev/ ttySTMx),则会调用到 stm32_uart_ops的底层函数,
这套的上层子系统是 tty
7
8
9
10
11 如果 刚好 / dev/ ttySTM0 恰好是 console , 则他们就会往同一个串口输出。相当于
12 用户态和内核态用不同的API 分时复用这个串口
busybox 支持 microcom , 目前好像支持的波特率有
9600
19200
38400
57600
115200
230400
460800
921600
1843200
3686400
7372800
14745600
29491200
58982400
117964800
235929600
microcom - s 115200 / dev/ ttySTM0
具体查看 uart_parse_options
console= ttySTM0, 115200 n8n
ttySTM0
115200 波特率 baud rate
n 是否校验 parity
8 数据bit个数 number of data bits
n 是否支持流控 flow control character