Linux内核TTY驱动架构资料下载.pdf
《Linux内核TTY驱动架构资料下载.pdf》由会员分享,可在线阅读,更多相关《Linux内核TTY驱动架构资料下载.pdf(14页珍藏版)》请在冰豆网上搜索。
![Linux内核TTY驱动架构资料下载.pdf](https://file1.bdocx.com/fileroot1/2022-10/7/a724247f-bd83-4d74-be55-e0811fffb382/a724247f-bd83-4d74-be55-e0811fffb3821.gif)
b.structuart_mxr_portmxc_ports8mxc_ports数组是自定义的uart_mxc_port数组,数组大小为8,在mx51中只用到前3个。
mxc_ports中包含的最重要的结构体是structuart_port,它们之间的关系详见数据结构关系图。
staticuart_mxc_port*mxc_portsMXC_UART_NR;
/MXC_UART_NR=82.数据结构关系图数据结构关系图uart_driverconstchar*driver_name;
constchar*dev_name;
structconsole*cons;
intnr;
*state;
*tty_driver;
uart_state.port;
.xmit;
*uart_port;
tty_driverintmagic;
constchar*driver_name;
constchar*name;
structcdevcdev;
structtty_struct*ttys;
structktermios*termios;
conststructtty_operations*ops;
intnum;
structlist_headtty_drivers;
uart_mxc_port.port;
structclk*clk;
uart_portunsignedintirq;
unsignedintline;
unsignedinttype;
unsignedintuartclk;
structuart_icounticount;
conststructuart_ops*ops;
structdevice*dev;
structuart_state*state;
void*private_data;
tty_portstructtty_struct*tty;
Conststructtty_port_operations*ops;
unsignedchar*xmit_buf;
tty_structintmagic;
*driver;
intindex;
structtty_ldisc*ldisc;
structtty_bufheadbuf;
*port;
void*driver_data;
char*write_bufcirc_bufchar*buf;
inthead;
inttail;
tty_bufheadstructtty_buffer*head;
structtty_buffer*tail;
structtty_buffer*free;
intmemory_used;
tty_bufferstructtty_buffer*next;
char*char_buf_ptr;
unsignedchar*flag_buf_ptr;
intused;
intsize;
intcommit;
intread;
unsignedlongdata0;
tty_ldiscStructtty_ldisc_ops*ops;
四四、uart注册及注册及初始化初始化1.uart注册注册uart驱动程序入口:
module_init(mxcuart_init);
staticint_initmxcuart_init(void)/uart_register_driver(uart_driver*)-tty_register_driver(tty_driver*)cdev_add()/最终注册了nr(nr=8)个字符设备驱动ret=uart_register_driver(&
mxc_reg);
/mxc_reg定义见数据结构1ret=platform_driver_register(&
mxcuart_driver);
/mxcuart_driver见下面定义在mxcuart_init()函数中,我们重点分析uart_register_driver(structuart_driver*),对于platform_driver_register(),详见平台设备注册文档分析。
下面重点分析uart_register_driver(structuart_driver*)在uart_register_driver()中,构建了tty_driver,并将uart_driver中的相关成员赋值给tty_driver,最终调用到tty_register_driver(structtty_driver*)。
uart_register_driver(structuart_driver*drv)drv-state=kzalloc(sizeof(structuart_state)*drv-nr,GFP_KERNEL);
structtty_driver*normal=alloc_tty_driver(drv-nr);
/将uart_driver中的成员变量赋值给tty_driver,例如:
主次/设备号,驱动名、设备名、通信相关init_termios设置等tty_set_operations(normal,&
uart_ops);
tty_port_init(port);
/初始化上面申请的(drv-nr)个uart_state中的tty_porttty_register_driver(normal);
在tty_register_driver(structtty_driver*)中,最终注册了8个字符设备驱动,其操作函数为tty_fops。
staticconststructfile_operationstty_fops=.read=tty_read,.write=tty_write,.open=tty_open,;
下面分析不同层次间几个operations函数的关系,如图:
tty_register_driver(structtty_driver*driver)dev=MKDEV(driver-major,driver-minor_start);
register_chrdev_region(dev,driver-num,driver-name);
cdev_init(&
driver-cdev,&
tty_fops);
cdev_add(&
driver-cdev,dev,driver-num);
/注册了8个字符驱动list_add(&
driver-tty_drivers,&
tty_drivers);
/将tty_drivers加入一个全局的tty_drivers链表tty_register_device(driver,i,NULL);
/i=07,循环注册8个device在上面前3层中,每一层都给自己的下一层提供了操作函数的接口,tty_core是一个字符设备驱动,实现了字符设备提供的structfile_operations,同时给自己的下层提供了structtty_operations操作接口。
serial_core使用了tty_core提供的structtty_operations操作接口,同时给自己的下层提供了structuart_ops操作接口。
在后面的打开、数据读写过程中我们将会看到具体的层层调用关系。
到这里uart注册告一段落。
2.uart初始化初始化uart平台设备在/arch/arm/mach-mx5/serial.c中arch_initcall(mxc_init_uart)注册,注册了3个平台设备。
uart平台驱动和uart平台设备通过名字“mxcintuart”匹配,匹配成功调用uart平台驱动中的mxcuart_probe()。
在mxcuart_probe中主要是将平台资源给mxc_ports中的uart_port,然后调用uart_add_one_port(),它根据uart_port中的line拿到uart_driver中对应的tty_coreserial_coreuart驱动structfile_operations.open.read.writestructtty_operations.open.read.writestructuart_ops.open.read.write字符驱动uart_state,然后配置好这个port并调用tty_register_device()注册该port。
匹配成功后将调用到mxcuart_probe()。
staticstructplatform_drivermxcuart_driver=.driver=.name=mxcintuart,.probe=mxcuart_probe,.remove=mxcuart_remove,.suspend=mxcuart_suspend,.resume=mxcuart_resume,;
staticstructplatform_devicemxc_uart_device1=.name=mxcintuart,.id=0,.num_resources=ARRAY_SIZE(mxc_uart_resources1),.resource=mxc_uart_resources1,.dev=.platform_data=&
mxc_ports0,;
staticstructresourcemxc_uart_resources1=.start=UART1_BASE_ADDR,.end=UART1_BASE_ADDR+0x0B5,.flags=IORESOURCE_MEM,.start=MXC_INT_UART1,.flags=IORESOURCE_IRQ,;
static