您的位置:首页 > 运维架构 > Linux

linux2.6设备驱动程序框架

2016-10-13 13:37 169 查看
my.c驱动层代码

/*头文件定义*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <asm/io.h>
#include <asm/uaccess.h>

static  char cbuff[1024];

static int my_open(struct inode *inode, struct file *file)
{
//设备打开时的操作........
MOD_INC_USE_COUNT;
/*在以前2.4版本内核中,该宏负责记录增加或者减少设备模块的使用情况,防止应用程序使用驱动时,模块被意外卸载。
在2.6内核版本后,实现自动化管理模块*/
printk("my device open   sucess!/n");
return 0;
}

static int my_release(struct inode *inode, struct file *file)
{
//设备关闭时的操作........
MOD_DEC_USE_COUNT;//跟上面MOD_INC_USE_COUNT宏意义一样
return 0;
}
//read方法完成将数据从内核拷贝到应用程序空间
static int my_read(struct file *file,const char *buff,size_t count,loff_t *ppos )
{
//file文件指针,buff数据缓冲区,count数据长度,ppos 文件偏移量
//设备写入时的操作......
/*调用内核接口函数
unsigned  long copy_to_user(void *to, const void *from, unsigned long count);
*/
copy_to_user(buff,  cbuff , count);
printk("user  read data from driver\n");
return  count;
}
//write方法完成将数据从应用程序拷贝到内核空间
static int my_write(struct file *file,const char *buff,size_t count,loff_t *ppos )
{
//设备写入时的操作......
copy_from_user(cbuf,  buff , count);
cbuff[0]++;
printk("user write data to driver \n");
return  count;
}

/*ioctl方法主要用于对设备进行读写之外的其他控制,比如配置设备,进入或者退出某种操作模式,这些操作无法通过read/write文件操作来完成,*/
static long my_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd) {
case 1:
printk("----------------------1\n");
break;
case 2:
printk("------------------------2\n");
break;
}
return 0;
}

//函数结构体
struct file_operations my_fops = {
.open = my_open,
.release = my_release,
.read = my_read,
.write = my_write,
.unlocked_ioctl = my_ioctl,
//对文件操作结构体成员定义初始值
};

//模块初始化
int my_major =555 ;
int my_minor =0 ;
dev_t  dev =0 ;
struct class *myclass;
static int my_init(void)
{
/****************设备号初始化***********************************/
int result;
/*字符设备号 静态注册
dev = MKDEV(my_major, minor);//把主次设备号转换成dev_t类型数据
result = register_chrdev_region(dev , 1, "mydevice");
if (result < 0) {
printk("register_chrdev_region error\n");
return ret;
}*/
/***************************************************************/
/*字符设备号动态注册
result = alloc_chrdev_region(&dev,0,1,"mydevice");
//dev是输出量,得到主次设备号放入dev中,0表次设备号,连续分配1个,名字叫mydevice
if (result < 0) {
printk("alloc_chrdev_regionerror\n");
return result ;
}
my_major = MAJOR(dev);//得到主设备号
my_minor = MINOR(dev);//得到次设备号
*********************************************************/
/*字符设备静态注册
int  error;
//dev上面已经得到了该值,my_fops为上面的函数结构体
cdevt_init(&dev,  &my_fops);
cdev->owner = THIS_MODULE;
//cdev->ops = &my_fops;
error = cdev_add(&cdev, dev, 1);
*/
/*********************************************************
struct cdev *my_cdev = cdev_alloc();//动态分配内存空间
my_cdev->ops = &my_fops;
my_cdev->owner = THIS_MODULE;
intcdev_add(my_cdev,dev,1);
*/
/*********************************************************
/*自动创建设备节点
myclass = class_create(THIS_MODULE, "myclass");
//创建设备类
if(IS_ERR(myclass)){
printk();
return -1;
}
device_create(myclass, NULL, dev , NULL, "mydevice%d",1)
//创建设备节点为mydevice1,函数后面为格式化打印
*/

return 0;
}

static void my_exit(void)
{
//删除设备文件//注销设备
device_distroy(myclass,dev);
class_distroy(myclass);
cdev_del(&cdev);
unregister_chrdev_region(dev, 1);

printk("unregister_chrdev_regionexit\n");
printk("good-bye,kernel!!\n");
}


举例说明应用层调用到内核

1、设备节点和设备文件同时存在才能打开
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: