当前位置: 技术问答>linux和unix
求助,linux下写啦个字符驱动,写啦个测试代码,open失败,急急急,我实在不知道错哪啦,请大神帮忙给看下
来源: 互联网 发布时间:2017-05-16
本文导语: 下面是过程 globalvar.c代码: #include #include #include #include MODULE_LICENSE("GPL"); #define MAJOR_NUM 254 //主设备号 static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*); static ssize_t globalvar_write(struct file *, const ...
下面是过程
globalvar.c代码:
#include
#include
#include
#include
MODULE_LICENSE("GPL");
#define MAJOR_NUM 254 //主设备号
static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);
//初始化字符设备驱动的file_operations结构体
struct file_operations globalvar_fops =
{
read: globalvar_read, write: globalvar_write,
};
static int global_var = 0; //"globalvar"设备的全局变量
static int __init globalvar_init(void)
{
int ret;
//注册设备驱动
ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
if (ret)
{
printk("globalvar register failure");
}
else
{
printk("globalvar register success");
}
return ret;
}
static void __exit globalvar_exit(void)
{
int ret;
//注销设备驱动
ret = unregister_chrdev(MAJOR_NUM, "globalvar");
if (ret)
{
printk("globalvar unregister failure");
}
else
{
printk("globalvar unregister success");
}
}
static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
//将global_var从内核空间复制到用户空间
if (copy_to_user(buf, &global_var, sizeof(int)))
{
return - EFAULT;
}
return sizeof(int);
}
static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
//将用户空间的数据复制到内核空间的global_var
if (copy_from_user(&global_var, buf, sizeof(int)))
{
return - EFAULT;
}
return sizeof(int);
}
module_init(globalvar_init);
module_exit(globalvar_exit);
Makefile:
obj-m := globalvar.o
KERNEL := /lib/modules/`uname -r`/build
all:
make -C $(KERNEL) M=`pwd` modules
install:
make -C $(KERNEL) M=`pwd` modules_install
depmod -A
clean:
make -C $(KERNEL) M=`pwd` clean
rm -f *.*~ Module.* modules.*
下面是测试文件:
#include
#include
#include
#include
main()
{
int fd, num;
//打开"/dev/globalvar"
fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR);
if (fd != -1 )
{
//初次读globalvar
read(fd, &num, sizeof(int));
printf("The globalvar is %d/n", num);
//写globalvar
printf("Please input the num written to globalvar/n");
scanf("%d", &num);
write(fd, &num, sizeof(int));
//再次读globalvar
read(fd, &num, sizeof(int));
printf("The globalvar is %d/n", num);
//关闭"/dev/globalvar"
close(fd);
}
else
{
printf("Device open failure/n");
}
}
下面是编译的整个过程:
$:sudo make
$:sudo insmod globalvar.ko
$:sudo mknod /dev/globalvar c 50 0
$:gcc globalvartest.c
$:./a.out
后面就提示打开设备失败
请问到底问题出在哪啊?我实在不知道问题出哪啊?请大神给我看看,不胜感激。
globalvar.c代码:
#include
#include
#include
#include
MODULE_LICENSE("GPL");
#define MAJOR_NUM 254 //主设备号
static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);
//初始化字符设备驱动的file_operations结构体
struct file_operations globalvar_fops =
{
read: globalvar_read, write: globalvar_write,
};
static int global_var = 0; //"globalvar"设备的全局变量
static int __init globalvar_init(void)
{
int ret;
//注册设备驱动
ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
if (ret)
{
printk("globalvar register failure");
}
else
{
printk("globalvar register success");
}
return ret;
}
static void __exit globalvar_exit(void)
{
int ret;
//注销设备驱动
ret = unregister_chrdev(MAJOR_NUM, "globalvar");
if (ret)
{
printk("globalvar unregister failure");
}
else
{
printk("globalvar unregister success");
}
}
static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
//将global_var从内核空间复制到用户空间
if (copy_to_user(buf, &global_var, sizeof(int)))
{
return - EFAULT;
}
return sizeof(int);
}
static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
//将用户空间的数据复制到内核空间的global_var
if (copy_from_user(&global_var, buf, sizeof(int)))
{
return - EFAULT;
}
return sizeof(int);
}
module_init(globalvar_init);
module_exit(globalvar_exit);
Makefile:
obj-m := globalvar.o
KERNEL := /lib/modules/`uname -r`/build
all:
make -C $(KERNEL) M=`pwd` modules
install:
make -C $(KERNEL) M=`pwd` modules_install
depmod -A
clean:
make -C $(KERNEL) M=`pwd` clean
rm -f *.*~ Module.* modules.*
下面是测试文件:
#include
#include
#include
#include
main()
{
int fd, num;
//打开"/dev/globalvar"
fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR);
if (fd != -1 )
{
//初次读globalvar
read(fd, &num, sizeof(int));
printf("The globalvar is %d/n", num);
//写globalvar
printf("Please input the num written to globalvar/n");
scanf("%d", &num);
write(fd, &num, sizeof(int));
//再次读globalvar
read(fd, &num, sizeof(int));
printf("The globalvar is %d/n", num);
//关闭"/dev/globalvar"
close(fd);
}
else
{
printf("Device open failure/n");
}
}
下面是编译的整个过程:
$:sudo make
$:sudo insmod globalvar.ko
$:sudo mknod /dev/globalvar c 50 0
$:gcc globalvartest.c
$:./a.out
后面就提示打开设备失败
请问到底问题出在哪啊?我实在不知道问题出哪啊?请大神给我看看,不胜感激。
|
可以不用在程序里创建,mknod也可以, 你注册设备的时候注册上了吗,不然内核没有你mknod也没用啊,你先网上找个可以跑的,然后抄一遍,学习下,在自己写。
|
不懂,好像没有 xxx_open 接口啊
|
有没有open不是关键,关键是你的驱动初始化之后在/dev下根本没有globalvar设备,你只是注册了设备,并没有创建设备
还要使用class_create创建类,然后device_create创建设备。之后/dev下就有了设备。就可以open了。
还要使用class_create创建类,然后device_create创建设备。之后/dev下就有了设备。就可以open了。