Linux用户态传参,Linux字符设备-内核态数据与用户态数据互传

Linux字符设备-内核态数据与用户态数据互传

_IO,_IOR,_IOW和_IORW的含义

对于系统支持设备的ioctl号,你可以在/usr/include下面的头文件中找到,对于你自己的设备,如果需要使用ioctl接口,则需要定义自己 的ioctl号。以前的2.4中有个问题是,大家都随便定义自己的ioctl号,造成很大可能性的重复性。一个坏处是难以管理,另外一个是容易造成错误, 例如如果用户本来希望打开一个串口设备,结果通过open打开了网口,如果串口的某个ioctl号正好是网口的关闭操作,这样就会造成错误。在2.6里 面,你定义自己的ioctl号最好使用_IO,  _IOR,  _IOW和_IORW来定义,这些宏考虑了第三个参数的长度,设备的magic number,以及操作的方向等,避免了2.4中的问题

: _IO(type,nr)(给没有参数的命令),

_IOR(type, nre, datatype)(给从驱动中读数据的),

_IOW(type,nr,datatype)(给写数据),

_IOWR(type,nr,datatype)(给双向传送).

type 和 number 成员作为参数被传递,

并且 size 成员通过应用 sizeof 到 datatype 参数而得到

int ioctl( int fd, int request, .../* void *arg */ ) 详解

第三个参数总是一个指针,但指针的类型依赖于request 参数。我们可以把和网络相关的请求划分为6 类:

套接口操作

文件操作

接口操作

ARP 高速缓存操作

路由表操作

流系统

先写一个内核态数据与用户态数据互传的例子及APP

手动安装步骤:

Insmod my_char_dev.ko

不需要再安装设备节点

然后是测试app

./my_char_dev_app 1

fa8567c0f10a79a4a24ef4ee32c76889.png

#include

#include

#include

#include

#include   //下面这三个头文件是由于动态创建需要加的

#include

#include

#include "my_cdev.h"

#include

struct cdev cdev;

dev_t devno;//这里是动态分配设备号和动态创建设备结点需要用到的

struct class *cdev_class;

int param;

int my_cdev_open(struct inode *node,struct file *filp)

{

printk("my_cdev_open sucess!\n");

return 0;

}

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

{

int rc = -1;

switch(cmd)

{

case LED_ON:

rc = copy_from_user(&param, (int __user*)arg, 4);

if (0 != rc)

{

printk("copy_from_user failed.\n");

break;

}

printk("Param is %d.\n",param);

printk("CMD test: LED_ON is set!\n");

return 0;

case LED_OFF:

printk("CMD test: LED_OFF is set!\n");

param = 1000;

rc = copy_to_user((int __user*)arg,&param,4);

if (0 != rc)

{

printk("copy_to_user failed.\n");

}

param = 0;

return 0;

default :

return -EINVAL;

}

}

struct file_operations my_cdev_fops=

{

.open = my_cdev_open,

.unlocked_ioctl = my_cdev_ioctl,

};

static int my_cdev_init(void)

{

int ret;

/**动态分配设备号*/

ret = alloc_chrdev_region(&devno,0,1,"my_chardev");

if(ret)

{

printk("alloc_chrdev_region fail!\n");

unregister_chrdev_region(devno,1);

return ret;

}

else

{

printk("alloc_chrdev_region sucess!\n");

}

/**描述结构初始化*/

cdev_init(&cdev,&my_cdev_fops);

/**描述结构注册*/

ret = cdev_add(&cdev,devno,1);

if(ret)

{

printk("cdev add fail.\n");

unregister_chrdev_region(devno,1);

return ret;

}

else

{

printk("cdev add sucess!\n");

}

cdev_class = class_create(THIS_MODULE,"my_chardev");

if(IS_ERR(cdev_class))

{

printk("Create class fail!\n");

unregister_chrdev_region(devno,1);

return -1;

}

else

{

printk("Create class sucess!\n");

}

device_create(cdev_class,NULL,devno,0,"my_chardev");

return 0;

}

static void my_cdev_exit(void)

{

device_destroy(cdev_class,devno);

class_destroy(cdev_class);

cdev_del(&cdev);

unregister_chrdev_region(devno,1);

printk("my_cdev_exit sucess!\n");

}

module_init(my_cdev_init);

module_exit(my_cdev_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("YEFEI");

MODULE_DESCRIPTION("YEFEI Driver");

--------------------------------------------

#ifndef __MY_CDEV_H__

#define __MY_CDEV_H__

#define LED_MAGIC 'L'

#define LED_ON _IOW(LED_MAGIC,0,int)

#define LED_OFF _IOR(LED_MAGIC,1,int *)

#endif

--------------------------------------------

#include

#include

#include

#include

#include

#include "my_cdev.h"

int main(int argc,char *argv[])

{

int fd;

int cmd;

long ret = 0;

unsigned long param = 0;

if(argc < 2)

{

printf("Please enter secend param!\n");

return 0;

}

cmd = atoi(argv[1]);

fd = open("/dev/my_chardev",O_RDWR);

if(fd < 0)

{

printf("Open dev/my_chardev fail!\n");

close(fd);

return 0;

}

switch(cmd)

{

case 1:

param = 500;

ret = ioctl(fd,LED_ON,&param);

break;

case 2:

ret = ioctl(fd,LED_OFF,&param);

printf("ret is %d. read data is %d.\n",ret,param);

break;

default:

break;

}

close(fd);

return 0;

}

--------------------------------------------

1 obj-m :=my_char_dev.o2 KDIR := /home/win/dn377org/trunk/bcm7252/linux/

3 all:4    make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm5 clean:6    rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值