linux 8250驱动笔记
来源:互联网 发布:直播平台app 源码 编辑:程序博客网 时间:2024/05/21 00:47
struct uart_driver {
struct module *owner;
const char *driver_name;
const char *dev_name;
int major;
int minor;
int nr;
struct console *cons;
/*
* these are private; the low level driver should not
* touch these; they should be initialised to NULL
*/
/*
*下面两个变量的赋值在调用uart_register_driver中分配的
*/
struct uart_state *state;
struct tty_driver *tty_driver;
};
其中需要注意的是:在uart_register_driver中分配的的uart_state的个数。是由
uart_driver中的nr的内部变量决定的。在8250.c文件serial8250_init
serial8250_reg.nr = UART_NR;
ret = uart_register_driver(&serial8250_reg);
以8250串口驱动为例,大致描述一下串口的流程:
ü 对serial8250_reg.nr= UART_NR;
ü 向serialcore中注册serial8250_reg驱动程序。Uart_register_driver
ü 初始化uart_port结构体。serial8250_isa_init_ports();
ü 向注册的串口驱动添加uart_port。uart_add_one_port。一个串口驱动可以支持多个uart_port,在读写数据的时候如何区分是对应哪个uart_port。是通过uart_state。每个uart_port位于uart_state中的不同的位置。具体一个uart_port位于uart_state的位置,是通过uart_port->line来决定。例如在serial8250_isa_init函数中有对uart_port->line的赋值。从0到nr_uarts – 1。Nr_uarts的大小等于CONFIG_SERIAL_8250_RUNTIME_UARTS。这个是我们在配置内核的时候配置的。默认的情况下是4,该值在配置的路径:Device Drivers->CharacterDevice->Serial drivers。在内核代码中,有段关于uart_addr_one_port的解释: attach a driver-defined port structureThis allows the driver to register its own uart_port structure with the coredriver. The main purpose is to allow the low level uart drivers to expanduart_port, rather than having yet more levels of structures.
ü 在uart_add_one_port中会调用uart_configure_port。这个函数会回调port->ops->config_port进行串口配置。在8250中 port->ops= serial8250_pops这个赋值是在serial8250_isa_init中完成。Config_port= serial8250_config_port。
ü serial8250_config_port中首先完成注册io资源,然后将调用autoconfig配置串口。也是在这个函数里面检测串口是否存在的,具体的检测方法是,保存ier寄存器的是,分别两次写入全0和全1,在读出判断写入和读出的值是否相等。在uart_port的flags没有标记UPF_SKIP_TEST的情况下,进行MCR的回写模式的检测。
下面见uart驱动常见数据结构表示如下:
关于8250串口驱动的一点自己的理解:
大致流程就像上面所描述的。我们在serial8250_register_ports函数中会去使用old_serial_port来初始化serial8250_ports这个结构体。在x86平台在arch/x86/include/asm/serial.h定义SERIAL_PORT_DFNS来初始化old_serial_port这个结构体。但是在非x86平台并没有定义SERIAL_PORT_DFNS这样的宏。例如powerpc平台就没有。那么serial8250_ports这个结构体的初始化,就放在了平台驱动注册platform_driver_register(&serial8250_isa_driver);的过程中对于平台设备匹配成功的话,会调用probe(serial8250_probe)再次初始化serial8250_ports。这个工作在serial8250_register_port中完成。这个函数的主要的任务是从serial8250_ports中找出与平台设备中类型匹配或者未初始化的serial8250_ports的值,先调用uart_remove_one_port(&serial8250_reg,&uart->port);删除uart_port。在重新初始化,在调用uart_add_one_port注册串口。在powerpc 平台串口的设备的注册在arch/powerpc/kernel/leagacy_serial.c文件里。
- linux 8250驱动笔记
- Linux驱动笔记:SPI驱动
- linux驱动阅读笔记
- linux i2c驱动笔记
- Linux 驱动学习笔记
- linux驱动模型---笔记
- linux i2c驱动笔记
- Linux IIC驱动笔记
- linux i2c驱动笔记
- linux驱动移植笔记
- LINUX SPI驱动笔记
- linux IIC驱动笔记
- arm linux驱动笔记
- 笔记~~linux驱动
- linux IIC驱动笔记
- Linux IIC驱动笔记
- linux驱动 pci笔记
- linux驱动学习笔记
- abap assigning a structure by component
- JQuery 属性操作方法
- 选摘
- Delphi GDI+ 实现简单画图
- abap casting with field symbol type
- linux 8250驱动笔记
- URI、URL、URN
- 人生三件事/三句话/三乐/三不
- DOS命令行删除N天以前的文件
- 索引
- CronExpression详解
- 自定义异常类简介
- 子查询
- 反思自己