一、基本理论
二、基本数据结构和实例
三 、总结
一、基本理论
二、基本数据结构和实例、
前面hello驱动的升级,定义了一个基于内存int数据的设备,有很多不全的地方,只是简单的一个测试demo。关于其它驱动基本框架都类似,具体的就是操作的寄存器复杂和时序的不同。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
struct freg_device{
struct cdev dev;
int val;
};
static int major=0;
static struct class *hello_class=NULL;
static struct freg_device hello_device;
static int hello_open(struct inode *inode,struct file *filp){
printk(KERN_ALERT "hello open function.\n");
return 0;
}
static int hello_close(struct inode *inode,struct file *filp){
printk(KERN_ALERT "hello close function.\n");
return 0;
}
static ssize_t hello_write(struct file *file,const char __user *buf,size_t count,loff_t *ppos){
int val=0;
int err=0;
printk(KERN_ALERT "hello write function.\n");
if(copy_from_user(&val,buf,count)){
err= -EFAULT;
goto out;
}
hello_device.val=val;
printk(KERN_ALERT "write %d to kernel.\n",val);
err=sizeof(val);
out:
return err;
}
static struct file_operations hello_fops={
.owner=THIS_MODULE,
.open=hello_open,
.release=hello_close,
.write=hello_write,
};
static int __init hello_init(void){
int err=0;
dev_t devid;
printk(KERN_ALERT "hello kernel1.\n");
#if 0
major=register_chrdev(0,"hello",&hello_fops);
devid=MKDEV(major,0);
#else
if(major){
devid=MKDEV(major,0);
err=register_chrdev_region(devid,1,"hello");
if(err<0){
printk("Fail to register char dev region\n");
goto fail;
}
}
else{
err=alloc_chrdev_region(&devid,0,1,"hello");
if(err<0){
printk("Fail to alloc char dev region\n");
goto fail;
}
major=MAJOR(devid);
}
cdev_init(&(hello_device.dev),&hello_fops);
hello_device.dev.owner=THIS_MODULE;
cdev_add(&(hello_device.dev),devid,1);
#endif
hello_class= class_create(THIS_MODULE,"hello_drv");
device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello");
fail:
return err;
}
static void __exit hello_exit(void){
dev_t devid=MKDEV(major,0);
printk(KERN_ALERT"exit kernel.\n");
device_destroy(hello_class,MKDEV(major,0));
class_destroy(hello_class);
cdev_del(&(hello_device.dev));
unregister_chrdev_region(devid,1);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
测试程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
int fd=0;
int val=4;
fd=open("/dev/hello",O_RDWR);
if(fd<0){
printf("fail to open.\n");
}
write(fd,&val,sizeof(val));
close(fd);
return 0;
}
测试结果
三 、总结
.......