当前位置: 首页 > news >正文

重庆免费网站建站模板微网站趋势

重庆免费网站建站模板,微网站趋势,贵州省城乡住房和建设厅网站,网站中文商标域名注册一般而言字符设备驱动不可能只会调用读写操作(read/write),因为字符设备还需要进行其他参数的配置(如摄像头驱动 设置摄像头的画面参数、获取摄像头的能力......),像这样的操作都不会使用读写函数来实现&am…

一般而言字符设备驱动不可能只会调用读写操作(read/write),因为字符设备还需要进行其他参数的配置(如摄像头驱动 设置摄像头的画面参数、获取摄像头的能力......),像这样的操作都不会使用读写函数来实现,一般内核都会交给ioctl函数来实现,像ioctl函数的特点就是通过发送不同命令码,然后驱动返回不同的数据。

一、应用程序中的ioctl函数

头文件

#include <sys/ioctl.h>

函数原型

int ioctl(int fd, unsigned long request,...);
参数说明:int fd-----文件描述符 open返回值unsigned long request----依赖于设备的请求代码(对设备的请求方式、命令)... ----->第三个参数可以有,也可以省略,要根据参数二来确定比如:摄像头----videodev2.h--->usr/include/linux/videodev2.h4#define VIDIOC_G_FMT 	_IOWR('V', 4, struct v412_format)---->从底层得到v412 format数据给应用层#define VIDIOC_S_FMT	_IOWR('V', 5, struct v4l2_format)---->ioctl(fd,VIDIOC_G_FMT,要第三个参数)

常用的两种:

int ioctl(int fd, unsigned long request); //应用程序下发命令给驱动

int ioctl(int fd, unsigned long request , unsigned long args);  //应用程序下发命令和参数给驱动

二、驱动程序中的ioctl函数

long (*unlocked ioctl)(struct file *,unsigned int, unsigned long);

ioctl控制命令的形式
  ioctl命令:IO,IOR,IOW,IOWR,但是,应用程序和驱动程序也要约定同一个形式,而且由驱动程序来确定。

在linux中,提供了一种 ioctl 命令的统一格式,将 32 位 int 型数据划分为四个位段,如下所示:

#define _IOC(dir,type,nr,size) \(((dir)  << _IOC_DIRSHIFT) | \((type) << _IOC_TYPESHIFT) | \((nr)   << _IOC_NRSHIFT) | \((size) << _IOC_SIZESHIFT))
名称

比特位

含义
dir31-30

命令访问模式(数据传输方向),占据 2 bit

00 - 命令不带参数
01 - 命令需要把数据写入驱动,写方向
10 - 命令需要从驱动中获取数据,读方向
11 - 命令既要写入数据又要获取数据,读写方向

type15-8设备类型,占据 8 bit,可以为任意 char 型字符,例如灯-----> 'L', beep ----> 'B'等等,其主要作用是使 ioctl 命令有唯一的设备标识
nr7-0命令编号/序数,占据 8 bit,可以为任意 unsigned char 型数据,取值范围 0~255,如果定义了多个 ioctl 命令,通常从 0 开始编号递增
size29-16涉及到 ioctl 函数第三个参数 arg ,占据14bit,指定了 arg 的数据类型及长度
#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOR_BAD(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW_BAD(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR_BAD(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))/* used to decode ioctl numbers.. */
#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)/* ...and for the drivers/sound files... */#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)

1)定义一个命令,该命令不需要参数

  #define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0)

2)定义一个命令,该命令说明应用程序向驱动程序读参数

#define _IOR(type,nr,size)    _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))

3)定义一个命令,该命令说明应用程序向驱动程序写参数

  #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))

4)定义一个命令,参数的传输是双向的

 #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE, (type),(nr),(_IOC_TYPECHECK(size)))

5)获得传输方向位段的值

#define _IOC_DIR(nr)  (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)

6)获得类型的值

#define _IOC_TYPE(nr)  (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)

7)获得编号的值

#define _IOC_NR(nr)  (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)

8)获得大小的值

#define _IOC_SIZE(nr)  (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)    

应用程序如果打算下发命令给驱动程序,需要设计对应的命令码,并且驱动程序也必须有对应的命令码(相当于应用程序和驱动程序必须有一致的命令码)。

三、示例

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/device.h>static struct class *class;struct option{unsigned int datab;unsigned int parity;unsigned int stopb;
};#define VS_MAGIC 's'#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOR(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOR(VS_MAGIC, 3, struct option)#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"struct vser_dev{unsigned int baud;struct option opt;struct cdev cdev;
};DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;static int vser_open(struct inode *inode, struct file *filp)
{return 0;
}static int vser_release(struct inode *inode, struct file *flip)
{return 0;
}static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{int ret;unsigned int copied = 0;ret = kfifo_to_user(&vsfifo, buf, count, &copied);return ret == 0 ? copied : ret;
}static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{int ret;unsigned int copied = 0;ret = kfifo_from_user(&vsfifo, buf, count, &copied);return ret == 0? copied : ret;
}static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{if (_IOC_TYPE(cmd) != VS_MAGIC)return -ENOTTY;switch(cmd) {case VS_SET_BAUD:vsdev.baud = arg;break;case VS_GET_BAUD:arg = vsdev.baud;break;case VS_SET_FFMT:if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))return -EFAULT; break;case VS_GET_FFMT:if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))return -EFAULT;break;default:break;};return 0;
}static struct file_operations vser_ops = {.owner = THIS_MODULE,.open = vser_open,.release = vser_release,.read = vser_read,.write = vser_write,.unlocked_ioctl = vser_ioctl,
};static int __init vser_init(void)
{int ret;dev_t dev;dev = MKDEV(VSER_MAJOR, VSER_MINOR);ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);if (ret)goto reg_err;cdev_init(&vsdev.cdev, &vser_ops);vsdev.cdev.owner = THIS_MODULE;vsdev.baud = 115200;vsdev.opt.datab = 8;vsdev.opt.parity = 0;vsdev.opt.stopb = 1;ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);if (ret)goto add_err;/* 自动创建设备节点 */class = class_create(THIS_MODULE, "my_ioctl");  /* /sys/class/my_ioctl */device_create(class, NULL, dev, NULL, "vser0"); /* /dev/vser0 */return 0;add_err:unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:return ret;
}static void __exit vser_exit(void)
{dev_t dev;dev = MKDEV(VSER_MAJOR, VSER_MINOR);cdev_del(&vsdev.cdev);device_destroy(class, dev);class_destroy(class);unregister_chrdev_region(dev, VSER_DEV_CNT);
}module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");

应用层:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>struct option{unsigned int datab;unsigned int parity;unsigned int stopb;
};#define VS_MAGIC 's'#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOR(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOR(VS_MAGIC, 3, struct option)int main(int argc, char *argv[])
{int fd;int ret;unsigned int baud;struct option opt = {8,1,1};fd = open("/dev/vser0", O_RDWR);if (fd == -1)goto fail;baud = 9600;ret = ioctl(fd, VS_SET_BAUD, baud);if (ret == -1)goto fail;ret = ioctl(fd, VS_GET_BAUD, baud);if (ret == -1)goto fail;ret = ioctl(fd, VS_SET_FFMT, &opt);if (ret == -1)goto fail;ret = ioctl(fd, VS_GET_FFMT, &opt);if (ret == -1)goto fail;printf("baud rate:%d\n", baud);printf("frame format: %d%d%d\n", opt.datab, opt.parity, opt.stopb);close(fd);exit(EXIT_SUCCESS);fail:perror("ioctl test");exit(EXIT_FAILURE);
}

觉得有帮助的话,打赏一下呗。。

           

需要商务合作(定制程序)的欢迎私信!! 

http://www.dtcms.com/a/594000.html

相关文章:

  • DDR5引领变革:内存条行业的技术迭代与市场重构
  • 一小时速通Pytorch之Tensor张量(一)
  • 怎么做网站教程 用的工具提供网站推广公司电话
  • 网站服务内容怎么写wordpress 响应时间
  • 主成分分析(Principal Component Analysis,PCA)的个人理解
  • sqlite数据库迁移至mysql
  • PostgreSQL 高并发优化:从 “连接数满到崩” 到 “支撑 10 万 QPS” 的实战技巧
  • 怎么免费建自己的网站网络营销课程培训机构
  • 团队开发者git仓库工作手册
  • 欧美风网站建设seo品牌优化整站优化
  • 2.8 模型压缩与优化技术
  • 数字孪生工厂浪潮来袭,众趣科技以实景智能筑牢智造基石
  • [設計模式]二十三種設計模式
  • 有视频接口怎么做网站哪个行业最需要做网站
  • 解锁AI工作流的终极密码:Semantic Kernel Process框架深度技术解析
  • 从0到1:Makefile自动化编译实战全解析
  • 广州网站推广教程中国建设银行网站会员用户名
  • 怎么做分享软件的网站php网站开发框架搭建
  • 网站跟网页的区别jsp做的网页是网站吗
  • 根据docker服务保存日志脚本,时间可选版本
  • 九、神经网络的构建方式详解
  • 第五章 神经网络
  • 网站建设相关的工作鸿顺里网站建设公司
  • 自己做网站卖手机网站建设电话
  • TypeScript 元组
  • LLM - 大模型融合 LangChain 与 OpenRouter 的框架
  • 南宁建企业网站公司办公室装修设计怎么收费
  • 天气形势时间层的选择策略
  • 一站式网站建设多少钱网站怎么会k
  • JAVA实现国密算法SM2/SM3/SM4签名与验签(基于 BouncyCastle)