內核入門:較為基礎的Linux系統設備驅動
更新時間: 2007-12-12 15:34:45來源: 粵嵌教育瀏覽量:645
驅動程序為:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static unsigned int major = 0;
static unsigned int minor = 0;
static unsigned int devno;
static char *filename = "mydevice";
static struct cdev *mycdev = NULL;
static int mycdevflg = 0;
static int devnoflg = 0;
static int adddevflg = 0;
MODULE_LICENSE("Dual BSD/GPL");
static int myopen(struct inode *inodep, struct file *flipl)
{
printk("my open is run\n");
return 0;
}
static ssize_t myread(struct file *flip, char __user *buf, size_t size, loff_t offset)
{
printk("myread is ok!\n");
static int i = 0;
///copy_to_user(buf,from,size);
*buf = i++;
return 0;
}
static int myrelease(struct inode *myindoe, struct file *flip)
{
printk("myrelease is run.\n");
return 0;
}
static struct file_operations myfops =
{
.owner = THIS_MODULE,
.open = myopen,
.read = myread,
.release= myrelease,
};
/* 初始化設備的過程主要是三步:1,生成設備號;2初始化設備;3,添加到內核。
*/
static int __init myinit(void)
{
int result = -1;
if(major)
{
devno = MKDEV(major,minor); //生成設備號
result = register_chrdev_region(devno,1,filename);//注冊設備號devno,1為設備的個數
devnoflg = 1;
}
else
{
result = alloc_chrdev_region(&devno,minor,1,filename);//生成設備號兵注冊,
mior為次設備號,這里注意的是指針devno?
major = MAJOR(devno);
devnoflg = 1;
}
if(result < 0)
{
printk("can't register the major num!\n");
devnoflg = 0;
return -1;
}
//mycdev = kmalloc(sizeof(struct cdev),GFP_KERNEL);
//如果采用cdev_init(struct cdev*,struct file *)方式的話,這個才需要。
mycdev = cdev_alloc();//申請cdev內存兵初始化設備cdev,不能在這之前申請內存,
否則要釋放兩次!
if(NULL == mycdev)
{
printk("can't request the memory!\n");
}
mycdevflg = 1;
//memset(mycdev,0,sizeof(mycdev));
mycdev->owner = THIS_MODULE;//如果采用cdev_init(struct cdev*,struct file *)方式的話,
這兩項可以去掉
mycdev->ops = &myfops;//如果采用cdev_init(struct cdev*,struct file *)方式的話,
這兩項可以去掉
result = cdev_add(mycdev,devno,1);//設備和設備號聯系起來,
即通常說的添加設備到內核
if(result < 0)
{
printk("can't add cdev.2\n");
adddevflg = 0;
}
else
{
adddevflg = 1;
}
return 0;
}
/* 以和設備注冊的次序"卸載",注意有的時候,當出錯的時候,要注意是否用到這些操作,
所以要加上判斷,否則比如對空指針free會導致系統崩潰!
*/
static void myexit(void)
{
printk("myexit begin.\n");
if(adddevflg)
{
cdev_del(mycdev);
adddevflg = 0;
}
if(mycdev)
{
kfree(mycdev);
mycdev = NULL;
}
if(devnoflg)
{
unregister_chrdev_region(devno,1);
devno = 0;
devnoflg = 0;
}
printk("exit over.\n");
}
module_init(myinit);
module_exit(myexit);
應用程序為:
#include
#include
#include
#include
#include
int main()
{
int fd;
int i=0;
fd = open("/dev/mydevice", O_RDONLY);
if (fd < 0)
{
printf("error1\n");
return -1;
}
int j = 0;
while(j++<10000)
{
if (read(fd, &i, sizeof(int)) < 0)
{
printf("read error2\n");
return -1;
}
printf("i = %d\n",i);
}
close("/dev/mydevice");
return 0;
}
一定要注意register_chrdev_region(),alloc_chrdev_region(),cdev_init(),cdev_alloc(),cdev_add()這些函數的參數類型,不要把指針當成非指針,把int類型當作指針(或者&)來使用!