微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 驱动学习1

驱动学习1

时间:12-01 来源:互联网 点击:

KERNELRELEASE = $(shell cat include/config/kernel.release 2>

:= memdev.o。这样就实现了内核的编译。

具体的应用程序代码我都是按着别人的代码修改调试的。

下面是我的源码:

第一个代码是头文件:

#ifndef _MEMDEV_H_H_

#define _MEMDEV_H_H_

#ifndef MEMDEV_MAJOR

#define MEMDEV_MAJOR 555

#endif

#ifndef MEMDEV_NR_DEVS

#define MEMDEV_NR_DEVS 2

#endif

#ifndef MEMDEV_SIZE

#define MEMDEV_SIZE 2048

#endif

struct mem_dev

{

char *data;

unsigned long size;

};

#endif

第二个是C文件:

#include

#include

#include

//#include

#include

#include

#include

/*该头文件主要实现内存的控制,包括kmalloc等函数*/

#include

#include

#include

#include

/*错误的不同,需要具体的类型*/

#include

/*自己定义的头文件*/

#include"memdev.h"

static mem_major = MEMDEV_MAJOR;

module_param(mem_major,int,S_IRUGO);

module_param(mem_major,int,S_IRUGO);

struct mem_dev *mem_devp;

struct cdev cdev;

/*函数的声明*/

static int memdev_init(void);

static void memdev_exit(void);

int mem_open(struct inode *inode,struct file *filp);

int mem_release(struct inode *inode, struct file *flip);

static ssize_t mem_read(struct file *flip,char __user *buf, size_t size,loff_t *ppos);

static ssize_t mem_write(struct file *filp,const char __user *buf,size_t size,loff_t *ppos);

static loff_t mem_llseek(struct file *filp,loff_t offset, int whence);

/*添加该模块的基本文件操作支持*/

static const struct file_operations mem_fops =

{

.owner = THIS_MODULE,

.llseek = mem_llseek,

.read = mem_read,

.write = mem_write,

.open = mem_open,

.release = mem_release,

};

/*初始化函数*/

static int memdev_init(void)

{

int result;

int i;

/*创建一个设备号*/

dev_t devno = MKDEV(mem_major,0);

/*注册一个设备号*/

/*如果定义了主设备号采用静态申请的方式*/

if(mem_major)

result = register_chrdev_region(devno,2,"mem_dev");

else/*动态申请设备号*/

{

result = alloc_chrdev_region(&devno,0,2,"mem_dev");

mem_major = MAJOR(result);

}

/*错误处理*/

if(result < 0)

return result;

/*创建一个设备*/

/*初始化cdev,并将相关的文件操作添加进来*/

cdev_init(&cdev,&mem_fops);

cdev.owner = THIS_MODULE;

cdev.ops = &mem_fops;

/*注册字符设备*/

cdev_add(&cdev,MKDEV(mem_major,0),MEMDEV_NR_DEVS);

/*分配两个内存空间,此处是在物理内存上实现分配,实质是创建两个设备*/

mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev),GFP_KERNEL);

if(!mem_devp)/*出错的相应操作*/

{

result = -ENOMEM;

/*错误处理,采用典型的goto语句*/

goto fail_malloc;

}

/*清除空间*/

memset(mem_devp,0,sizeof(struct mem_dev));

for(i = 0; i < MEMDEV_NR_DEVS; ++i)

{

mem_devp[i].size = MEMDEV_SIZE;

mem_devp[i].data = kmalloc(MEMDEV_SIZE,GFP_KERNEL);

/*问题,没有进行错误的控制*/

memset(mem_devp[i].data,0,MEMDEV_SIZE);

}

return 0;

fail_malloc:

unregister_chrdev_region(devno,1);

return result;

}

/*模块清除函数*/

static void memdev_exit(void)

{

cdev_del(&cdev);/*注销字符设备*/

/*释放两个物理内存*/

kfree(mem_devp[0].data);

kfree(mem_devp[1].data);

kfree(mem_devp);/*释放设备结构体内存*/

unregister_chrdev_region(MKDEV(mem_major,0),2);

}

/*定义相关的操作函数*/

/*mem_open*/

int mem_open(struct inode *inode,struct file *filp)

{

struct mem_dev *dev;

/*判断设备文件的次设备号*/

int num = MINOR(inode->i_rdev);

if(num >= MEMDEV_NR_DEVS)

return -ENODEV;

dev = &mem_devp[num];

/*将数据指向两个内存空间*/

filp->private_data = dev;

return 0;

}

/*release函数的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top