linux切换终端 驱动程序,linux终端设备驱动分析

一、字符设备驱动概述

1、两个结构体

struct cdev{

...

struct  file operations  *ops;

}

struct file_opreations{  ...}

2、分配/注销设备号函数register_chrdev_region()/  unregister_chrdev_region (  )

注册/注销设备   cdev_add ()  /     cdev_del   (   )

3、简单的驱动架构

a、头文件、宏定义等

b、字符设备结构体的定义

操作结构体的定义及成员的填写

c、初始化并添加cdev结构体

d、加载与卸载函数

二、终端设备

属于字符设备

1、终端设备驱动结构Linux内核中tty的层次结构包含:tty核心、tty线路规程和tty驱动。

2、结构分析

通用层(drivers/char/...)

在tty_dirver.h中

struct tty_driver{ ... struct cdev *cdev ...}  实现对cdev的封装

struct tty_opreations{ ... }  特有的操作,相对于file_operations结构体

在tty_io.c中

1、定义structcdevtty_cdev{ ... }  以及console结构体

源码:static struct cdev tty_cdev, console_cdev;

2、定义 struct  file_operations tty_ops{ ... } 以及 console_ops 结构体

源码:

static const struct file_operations tty_fops = {

.llseek = no_llseek,

.read= tty_read,

.write = tty_write,

.poll= tty_poll,

.unlocked_ioctl= tty_ioctl,

.compat_ioctl = tty_compat_ioctl,

.open= tty_open,

.release = tty_release,

.fasync = tty_fasync,

};

static const struct file_operations console_fops = {

.llseek = no_llseek,

.read= tty_read,

.write = redirected_tty_write,

.poll= tty_poll,

.unlocked_ioctl= tty_ioctl,

.compat_ioctl = tty_compat_ioctl,

.open= tty_open,

.release = tty_release,

.fasync = tty_fasync,

};

3、注册tty设备,console

源码:

static int __init tty_init(void)

{

cdev_init(&tty_cdev, &tty_fops);

if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||

register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)

panic("Couldn't register /dev/tty driver\n");

device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,

"tty");

cdev_init(&console_cdev, &console_fops);

if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||

register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)

panic("Couldn't register /dev/console driver\n");

device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,

"console");

#ifdef CONFIG_VT

vty_init(&console_fops);

#endif

return 0;

}

module_init(tty_init);

4.定义接口函数

tty驱动,tty设备的注册和注销等接口函数

特有层(drivers/setial/...)

1、在serial_core.h中

(1)定义了struct uart_driver { ...struct tty_driver...  }   实现了对  tty_driver  的封装

定义 了 struct  uart_ops  {  ....   }   特有的操作

(2)定义了uart_port结构体,用于描述UART端口

2、在serial_core.c中

(1)定义了struct tty_operations  uart_ops{  } 结构体,及其成员

实现了tty_operations  与 uart_ops 的连接,用  uart_ops 的 成员填充了 tty_operations 的成员

(2)定义关于uart的 接口函数   uart接口函数包含  tty驱动的接口函数

3、开发板串口驱动位于samsung,c(定义了一系列接口函数)

(1)定义了static struct uart_ops s3c24xx_serial_ops 并填充了uart_ops

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,

.enable_ms = s3c24xx_serial_enable_ms,

.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,

};

(2)定义static struct uart_driver s3c24xx_uart_drv

static struct uart_driver s3c24xx_uart_drv = {

.owner = THIS_MODULE,

.dev_name = "s3c2410_serial",

.nr= CONFIG_SERIAL_SAMSUNG_UARTS,

.cons= S3C24XX_SERIAL_CONSOLE,

.driver_name = S3C24XX_SERIAL_NAME,

.major = S3C24XX_SERIAL_MAJOR,

.minor = S3C24XX_SERIAL_MINOR,

};

(3)定义static struct s3c24xx_uart_port s3c24xx_serial_ports结构体

(4)

int s3c24xx_serial_init(struct platform_driver *drv,

struct s3c24xx_uart_info *info)

{

dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);

#ifdef CONFIG_PM

drv->suspend = s3c24xx_serial_suspend;

drv->resume = s3c24xx_serial_resume;

#endif

return platform_driver_register(drv);

}

EXPORT_SYMBOL_GPL(s3c24xx_serial_init);

(5)注册s3c24xx_uart_drv

static int __init s3c24xx_serial_modinit(void)

{

int ret;

ret = uart_register_driver(&s3c24xx_uart_drv);

if (ret < 0) {

printk(KERN_ERR "failed to register UART driver\n");

return -1;

}

return 0;

}

static void __exit s3c24xx_serial_modexit(void)

{

uart_unregister_driver(&s3c24xx_uart_drv);

}

module_init(s3c24xx_serial_modinit);

module_exit(s3c24xx_serial_modexit);

4、 s3c2440. c  文件主要完成获取资源,定义,注册

(1)定义platform设备

static struct platform_driver s3c2440_serial_driver = {

.probe = s3c2440_serial_probe,

.remove = __devexit_p(s3c24xx_serial_remove),

.driver = {

.name= "s3c2440-uart",

.owner = THIS_MODULE,

},

};

(2)注册设备模块

static int __init s3c2440_serial_init(void) { return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf); } static void __exit s3c2440_serial_exit(void) { platform_driver_unregister(&s3c2440_serial_driver); } module_init(s3c2440_serial_init); module_exit(s3c2440_serial_exit);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值