liunx sys属性节点的使用(一个简单小例子)

这个内核驱动代码:

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/kthread.h>
#include <linux/semaphore.h>

struct v_dev{
	struct platform_device *p_dev;	
	struct input_dev *input;
	int x;
	int y;
	struct task_struct *run_thread;
	struct semaphore sem;
};

struct v_dev *vmouse_dev = NULL;

static ssize_t write_pos(struct device *dev, struct device_attribute *attr,
             const char *buf, size_t count)
{
	int x,y;
	sscanf(buf,"%d%d",&x,&y);
	vmouse_dev->x = x;
	vmouse_dev->y =y;

	//post 信号量
	up(&vmouse_dev->sem);	

	return count;
}

static ssize_t show_pos(struct device *dev, struct device_attribute *attr,
            char *buf){
	return sprintf(buf,"(%d,%d)\n",vmouse_dev->x,vmouse_dev->y);
}

DEVICE_ATTR(pos,0644,show_pos,write_pos);

static int vmouse_thread(void *data)
{
	int x,y;
	struct v_dev *vmouse_dev = (struct v_dev*)data;
	struct semaphore *sema = &(vmouse_dev->sem);
	
	printk(KERN_INFO "vmouse thread running\n");
	
	while(1){
		//等待信号量
		while((down_interruptible(sema)) == -EINTR){} ;
			
		x = vmouse_dev->x;
		y = vmouse_dev->y;
		input_report_abs(vmouse_dev->input,ABS_X,x);
		input_report_abs(vmouse_dev->input,ABS_Y,y);
		input_sync(vmouse_dev->input);

		printk("vmouse thread report\n");
	}

	return 0;
}	

static int vmouse_probe(struct platform_device *pdev)
{
	int ret = -1;
	printk("%s debug \n",__func__);
	
	if(vmouse_dev->p_dev == pdev){
		printk("platform device is same\n");
	}
	
	vmouse_dev->input = input_allocate_device();
	if(!(vmouse_dev->input)){
		printk("%s request input deivce error\n",__func__);
		goto alloc_input;
	}
	
	vmouse_dev->input->name = "vmouse";
	set_bit(EV_ABS,vmouse_dev->input->evbit);
	input_set_abs_params(vmouse_dev->input, ABS_X, -1024, 1024, 0, 0);
	input_set_abs_params(vmouse_dev->input, ABS_Y, -1024, 1024, 0, 0);

	ret = input_register_device(vmouse_dev->input);
	if(ret < 0){
		printk("%s register input device error\n",__func__);
		goto input_register;
	}
	
	device_create_file(&pdev->dev,&dev_attr_pos);
//初始化信号量,在线程中要用到
	sema_init(&(vmouse_dev->sem),0);	

	vmouse_dev->run_thread = kthread_run(vmouse_thread,vmouse_dev,"vmouse_thread");
	
	return 0;

input_register:
	input_free_device(vmouse_dev->input);
alloc_input:
	kfree(vmouse_dev);
	return ret;
}

static struct platform_driver vmouse_driver = {
	.probe = vmouse_probe,
	.driver = {
		.owner = THIS_MODULE,
		.name = "v_mouse",
	},
};

static int __init vmouse_init(void)
{
	int ret =-1;
	
	printk("%s\n", __func__);
	
	vmouse_dev = kzalloc(sizeof(struct v_dev),GFP_KERNEL);
	if(vmouse_dev == NULL){
		printk("%s alloc memory  error\n",__func__);
		return -ENOMEM;
	}

	vmouse_dev->p_dev= platform_device_register_simple("v_mouse",-1,NULL,0);	
	if(!(vmouse_dev->p_dev)){
		printk("%s register platform device error\n",__func__);
		return ret;
	}
	
	ret = platform_driver_register(&vmouse_driver);
	if(ret < 0){
		printk("%s register driver error\n",__func__);
		return ret;
	}

	return 0;
}

static void __exit vmouse_exit(void)
{
	printk("%s\n", __func__);
	if(vmouse_dev->input != NULL){
		input_unregister_device(vmouse_dev->input);
	}
	printk("%s debug__1\n",__func__);
	
	if(vmouse_dev != NULL){
	platform_device_unregister(vmouse_dev->p_dev);
	}
	printk("%s debug__2\n",__func__);
	
	platform_driver_unregister(&vmouse_driver);
	printk("%s debug__3\n",__func__);
	
	kfree(vmouse_dev);
	printk("%s debug__4\n",__func__);
}

module_init(vmouse_init);
module_exit(vmouse_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("WEED<weed_hz@126.com>");
应用层测试代码:

#include <fcntl.h>
#include <linux/input.h>
#include <stdio.h>
//要看自己的节点了
#define EVENT_DEV "/dev/input/event5"

int main(void)
{
	struct input_event ev;
	int count,x,y;

	int fd = open(EVENT_DEV, O_RDWR);
	if(fd < 0){
		printf("open %s failed\n",EVENT_DEV);
		return 0;
	}

	while(1){
		count = read(fd, &ev,sizeof(struct input_event));
		if(EV_ABS == ev.type){
			if(ev.code == ABS_X){
				x = ev.value;
			}else if(ev.code == ABS_Y){
				y = ev.value;
			}
			printf("position: x=%d, y=%d\n",x,y);
		}else if(EV_SYN == ev.type){
				puts("sync!");
		}
	}

	return 0;	
}
先运行应用程序:./test_sys  
在另一个终端执行:echo "90 90" >/sys/devices/platform/v_mouse/pos

你就会看到你input设备上报的坐标,打印信息如下:

position: x=90, y=0
position: x=90, y=90
sync!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值