01-最简单的驱动

目标:实现一个简单的字符设备驱动,实现读写字符串功能。

驱动程序:

#include <linux/module.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>

#define MIN(a,b) (a<b?a:b)
#define DEVICE_NAME "hello_alon"
static int major = 0;
static struct class *hello_class;
static char kernel_buf[1024];

static int hello_drv_open(struct inode *node, struct file *file)
{
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	return 0;
}

static ssize_t hello_drv_read(struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	int err;
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	err = copy_to_user(buf,kernel_buf,MIN(1024,size));
	return MIN(1024,size);
}

static ssize_t hello_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
	int err;
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	err = copy_from_user(kernel_buf,buf,MIN(1024,size));
	return MIN(1024,size);
}

static int hello_drv_close(struct inode *node, struct file *file)
{
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	return 0;
}

static struct file_operations hello_drv = {
	.owner   = THIS_MODULE,
	.open    = hello_drv_open,
	.read    = hello_drv_read,
	.write   = hello_drv_write,
	.release = hello_drv_close,
};

static int __init hello_init(void)
{
	int err;
	
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	
	major = register_chrdev(0,"hello_chr",&hello_drv); 

	hello_class = class_create(THIS_MODULE,"hello_class");
	err = PTR_ERR(hello_class);

	if(IS_ERR(hello_class))
	{
		printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
		unregister_chrdev(major,DEVICE_NAME);
		return -1;
	}

	device_create(hello_class,NULL,MKDEV(major,0),NULL,DEVICE_NAME);

	
	return 0;
}

static void  __exit hello_exit(void)
{	
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);

	device_destroy(hello_class,MKDEV(major,0));
	class_destroy(hello_class);
	unregister_chrdev(major,DEVICE_NAME);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

测试程序:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

/*
 * ./hello_drv_test -w abc
 * ./hello_drv_test -r
 */
#define DEVICE_NAME "/dev/hello_alon"

int main(int argc, char **argv)
{
	int fd;
	char buf[1024];
	int len;

	if(argc < 2)
	{
		printf("Usage: %s -w <string>\n",argv[0]);
		printf("	%s -r\n",argv[0]);
		return -1;
	}

	fd = open(DEVICE_NAME,O_RDWR);
	if(fd == -1)
	{
		printf("cannot open %s \n",DEVICE_NAME);
		return -1;
	}

	if(0 == strcmp(argv[1],"-w") && 3 == argc)
	{
		len = strlen(argv[2]) + 1;
		len = len<1024?len:1024;
		write(fd,argv[2],len);
	}else{
		len = read(fd,buf,1024);
		buf[1023] = '\0';
		printf("APP read: %s\n",buf);
	}

	close(fd);
	return 0;
}

Makefile:

KERN_DIR = /home/book/100ask_imx6ull-sdk/Linux-4.9.88

all:
	make -C $(KERN_DIR) M=`pwd` modules 
	$(CROSS_COMPILE)gcc -o hello_drv_test hello_drv_test.c 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order
	rm -f hello_drv_test

obj-m += hello_drv.o

测试结果:

[root@100ask:/mnt/drv_code_of_Alon/01_hello_drv]# ./hello_drv_test -w abc123
[root@100ask:/mnt/drv_code_of_Alon/01_hello_drv]# ./hello_drv_test -r       
APP read: abc123

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值