linux tty 驱动之ioctls 函数

这篇具有很好参考价值的文章主要介绍了linux tty 驱动之ioctls 函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在 struct tty_driver 中的 ioctl 函数被 tty 核心调用当 ioctl(2) 被在设备节点上
调用. 如果这个 tty 驱动不知道如何处理传递给它的 ioctl 值, 它应当返回 -
ENOIOCTLCMD 来试图让 tty 核心实现一个通用的调用版本.
2.6 内核定义了大约 70 个不同的 tty ioctls, 可被用来发送给一个 tty 驱动. 大部分
的 tty 驱动不处理它们全部, 但是只有一个小的更普通的子集. 这是一个更通用的 tty
ioctls 列表, 它们的含义, 以及如何实现它们:
TIOCSERGETLSR
获得这个 tty 设备的线路状态寄存器( LSR )的值.
TIOCGSERIAL

获得串口线信息. 调用者可以潜在地从 tty 设备获得许多串口线路信息, 在这个
调用中一次全部. 一些程序( 例如 setserial 和 dip) 调用这个函数来确保波特
率被正确设置, 以及来获得通常的关于驱动控制的设备类型信息. 调用者传递一个
指向一个大的 serial_struct 结构的指针, 这个结构应当由 tty 驱动填充正确的
值. 这是一个如何实现这个的例子:
static int tiny_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct tiny_serial *tiny = tty->driver_data;
if (cmd == TIOCGSERIAL)
{
struct serial_struct tmp;
if (!arg)
return -EFAULT;
memset(&tmp, 0, sizeof(tmp));
tmp.type = tiny->serial.type;
tmp.line = tiny->serial.line;
tmp.port = tiny->serial.port;
tmp.irq = tiny->serial.irq;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
tmp.xmit_fifo_size = tiny->serial.xmit_fifo_size;
tmp.baud_base = tiny->serial.baud_base;
tmp.close_delay = 5*HZ;
tmp.closing_wait = 30*HZ;
tmp.custom_divisor = tiny->serial.custom_divisor;
tmp.hub6 = tiny->serial.hub6;
tmp.io_type = tiny->serial.io_type;
if (copy_to_user((void __user *)arg, &tmp, sizeof(tmp)))
return -EFAULT;
return 0;
}
return -ENOIOCTLCMD;
}
TIOCSSERIAL
设置串口线路信息. 这是 IOCGSERIAL 的反面, 并且允许用户一次全部设置 tty
设备的串口线状态. 一个指向 struct serial_struct 的指针被传递给这个调用,
填满这个 tty 设备应当被设置的数据. 如果这个 tty 驱动没有实现这个调用, 大
部分程序仍然正确工作.
TIOCMIWAIT
等待 MSR 改变. 用户在非寻常的情况下请求这个 ioctl, 它想在内核中睡眠直到
这个 tty 设备的 MSR 寄存器发生某些事情. arg 参数包含用户在等待的事件类型.
这通常用来等待直到一个状态线变化, 指示有更多的数据发送给设备.

当实现这个 ioctl 时要小心, 并且不要使用 interruptible_sleep_on 调用, 因
为它是不安全的(有很多不好的竞争条件涉及它). 相反, 一个 wait_queue 应当用
来避免这个问题. 这是一个如何实现这个 ioctl 的例子:
static int tiny_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct tiny_serial *tiny = tty->driver_data;
if (cmd == TIOCMIWAIT)
{
DECLARE_WAITQUEUE(wait, current);
struct async_icount cnow;
struct async_icount cprev;
cprev = tiny->icount;
while (1) {
add_wait_queue(&tiny->wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
schedule();
/* see if a signal woke us up */
remove_wait_queue(&tiny->wait, &wait);
if (signal_pending(current))
return -ERESTARTSYS;
cnow = tiny->icount;
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
return -EIO; /* no change => error */
if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
return 0;
}
cprev = cnow;
}
}
return -ENOIOCTLCMD;
}
在 tty 驱动的代码中能知道 MSR 寄存器改变的某些地方, 下面的代码行必须调用
以便这个代码能正常工作:
wake_up_interruptible(&tp->wait);
TIOCGICOUNT
获得中断计数. 当用户要知道已经产生多少串口线中断时调用. 如果驱动有一个中
断处理, 它应当定义一个内部计数器结构来跟踪这些统计和递增适当的计数器, 每
次这个函数被内核运行时.

这个 ioctl 调用传递内核一个指向结构 serial_icounter_struct 的指针, 它应当被
tty 驱动填充. 这个调用常常和之前的 IOCMIWAIT ioctl 调用结合使用. 如果 tty 驱动
跟踪所有的这些中断在驱动操作时, 实现这个调用的代码会非常简单:
static int tiny_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct tiny_serial *tiny = tty->driver_data;
if (cmd == TIOCGICOUNT)
{
struct async_icount cnow = tiny->icount;
struct serial_icounter_struct icount;
icount.cts = cnow.cts;
icount.dsr = cnow.dsr;
icount.rng = cnow.rng;
icount.dcd = cnow.dcd;
icount.rx = cnow.rx;
icount.tx = cnow.tx;
icount.frame = cnow.frame;
icount.overrun = cnow.overrun;
icount.parity = cnow.parity;
icount.brk = cnow.brk;
icount.buf_overrun = cnow.buf_overrun;
if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
return -EFAULT;
return 0;
}
return -ENOIOCTLCMD;
}文章来源地址https://www.toymoban.com/news/detail-803074.html

到了这里,关于linux tty 驱动之ioctls 函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux字符设备驱动(设备文件,用户空间与内核空间进行数据交互,ioctl接口)

    在Linux系统中“一切皆文件”,上一篇讲述了cdev结构体就描述了一个字符设备驱动,主要包括设备号和操作函数集合。但是要怎么操作这个驱动呢?例如,使用open()该打开谁,read()该从哪读取数据等等。所以就需要创建一个设备文件来代表设备驱动。 应用程序要操纵外部硬件

    2024年02月12日
    浏览(38)
  • linux驱动开发:Linux 内核的一些函数

    1 、 MKDEV ( ma, mi ) 构造设备号,将主设备号和次设备号转换为设备号类型(dev_t)。 MKDEV 宏将主设备号( ma )左移 20 位,然后与次设备号( mi )相与,得到设备号。 dev_t 结构 主设备号 12 位

    2024年02月17日
    浏览(38)
  • 【Linux驱动开发】012 gpio子系统API函数

    设置好设备树以后, 在驱动程序中就可以使用 gpio 子系统提供的 API 函数来操作指定的 GPIO, gpio 子系统向驱动开发人员屏蔽了具体的读写寄存器过程。这就是驱动分层与分离的好处,大家各司其职,做好自己的本职工作即可。 gpio 子系统提供的常用的 API 函数有下面几个:

    2023年04月18日
    浏览(40)
  • tty驱动初步了解学习

    本人是linux驱动初学者,最近在初步学习uart驱动,在这记录下来自己的理解 linux3.10 soc:君正x1000e 四位大佬写的很好 https://blog.csdn.net/cosmoslhf/article/details/16945009 https://blog.csdn.net/lizuobin2/article/details/51801183 https://blog.csdn.net/Luckiers/article/details/123577836 https://blog.csdn.net/mike8825/arti

    2023年04月08日
    浏览(32)
  • 【Linux驱动开发】013 与gpio相关的OF函数 一、前言

    在上节,我们提供了驱动中gpio子系统相关的API函数,主要用来申请释放gpio、设置gpio输入输出、获取设置gpio的值。 我们进行上述设置的前提是:在驱动程序中需要读取 gpio 属性内容。为此,Linux 内核提供了几个与 GPIO 有关的 OF 函数。 用于统计设备树某个属性里面定义了几个

    2024年02月14日
    浏览(47)
  • ifconfig工具与驱动交互解析(ioctl)

    Linux ifconfig命令用于显示或设置网络设备。ifconfig可设置网络设备的状态,或是显示目前的设置。 同netstat一样,ifconfig源码也位于net-tools中。 源码位于net-tools工具包中,这是linux网络的基本工具包,此外还有arp,hostname,route等命令。 此文章不考虑ifconfig的具体功能介绍,而是侧

    2024年02月07日
    浏览(103)
  • Ioctl()方式实现与驱动交互简洁框架

    ioctl是linux中一种除read和write之外的数据传递机制 驱动层IOCTL: 以上函数参数的含义如下 。 inode和fp用来确定被操作的设备。 request就是用户程序下发的命令。 args就是用户程序在必要时传递的参数。 在2.6.36以后ioctl函数已经不存在了,用unlocked_ioctl和compat_ioctl两个函数代替。

    2024年02月09日
    浏览(54)
  • 【genius_platform软件平台开发】第九十七讲:linux设备驱动中信号(signal函数)的异步通知机制

    意思是: 一旦设备就绪,则主动通知应用程序 ,这样应用程序根本就不需要查询设备状态,这一点非常 类似于硬件上“中断”的概念 ,比较准确的称谓是“ 信号驱动的异步I/O ”。信号是在软件层次上对 中断机制的一种模拟 ,在原理上,一个进程收到一个信号与处理器收到一

    2024年02月08日
    浏览(61)
  • Linux用户与内核空间交互—ioctl

    目录 简介 一、交互方法笔记与总结 二、ioctl 三、实战 1、头文件 2、应用程序 3、内核程序 4、 程序输出 用户空间与内核的交互方式,使用copy_from_user(), copy_to_user(). 除了这两种交互方式,内核还提供了其他高级的方式,对于写驱动来说很重要。有proc、sysfs、debugfs、netlink、

    2024年02月10日
    浏览(198)
  • Linux shell编程学习笔记25:tty

    在 1830 年代和 1840 年代,开发了称为电传打字机(teletypewriters)的机器,这些机器可以将发件人在键盘上输入的消息“沿着线路”发送在接收端并打印在纸上。 电传打字机的名称由teletypewriters, 缩短为teletypes,并最终缩短为 TTY。 电传打字机:teletypewriters →  teletypes → t

    2024年02月05日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包