Controlling a device --- ioctl

本文介绍了在设备驱动中实现ioctl机制的方法,包括ioctl的基本概念、ioctl函数原型及其参数含义,并详细解释了通过宏定义来创建ioctl命令的具体方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sometimes apllications need the ability to control the device, in addition to exchanging data.

1. Two approaches exist for implementing device control:

--- Through special command sequences embeded in data that is written to the device.

--- By implementing the ioctl method in your driver.

2.  the ioctl approach involves implementing a separate method dedicated to handling device control.

ioctl is a bidirectional mechanism, allowing the setting and querying of device configuration, even in the same transaction.

3. the prototype for an ioctl function looks like this:

int mydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);

Parameters has following meaning:

--- inode : represents the device node.

--- file : represents the file discripter.

--- cmd : a numerical manifest which specifies command being issued.

--- arg: an argument associated with the specified command.

The kernel uses a struct inode structure to describe files. As opposed tofile descriptors, which are described by astruct file.
struct inode {
	struct hlist_node	i_hash;
	struct list_head	i_wb_list;	/* backing dev IO list */
	struct list_head	i_lru;		/* inode LRU list */
	struct list_head	i_sb_list;
	struct list_head	i_dentry;
	unsigned long		i_ino;
	atomic_t		i_count;
	unsigned int		i_nlink;
	uid_t			i_uid;
	gid_t			i_gid;
	dev_t			i_rdev;    // 设备号,包含了被打开设备的主次设备号。
	unsigned int		i_blkbits;
	u64			i_version;
	loff_t			i_size;
#ifdef __NEED_I_SIZE_ORDERED
	seqcount_t		i_size_seqcount;
#endif
	struct timespec		i_atime;
	struct timespec		i_mtime;
	struct timespec		i_ctime;
	blkcnt_t		i_blocks;
	unsigned short          i_bytes;
	umode_t			i_mode;
	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */
	struct mutex		i_mutex;
	struct rw_semaphore	i_alloc_sem;
	const struct inode_operations	*i_op;
	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
	struct super_block	*i_sb;
	struct file_lock	*i_flock;
	struct address_space	*i_mapping;
	struct address_space	i_data;
#ifdef CONFIG_QUOTA
	struct dquot		*i_dquot[MAXQUOTAS];
#endif
	struct list_head	i_devices;
	union {
		struct pipe_inode_info	*i_pipe;
		struct block_device	*i_bdev;
		struct cdev		*i_cdev;             //被注册进驱动的字符设备
	};

	__u32			i_generation;

#ifdef CONFIG_FSNOTIFY
	__u32			i_fsnotify_mask; /* all events this inode cares about */
	struct hlist_head	i_fsnotify_marks;
#endif

	unsigned long		i_state;
	unsigned long		dirtied_when;	/* jiffies of first dirtying */

	unsigned int		i_flags;

#ifdef CONFIG_IMA
	/* protected by i_lock */
	unsigned int		i_readcount; /* struct files open RO */
#endif
	atomic_t		i_writecount;
#ifdef CONFIG_SECURITY
	void			*i_security;
#endif
#ifdef CONFIG_FS_POSIX_ACL
	struct posix_acl	*i_acl;
	struct posix_acl	*i_default_acl;
#endif
	void			*i_private; /* fs or device private pointer */
};

4. implementing ioctl
the first step in implementing ioctl involves defining the command set that your driver will use.
the kernel provides 4 macros to assist in defining unique manifests for your ioctl command set.
These macros are:
 _IO --- no exchange of data. For example, enabling or disabling an LED display.
_IOW --- Commands which carry data to the device. For example, setting a brightness level to an integral value.
_IOR --- Commands which carry data from the device. For example, retrieve current brightness setting.
_IORW --- Commands which carry data in both directions in a single transaction, For example, set a new brightness level, while retriving the old setting.

To define your command set, a typical header file for a driver might something look like:


a corresponding ioctl function might resemble the following:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值