您的位置:首页 > 运维架构 > Linux

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文件里。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: