博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
串口 (四) linux串口之驱动代码
阅读量:4285 次
发布时间:2019-05-27

本文共 9350 字,大约阅读时间需要 31 分钟。

early console 之 early printk

需要平台侧实现 printch

early console 之 earlycon

//驱动需要实现的代码     static void pl011_putc(struct uart_port *port, int c)                              {
while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) // 寄存器在平台相关侧定义,基址有上层传入 ; writeb(c, port->membase + UART01x_DR); while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY) ; } static void pl011_early_write(struct console *con, const char *s, unsigned n) {
struct earlycon_device *dev = con->data; uart_console_write(&dev->port, s, n, pl011_putc); } static int __init pl011_early_console_setup(struct earlycon_device *device, const char *opt) {
if (!device->port.membase) return -ENODEV; device->con->write = pl011_early_write; return 0; } // 可见,提供给kernel 的只是一个函数,这个函数的第一个参数是个 earlycon_device 的句柄.//of_setup_earlycon // 地址 波特率 iotype 已经从dts众解析且被传入 early_console_dev //setup(&early_console_dev, NULL); // 该 setup 就是 pl011_early_console_setup. //register_console(early_console_dev.con); EARLYCON_DECLARE(pl011, pl011_early_console_setup); OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup);// 具体使用的时候会使用 printk ---> early_console_dev->con->write ---> pl011_putc

console

console 一般用 console_initcall 声明,并在声明函数中 register_console还可以 在 串口注册的时候 uart_add_one_port ---> register_console
  • console_initcall
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE                                                                                                                                  static struct console s3c24xx_serial_console;                                                                                                                             static int __init s3c24xx_serial_console_init(void)                                    {
register_console(&s3c24xx_serial_console); return 0; } console_initcall(s3c24xx_serial_console_init); #define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console #else #define S3C24XX_SERIAL_CONSOLE NULL #endif static struct console s3c24xx_serial_console = {
.name = S3C24XX_SERIAL_NAME, .device = uart_console_device, .flags = CON_PRINTBUFFER, .index = -1, .write = s3c24xx_serial_console_write, .setup = s3c24xx_serial_console_setup, .data = &s3c24xx_uart_drv, };
  • uart_add_one_port
控制台也可以在 使用 uart_add_one_port(&amba_reg, &uap->port); 的 时候注册  static struct uart_driver amba_reg = {
.owner = THIS_MODULE, .driver_name = "ttyAMA", .dev_name = "ttyAMA", .major = SERIAL_AMBA_MAJOR, .minor = SERIAL_AMBA_MINOR, .nr = UART_NR, .cons = AMBA_CONSOLE, }; #define AMBA_CONSOLE (&amba_console) static struct console amba_console = {
.name = "ttyAMA", .write = pl011_console_write, .device = uart_console_device, .setup = pl011_console_setup, .flags = CON_PRINTBUFFER, .index = -1, .data = &amba_reg, }; probe uart_add_one_port(&amba_reg, &uap->port); register_console

串口注册设备 /dev/ttyXXX

static struct uart_ops s3c24xx_serial_ops = {
.pm = s3c24xx_serial_pm, .tx_empty = s3c24xx_serial_tx_empty, .get_mctrl = s3c24xx_serial_get_mctrl, .set_mctrl = s3c24xx_serial_set_mctrl, .stop_tx = s3c24xx_serial_stop_tx, .start_tx = s3c24xx_serial_start_tx, .stop_rx = s3c24xx_serial_stop_rx, .break_ctl = s3c24xx_serial_break_ctl, .startup = s3c24xx_serial_startup, .shutdown = s3c24xx_serial_shutdown, .set_termios = s3c24xx_serial_set_termios, .type = s3c24xx_serial_type, .release_port = s3c24xx_serial_release_port, .request_port = s3c24xx_serial_request_port, .config_port = s3c24xx_serial_config_port, .verify_port = s3c24xx_serial_verify_port, #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) .poll_get_char = s3c24xx_serial_get_poll_char, .poll_put_char = s3c24xx_serial_put_poll_char, #endif };// 发 s3c24xx_serial_start_tx s3c24xx_serial_start_next_tx s3c24xx_serial_start_tx_pio s3c24xx_serial_start_tx_dma wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);// 收 s3c64xx_serial_handle_irq s3c24xx_serial_rx_chars s3c24xx_serial_rx_chars_dma uart_rx_drain_fifo rd_regb(port, S3C2410_URXH); s3c24xx_serial_rx_chars_pio rd_regb(port, S3C2410_URXH);// 注册 static struct uart_driver s3c24xx_uart_drv = {
// 1. .owner = THIS_MODULE, .driver_name = "s3c2410_serial", .nr = CONFIG_SERIAL_SAMSUNG_UARTS, .cons = S3C24XX_SERIAL_CONSOLE, .dev_name = S3C24XX_SERIAL_NAME, .major = S3C24XX_SERIAL_MAJOR, .minor = S3C24XX_SERIAL_MINOR, };s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {
// 2. [0] = {
.port = {
// struct uart_port .ops = &s3c24xx_serial_ops,};probe uart_register_driver(&s3c24xx_uart_drv); // 1. ourport = &s3c24xx_serial_ports[index]; uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); //2.

转载地址:http://baigi.baihongyu.com/

你可能感兴趣的文章
编写更好的CSS必备的40个工具
查看>>
设计出色响应式网站的十个技巧
查看>>
文60个有用CSS代码片段
查看>>
trick:CSS 3+checkbox实现JQuery的6个基本动画效果
查看>>
Trick:不用table,怎么等分DIV
查看>>
《机器学习实战》KNN算法实现
查看>>
《机器学习实战》ID3算法实现
查看>>
Linux终端小技巧
查看>>
《机器学习实战》朴素贝叶斯
查看>>
《机器学习实战》Logistic回归
查看>>
协方差和相关系数的概念和含义
查看>>
概率密度函数、概率分布函数、概率质量函数
查看>>
StanFord ML 笔记 第五部分
查看>>
大数定律和中心极限定律
查看>>
StanFord ML 笔记 第六部分&&第七部分
查看>>
StanFord ML 笔记 第八部分
查看>>
《图像处理实例》 之 Voronoi 图
查看>>
TessorFlow学习 之 序言
查看>>
《图像处理实例》 之 二值图像分割
查看>>
Matplotlib模块
查看>>