Linux驱动开发笔记

使用alloc_chrdev_region函数创建的设备号不知道,可以使用如下代码调试打印出主设备号
printk(KERN_INFO “devno=%d,minor=%d\n”,MAJOR(devno),MINOR(devno));

使用“mknod /dev/设备名 设备类型 主设备号 0”的方式为设备创建节点,之后应用程序就可以使用open("/dev/设备名",O_RDWR)函数打开设备了。
下面是一个字符设备示例:

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>

struct cdev* pcdev;
char kernel_buf[100] = { 0 };
dev_t devno;//主设备号

#define BASEMINOR 0  //起始次设备号
#define DEVNUM 1 //设备个数
#define DEVNAME "cdev_driver1"

/*文件打开函数*/
int cdev_driver1_open(struct inode *inode, struct file *filp)
{
	printk(KERN_INFO "cdev_driver1_open\n");
	return 0;
}

/*文件释放函数*/
int cdev_driver1_release(struct inode *inode, struct file *filp)
{
	printk(KERN_INFO "cdev_driver1_release\n");
	return 0;
}

/*读函数*/
static ssize_t cdev_driver1_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
	/*读数据到用户空间*/
	char* pstr = "This is kernel data.";
	int len = strlen(pstr);
	if (copy_to_user(buf, pstr, len))
	{
		return -EFAULT;
	}
	return len;
}

/*写函数*/
static ssize_t cdev_driver1_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{

	/*从用户空间写入数据*/
	if (copy_from_user(kernel_buf, buf, size))
		return -EFAULT;

	printk(KERN_INFO "User write to kernel:%s\n", kernel_buf);

	return size;
}

/*文件操作结构体*/
static const struct file_operations fops =
{
	.owner = THIS_MODULE,
	.read = cdev_driver1_read,
	.write = cdev_driver1_write,
	.open = cdev_driver1_open,
	.release = cdev_driver1_release,
};

/*设备驱动模块加载函数*/
static int cdev_driver1_init(void)
{
	int result;

	//申请设备号
	devno = 0;
	result = alloc_chrdev_region(&devno, BASEMINOR, DEVNUM, DEVNAME);
	if (result < 0)
		return result;
	printk(KERN_INFO "devno=%d,minor=%d\n", MAJOR(devno), MINOR(devno));

	//
	pcdev = cdev_alloc();
	if (pcdev == NULL)
	{
		return -EFAULT;
	}

	printk(KERN_INFO "cdev_driver1_init\n");

	/*初始化cdev结构*/
	cdev_init(pcdev, &fops);

	/* 注册字符设备 */
	if (cdev_add(pcdev, devno, DEVNUM)<0)
	{
		printk(KERN_ERR "cdev_add call failed.\n");
		result = -ENOMEM;
	}

	return result;
}

/*模块卸载函数*/
static void cdev_driver1_exit(void)
{

	printk(KERN_INFO "cdev_driver1_exit\n");

	cdev_del(pcdev); /*注销设备*/
	unregister_chrdev_region(devno, DEVNUM); /*释放设备号*/
}

MODULE_AUTHOR("AUTHOR");
MODULE_LICENSE("GPL");

module_init(cdev_driver1_init);
module_exit(cdev_driver1_exit);

应用程序如下:

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

int main()
{
	int fd=open("/dev/cdev_driver1",O_RDWR);
	char buf[100]={0};
	read(fd,buf,100);
	printf("%s\n",buf);
	write(fd,"hello",5);
	close(fd);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值