mycdev.c
/*字符驱动模块程序 2017年04月21日 星期五*/
#include <linux/init.h> //模块所需的大量符号和函数定义
#include <linux/module.h> //指定初始化和清除函数
#include <linux/types.h> //dev_t 是用来在内核里代表设备号的类型.
#include <linux/fs.h> //"文件系统"头文件是编写设备驱动需要的头文件. 许多重要的函数和数据结构在此定义
#include <linux/sched.h>
#include <linux/cdev.h> //cdev 结构管理的函数, 它代表内核中的字符设备
#include <linux/mm.h>
#include <linux/kernel.h> //printk()一个传统宏定义, 可用来获取一个结构指针, 从它里面包含的某个其他结构的指
#include <asm/io.h>
//#include <asm.current.h> //
#include <asm/uaccess.h> //在内核和用户空间中移动数据的函数copy_to_user和copy_from_user
MODULE_LICENSE("leo BSD/GPL"); //许可证
#define MYCDEV_MAJOB 231 /*给定的主设备号*/
#define MYCDEV_SIZE 2048
//open 方法提供给驱动来做任何的初始化来准备后续的操作.
static int mycdev_open(struct inode *inode, struct file *fp)
{
return 0;
}
//释放 open 分配在 filp->private_data 中的任何东西,在最后的 close 关闭设备
static int mycdev_release(struct inode *inode, struct file *fp)
{
return 0;
}
//文件操作
static ssize_t mycdev_read(struct file *fp, char __user *buf, size_t size, loff_t *pos)
{
unsigned long p = *pos;
unsigned int count = size;
char kernel_buf[MYCDEV_SIZE]="This is mycdev!";
if(p >= MYCDEV_SIZE)
return -1;
if(count > MYCDEV_SIZE)
count = MYCDEV_SIZE-p;
if(copy_to_user(buf,kernel_buf,count)!=0){
printk("read error!\n");
return -1;
}
printk("reader: %d bytes was read...\n",count);
return count;
}
static ssize_t mycdev_write(struct file *fp, const char __user *buf, size_t size, loff_t *pos)
{
return size;
}
/*填充mycdev的file_operation结构*/
static const struct file_operations mycdev_fops = {
.owner = THIS_MODULE,
//.llseek = mycdev_llseek,
.read = mycdev_read,
.write = mycdev_write,
//.ioctl = mycdev_ioctl,
.open = mycdev_open,
.release = mycdev_release,
};
/*模块初始化函数*/
static int __init mycdev_init(void)
{
int ret;
printk("mycdev module is starting..\n");//此处打印成功
ret = register_chrdev(MYCDEV_MAJOB, "my_cdev", &mycdev_fops); //注册驱动程序
if(ret < 0)
{
printk("register failed..\n");
}
else
{
printk("register success..\n");//此处打印成功
}
return 0;
};
/*模块卸载函数*/
static void __exit mycdev_exit(void)
{
printk("mycdev module is leaving..\n");
unregister_chrdev(MYCDEV_MAJOB, "my_cdev");//注销驱动程序
}
module_init(mycdev_init);
module_exit(mycdev_exit);
test.c
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp0 = NULL;
char Buf[4096];
/*初始化Buf*/
strcpy(Buf,"Mem is char dev!"); //此处打印
printf("BUF: %s\n",Buf);
/*打开设备文件*/
fp0 = fopen("/dev/my_cdev","r+");
if (fp0 == NULL)
{
printf("Open my_cdev Error!\n");//此处打印
return -1;
}
/*写入设备*/
fwrite(Buf, sizeof(Buf), 1, fp0);
/*重新定位文件位置(思考没有该指令,会有何后果)*/
fseek(fp0,0,SEEK_SET);
/*清除Buf*/
strcpy(Buf,"Buf is NULL!");
printf("BUF: %s\n",Buf);
/*读出设备*/
fread(Buf, sizeof(Buf), 1, fp0);
/*检测结果*/
printf("BUF: %s\n",Buf);
return 0;
}