4,436
社区成员
发帖
与我相关
我的任务
分享
// 驱动程序文件
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#define SMPLE_MEMORY_SIZE (100)
struct SimpleDevice_st {
char* pdata;
int num;
struct cdev cdev;
};
MODULE_AUTHOR("Wanghaodong");
MODULE_DESCRIPTION("A char device driver to show how to write a char deivce driver");
MODULE_VERSION("0.1");
MODULE_LICENSE("Dual BSD/GPL");
//Declare function START
static int Simple_InitModule(void);
static void Simple_CleanUpModule(void);
static ssize_t Simple_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos);
static ssize_t Simple_Open(struct inode* inode, struct file* file);
static void SetupSimpleCdev(struct cdev* pcdev, int index);
//Define and Init variable
module_init(Simple_InitModule);
module_exit( Simple_CleanUpModule);
static struct file_operations pstCharDev_fops ={
.owner = THIS_MODULE,
.read = Simple_read,
//.write = Simple_Write,
.open = Simple_Open,
//.realse= Simple_Realse,
};
struct SimpleDevice_st* npstDevice = NULL;
static int schar_Major = 0;
static int schar_Minor = 0;
static int schar_MinorNum = 1;
static char memory_buffer[SMPLE_MEMORY_SIZE] = {
1, 2, 3, 4, 5, 6, 7, 8, 9,10,
};
static int Simple_InitModule(void)
{
dev_t dev;
int result,i;
if(schar_Major == 0){
result = alloc_chrdev_region(&dev,schar_Minor, schar_MinorNum, "SimpleCharDevice");
schar_Major = MAJOR(dev);
}
else{
dev = MKDEV(schar_Major, schar_Minor);
result = register_chrdev_region(dev, schar_MinorNum, "SimpleCharDevice");
}
if(result < 0){
printk(KERN_INFO "SimpleCharDevice: can't get major %d\n", schar_Major);
result = -1;
goto fail;
}
else{
printk(KERN_INFO "SimpleCharDevice: sign major ok %d\n", schar_Major);
}
npstDevice = (struct SimpleDevice_st* )kmalloc(schar_MinorNum * sizeof(struct SimpleDevice_st), GFP_KERNEL);
if(!npstDevice){
printk(KERN_INFO "SimpleCharDevice: alloc memory failure");
goto fail;
}
memset(npstDevice, 0, schar_MinorNum * sizeof(struct SimpleDevice_st));
for(i = 0; i < schar_MinorNum; i++){
(npstDevice + i)->pdata = (char*)kmalloc(SMPLE_MEMORY_SIZE, GFP_KERNEL);
(npstDevice + i)->num = SMPLE_MEMORY_SIZE;
SetupSimpleCdev(&((npstDevice + i)->cdev), i);
memcpy((npstDevice + i)->pdata, memory_buffer, sizeof(memory_buffer));
}
printk(KERN_INFO "SimpleCharDevice: init Ok");
return 0;
fail:
printk(KERN_INFO "SimpleCharDevice: init failure");
Simple_CleanUpModule();
return result;
}
static void Simple_CleanUpModule(void)
{
int i;
if(npstDevice){
for (i = 0; i < schar_MinorNum; i++) {
cdev_del(&npstDevice[i].cdev);
kfree(npstDevice[i].pdata);
}
kfree(npstDevice);
}
}
static void SetupSimpleCdev(struct cdev* pcdev, int index)
{
dev_t devno = 0;
int error = 0;
cdev_init(pcdev, &pstCharDev_fops);
pcdev->owner = THIS_MODULE;
pcdev->ops = &pstCharDev_fops;
error = cdev_add(pcdev,devno, 1);
if (error){
printk(KERN_INFO "SimpleCharDevice:Error %d adding scull%d", error, index);
}
printk(KERN_INFO "SimpleCharDevice: setup cdev ok");
}
static ssize_t Simple_Open(struct inode* inode, struct file* file)
{
struct SimpleDevice_st* pstChrDevice = NULL;
printk(KERN_INFO "SimpleCharDevice:Open init");
pstChrDevice = container_of(inode->i_cdev, struct SimpleDevice_st, cdev);
file->private_data = pstChrDevice;
printk(KERN_INFO "SimpleCharDevice:Open OK");
return 0;
}
ssize_t Simple_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
struct SimpleDevice_st* pstChrDevice = NULL;
ssize_t rvalue = 0;
pstChrDevice = (struct SimpleDevice_st*)filp->private_data;
if( *f_pos + count > pstChrDevice->num){
count = pstChrDevice->num - *f_pos;
}
if( copy_to_user(buf, pstChrDevice->pdata, count) ){
printk(KERN_NOTICE "SimpleDevice: read failure");
return rvalue = 0;
}
rvalue = count;
*f_pos += rvalue;
return rvalue;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <memory.h>
int main()
{
int fd = 0;
char buffer[32];
memset(buffer, 0, 32);
fd = open("/dev/SimpleCharDevice", O_RDONLY);
if ( fd < 0){
printf("open file failure %d\n", fd);
return -1;
}
read(fd, buffer, 32);
printf("%s\n",buffer);
close(fd);
}