第二个驱动~~~
上次编译成功hello world,兴奋了好一会,呵呵。之前一直尝试都没成功。。。缘分未到,各种各样的原因会让尝试失败。
用hello.ko练习了一把insmod,lsmod,rmmod,modinfo等命令,这些是使用module的基本命令吧。
然后就开始着手开展下一步学习了,有个guide上面说,编译完hello world之后,可以动手做一个比较完整的字符设备驱动了,当然,我还是想找些例子再模仿下,所以有了这个hello world 的升级版。
废话少说,上modulev.c代码:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
//当用户空间代码调用了open()函数时会调用my_cdev_open()
//
int my_cdev_open(struct inode *inod,struct file *fp)
{
printk("Opening device...\nMajor device no: %d\n",MAJOR((inod->i_cdev->dev)));
return 0;
}
//当用户空间的代码调用了close()系统调用时会调用my_cdev_release()
int my_cdev_release(struct inode *inod,struct file *fp)
{
printk("Closing device...\n");
return 0;
}
struct cdev my_cdev;
struct file_operations my_fops;
//初始化时注册设备号,初始化字符设备
int my_cdev_init(void)
{
if(register_chrdev_region(MKDEV(33,0),1,"Vivo char-device") != 0)
{
printk("Can not make device.\n");
return -1;
}
my_fops.open = my_cdev_open;
my_fops.release = my_cdev_release;
cdev_init(&my_cdev,&my_fops);
cdev_add(&my_cdev,MKDEV(33,0),1);
return 0;
}
//卸载模块时删除设备并释放掉占用的设备号
void my_cdev_exit(void)
{
cdev_del(&my_cdev);
unregister_chrdev_region(MKDEV(33,0),1);
}
module_init(my_cdev_init);
module_exit(my_cdev_exit);
MODULE_LICENSE("GPL");
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
//当用户空间代码调用了open()函数时会调用my_cdev_open()
//
int my_cdev_open(struct inode *inod,struct file *fp)
{
printk("Opening device...\nMajor device no: %d\n",MAJOR((inod->i_cdev->dev)));
return 0;
}
//当用户空间的代码调用了close()系统调用时会调用my_cdev_release()
int my_cdev_release(struct inode *inod,struct file *fp)
{
printk("Closing device...\n");
return 0;
}
struct cdev my_cdev;
struct file_operations my_fops;
//初始化时注册设备号,初始化字符设备
int my_cdev_init(void)
{
if(register_chrdev_region(MKDEV(33,0),1,"Vivo char-device") != 0)
{
printk("Can not make device.\n");
return -1;
}
my_fops.open = my_cdev_open;
my_fops.release = my_cdev_release;
cdev_init(&my_cdev,&my_fops);
cdev_add(&my_cdev,MKDEV(33,0),1);
return 0;
}
//卸载模块时删除设备并释放掉占用的设备号
void my_cdev_exit(void)
{
cdev_del(&my_cdev);
unregister_chrdev_region(MKDEV(33,0),1);
}
module_init(my_cdev_init);
module_exit(my_cdev_exit);
MODULE_LICENSE("GPL");
还有Makefile,补充下,这个是我改的,原来那个不知道为啥用不了,先不管。
# Makefile2.6
PWD := $(shell pwd)
# KVER ?= $(shell uname -r)
KVER ?= 2.6.19
KDIR := /home/jessen/global/atmel/linux-2.6.19
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
PWD := $(shell pwd)
# KVER ?= $(shell uname -r)
KVER ?= 2.6.19
KDIR := /home/jessen/global/atmel/linux-2.6.19
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
KDIR是我内核放置的地方,捣鼓hello.ko的时候知道,内核必须要make过的,这样才能用来编译模块。
so。。。参照编译hello.ko的过程检查完,一切ok,编译通过!
把modulev拷贝到我的板子上~~~~
先用下面的命令创建一个字符设备文件:
mknod my_cdev c 33 0
然后:
insmod modulev.ko
这里看不到效果啦,呵呵,有一个测试程序open.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int
main (int argc, char **argv)
{
int fd;
int ret;
fd = open (argv[1], O_RDWR);
if (fd < 0)
{
printf ("Open file failed.\n");
return -1;
}
close (fd);
return 0;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int
main (int argc, char **argv)
{
int fd;
int ret;
fd = open (argv[1], O_RDWR);
if (fd < 0)
{
printf ("Open file failed.\n");
return -1;
}
close (fd);
return 0;
}
编译后下载到板子上,看看效果哈:
[root@VL-EMS-II /home]# ./open my_cdev
Opening device...
Major device no: 33
Closing device...
[root@VL-EMS-II /home]#
Opening device...
Major device no: 33
Closing device...
[root@VL-EMS-II /home]#
Everything is ok~~~接下来是仿写,修改,呵呵
——————无论在哪里做什么,只要坚持服务、创新、创造价值,其他的东西自然都会来的。