ioctrl原形 linux_Linux系统ioctl使用示例 ioctl实验

这篇文章详述了Linux系统中ioctl命令的功能和用途,特别强调了它在Android的显示和相机模块中的应用。文中通过一个gpio_test的实验,演示了如何使用ioctl进行设备驱动与用户空间的交互,包括设置GPIO高低电平、读写结构体和整型变量等操作,对于初学者来说非常有帮助。

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

本文是我在andoid实验的ioctl的功能,如双向传递参数。贴出来希望对学习ioctl的人很有帮助。

linux的ioctl功能是很强大的,Android显示模块还有camera模块都离不开ioctl让上层和内核交互。

这个实验对初学者很有帮助的。

board中添加platform_devce

static struct ioctl_test_platform_data ioctl_pdata = {

static struct ioctl_test_platform_data ioctl_pdata = {

.gpio=17,

};

static struct platform_device msm_device_ioctl = {

.name    = "gpio_test",

.id        = -1,

.dev    = {

.platform_data = &ioctl_pdata,

},

};

头文件:

ioctl_test.h

#ifndef IOCTL_TEST_H

#define IOCTL_TEST_H

/* platform data from board file */

struct ioctl_test_platform_data{

u16 gpio;

};

struct gpio_priv_t {

int gpio;

int state0;

int state1;

int state2;

int state3;

};

#define GPIO_TEST_IOC_MAGIC          0x92

#define GPIO_TEST_SET_HIGH          _IO(GPIO_TEST_IOC_MAGIC, 1)

#define GPIO_TEST_SET_LOW          _IO(GPIO_TEST_IOC_MAGIC, 2)

#define GPIO_TEST_WRITE_STRUCT          _IOW(GPIO_TEST_IOC_MAGIC, 3,struct gpio_priv_t *)

#define GPIO_TEST_WRITE_INT        _IOW(GPIO_TEST_IOC_MAGIC, 4,unsigned int *)

#define GPIO_TEST_READ_STRUCT          _IOR(GPIO_TEST_IOC_MAGIC, 5,struct gpio_priv_t *)

#define GPIO_TEST_READ_INT          _IOR(GPIO_TEST_IOC_MAGIC, 6,unsigned int *)

#endif

driver:

生成设备节点:/dev/gpio_test

ioctl_test.c

#define pr_fmt(fmt) "%s: " fmt, __func__

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static struct gpio_priv_t *gpio_priv;

static int gpio_test_open(struct inode *inode, struct file *filp)

{

if (gpio_priv == NULL)

return -ENODEV;

filp->private_data = gpio_priv;

return 0;

}

static int gpio_test_release(struct inode *inode, struct file *filp)

{

filp->private_data = NULL;

return 0;

}

static long

gpio_test_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

{

int err = 0;

void __user *argp = (void __user *)arg;

int value0;

int value1 ;

/* Verify user arguments. */

if (_IOC_TYPE(cmd) != GPIO_TEST_IOC_MAGIC)

return -ENOTTY;

switch (cmd) {

case GPIO_TEST_SET_HIGH:

printk("GPIO_TEST_SET_HIGH\n");

if (arg == 0) {

pr_err("user space arg not supplied\n");

err = -EFAULT;

break;

}

gpio_set_value(17,1);

break;

case GPIO_TEST_SET_LOW:

printk("GPIO_TEST_SET_LOW\n");

if (arg == 0) {

pr_err("user space arg not supplied\n");

err = -EFAULT;

break;

}

gpio_set_value(17,0);

break;

case GPIO_TEST_WRITE_STRUCT:

printk("GPIO_TEST_WRITE\n");

if (copy_from_user(gpio_priv, argp, sizeof(struct gpio_priv_t)))

return -EFAULT;

printk("gpio_priv->state0=%d\n",gpio_priv->state0);

printk("gpio_priv->state1=%d\n",gpio_priv->state1);

printk("gpio_priv->state2=%d\n",gpio_priv->state2);

break;

case GPIO_TEST_READ_STRUCT:

printk("GPIO_TEST_READ\n");

gpio_priv->state0=1;

gpio_priv->state1=2;

gpio_priv->state2=3;

if (copy_to_user(argp, gpio_priv, sizeof(struct gpio_priv_t)))

return -EFAULT;

break;

case GPIO_TEST_WRITE_INT:

printk("GPIO_TEST_WRITE_INT\n");

if(copy_from_user(&value0,argp,sizeof(int)))

return -EFAULT;

printk("value0 = %d\n",value0);

break;

case GPIO_TEST_READ_INT:

printk("GPIO_TEST_READ_INT\n");

value1=101;

if (copy_to_user(argp, &value1, sizeof(int)))

return -EFAULT;

break;

default:

pr_err("Invalid ioctl command.\n");

return -ENOTTY;

}

return err;

}

static const struct file_operations gpio_test_fops = {

.owner = THIS_MODULE,

.unlocked_ioctl = gpio_test_ioctl,

.open = gpio_test_open,

.release = gpio_test_release

};

static struct miscdevice gpio_test_dev = {

.minor = MISC_DYNAMIC_MINOR,

.name = "gpio_test",

.fops = &gpio_test_fops

};

static int gpio_test_probe(struct platform_device *pdev)

{

int ret = 0;

printk("gpio_test_probe 0\n");

/* Initialize */

gpio_priv = kzalloc(sizeof(struct gpio_priv_t), GFP_KERNEL);

if (gpio_priv == NULL) {

pr_alert("Not enough memory to initialize device\n");

return -ENOMEM;

}

ret = misc_register(&gpio_test_dev);

if (ret < 0)

goto err;

return 0;

err:

printk("gpio_test register failed\n");

kfree(gpio_priv);

gpio_priv = NULL;

return ret;

}

static int __devexit gpio_test_remove(struct platform_device *plat)

{

kfree(gpio_priv);

gpio_priv = NULL;

misc_deregister(&gpio_test_dev);

printk("gpio_test remove\n");

return 0;

}

static struct platform_driver gpio_test_driver = {

.probe = gpio_test_probe,

.remove = gpio_test_remove,

.driver = {

.name = "gpio_test",

.owner = THIS_MODULE,

},

};

static int __init gpio_test_init(void)

{

printk("gpio_test_init  \n");

return platform_driver_register(&gpio_test_driver);

}

static void __exit gpio_test_exit(void)

{

platform_driver_unregister(&gpio_test_driver);

}

module_init(gpio_test_init);

 module_exit(gpio_test_exit);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值