linux字符设备驱动通用框架

linux字符设备驱动框架

myxx_driver.c

#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h> 
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/uaccess.h>

static int myxx_open (struct inode * inode, struct file * file)
{
	printk(" device open\n");
	return 0;
}

static int myxx_release (struct inode * inode, struct file * file){
	printk(" device release\n");
	return 0;
}

ssize_t myxx_read (struct inode * inode, struct file * file){
	printk(" device read\n");
	return 0;
}

ssize_t myxx_write (struct inode * inode, struct file * file){
	printk(" device write\n");
	return 0;
}

static struct file_operations myxx_fop = {
    .owner      = THIS_MODULE,
	.open        = myxx_open,
	.release    = myxx_release,
	.read        = myxx_read,
	.write        = myxx_write,
};

static struct cdev *myxx_cdev;
static struct class *myxx_class;

static dev_t device;

/* 驱动模块的入口函数 */
static int myxx_init(void){

	if (device){
		/* 静态申请设备号 */
		register_chrdev_region(device,1,"myxx_dev");
	}else{
		/* 动态申请设备号 */
		alloc_chrdev_region(&device,0, 1,"myxx_dev");
	}
	
	/* 申请空间 */
	my_chr_cdev = cdev_alloc();
	/* 注册字符设备驱动 */
	cdev_init(myxx_cdev,&myxx_fop);
	cdev_add(myxx_cdev, device, 1);
	
	/* 创建设备节点 */
	chr_class = class_create(THIS_MODULE, "myxx_dev");
	class_device_create(myxx_class, NULL, device, NULL,"myxx_dev");
	return 0;
}



/* 驱动模块的退出函数 */
static void myxx_exit(void){
	/* 删除设备节点 */
	class_device_destroy(myxx_class, device);
	class_destroy(myxx_class);
	/* 注销字符设备驱动 */
	cdev_del(myxx_cdev);
	/* 释放空间 */
	cdev_put(myxx_cdev);
	/* 释放设备号和相应的设备名 */
	unregister_chrdev_region(device, 1);
}

/* 这个宏将 myxx_init 函数修饰为模块的入口函数 */
module_init(myxx_init);
/* 这个宏将 myxx_exit 函数修饰为模块的退出函数 */
module_exit(myxx_exit);
/* 遵循GPL协议 */
MODULE_LICENSE("GPL");

makefile

#内核源码树路径
KERN_DIR = ~/work/kernel
#目标文件
obj-m += myxx_driver.o

all:
	make -C $(KERN_DIR) M=`pwd` modules
clean:
	make -C $(KERN_DIR) M=`pwd` modules clean

test_myxx.c

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

int buf;
int main(int argc, char** argv)
{
	int fd;
	if((fd = open("/dev/myxx_dev",O_RDWR))<0){
		printf("open device failed\n");
		return -1;
	}
	/* 将数据写到驱动程序,再读出来验证 */
	int i = 10;
	write(fd,&i,sizeof(i));
	read(fd,&buf,sizeof(buf));
	printf("read the data is:%d\n",buf);
	sleep(1);

	close(fd);
	return 0;
}

编译驱动
make ARCH=arm CROSSFILE=arm-linux-gcc
生成 myxx.ko

编译应用程序
arm-linux-gcc main.c -o test_myxx

将ko文件和应用程序复制到嵌入式机器上
加载驱动
insmod myxx.ko
执行应用程序
./test_myxx

其他指令
查看内核中已插入的模块
lsmod
卸载模块
rmmod xxx
查看模块的描述信息
modinfo xxx.ko

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值