使用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;
}