linux 8250驱动笔记
2011-01-06 12:33
246 查看
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->Character
Device->Serial drivers。在内核代码中,有段关于uart_addr_one_port的解释: attach a driver-defined port structure
This allows the driver to register its own uart_port structure with the core
driver. The main purpose is to allow the low level uart drivers to expand
uart_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文件里。
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->Character
Device->Serial drivers。在内核代码中,有段关于uart_addr_one_port的解释: attach a driver-defined port structure
This allows the driver to register its own uart_port structure with the core
driver. The main purpose is to allow the low level uart drivers to expand
uart_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驱动学习笔记之一——高精度定时器(1)
- linux学习笔记1:linux驱动设备概述
- 小松之LINUX 驱动学习笔记(一)
- linux字符设备驱动-同步互斥阻塞笔记
- [linux驱动]linux块设备学习笔记(四)——请求处理
- Linux2.6.32驱动笔记(2)字符设备驱动编程模型
- Linux设备与驱动学习笔记(概述)
- 我的内核学习笔记12:linux i2c-gpio驱动应用实例
- linux 驱动调试笔记二----背光
- linux驱动probe相关函数笔记
- Linux 学习笔记 (四)Ubuntu14.04 解决上网问题安装无线网卡驱动
- 学习Linux驱动的一点笔记
- 嵌入式Linux驱动笔记(十四)------详解clock时钟(CCF)框架及clk_get函数
- linux 驱动笔记(六)
- Linux驱动学习笔记(二)--kset内核对象集合
- Linux驱动学习笔记之一——高精度定时器(2)
- Linux驱动笔记(1)
- 【linux驱动笔记】linux模块机制浅析
- [linux驱动]linux块设备学习笔记(一)
- linux驱动 pci笔记