模块描述

将30个字节的内存空间模仿成设备文件。每次读写不超过30个字节。

模块加载成功之后,需建立设备文件

mknod /dev/mydev c 231 0

模块代码

#include <linux/types.h>     //dev_t,MAJOR,MINOR,MKDEV
#include <linux/fs.h> //file_operations,struct file,struct indoe,register
//unregister_chrdev,register/alloc/unregister_chrdev_regino,
#include <linux/cdev.h> //cdev_alloc,cdev_init,cdev_add,cdev_del
#include <linux/kernel.h> //container_of
#include <linux/slab.h> //kfree,kmalloc
#include <linux/errno.h> //error code
#include <linux/module.h> //MODULE_LICENSE,...
#include <linux/platform_device.h> //struct platform_device,struct platform_driver
#include <asm/uaccess.h> //copy_from_user,copy_to_user #define MYMAJOR 231 //静态分配设备号 MODULE_LICENSE("GPL");
MODULE_AUTHOR("WGY");
MODULE_DESCRIPTION("MY_FIRST_MODULE"); unsigned int count=0; //记录打开设备的次数
dev_t devn; //设备号 struct my_cdev
{
char kerbuf[30]; //分配30个字节的内存空间
struct cdev cd; //如果这里实例化cd为指针,记得使用前为cd分配空间
}; struct my_cdev ex_cdev; //设备结构 int simple_open(struct inode * inode,struct file * filp)
{
if(count>=1) //设备已被打开
{
printk(KERN_ERR "Device is in use.");
return -EBUSY;
}
count++; //设备初次打开,加一
return 0;
} int simple_release(struct inode * inode,struct file * filp)
{
count--; //关闭设备,计数减一
return 0;
} ssize_t simple_read(struct file * filp,char __user *usrbuf,size_t count,loff_t * f_pos)
{
if(count>30) //用户要求读出字符总数超过30个字节
{
printk(KERN_WARNING "Over the max length of the kernel array");
return -1;
} //拷贝内核空间的数据到用户空间
if(copy_to_user(usrbuf,ex_cdev.kerbuf,count))
{
return -EFAULT;
} return count;
} ssize_t simple_write(struct file * filp,const char __user *usrbuf,size_t count,loff_t * f_pos)
{
if(count>30) //用户写入字符总数超过30个字节
{
printk(KERN_WARNING "over the max length of the kernel array");
return -1;
} //拷贝用户空间的数据到内核空间
if(copy_from_user(ex_cdev.kerbuf,usrbuf,count))
{
return -EFAULT;
} return 0;
} struct file_operations simple_ops=
{
.owner=THIS_MODULE,
.read=simple_read,
.write=simple_write,
.open=simple_open,
.release=simple_release,
}; int __init simple_init_module(void)
{
int ret,result; devn=MKDEV(MYMAJOR,0); //获取设备号 ret=register_chrdev_region(devn,1,"/dev/mydev"); //起始设备号,设备个数,设备名
if(ret<0)
{
printk(KERN_WARNING "failed to alloc a dev number");
return ret;
} //直接涉及内核的操作
cdev_init(&ex_cdev.cd,&simple_ops);
ex_cdev.cd.owner=THIS_MODULE;
result = cdev_add (&ex_cdev.cd, devn, 1);
if(result)
{
printk(KERN_NOTICE "Error %d adding DEMO\n", result);
}
printk("success ,good!"); return 0; } void __exit simple_cleanup_module(void)
{
cdev_del(&ex_cdev.cd);
unregister_chrdev_region(devn,1);
printk("simple_cleanup_module");
} module_init(simple_init_module);
module_exit(simple_cleanup_module);

应用

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h> int main()
{
int fd,ret;
char buf[30]={'\0'}; fd=open("/dev/mydev",O_RDWR|O_NONBLOCK|O_NOCTTY);
if(fd<0)
{
printf("fail to open..");
exit(1);
} ret=write(fd,"hello",5); //向设备写入5个字符
if(ret<0)
{
printf("fail to write.. ");
exit(1);
} ret=read(fd,buf,5); //从设备读入5个字符
if(ret<0)
{
printf("fail to read..");
exit(1);
} printf("string=%s\n",buf); //打印从设备读到的字符
close(fd); //关闭打开的文件
return 0; }

MY_FIRSH_MODULE的更多相关文章

随机推荐

  1. VS代码段扩展Snippet Designer is a Visual Studio plug in which allows you to create and search for snippets inside the IDE

    Snippet Designer is a Visual Studio plug in which allows you to create and search for snippets insid ...

  2. OC-基本

    #import <Foundation/NSObjCRuntime.h> //import: //1,同#include一样, 拷贝文件内容 //2,可以自动防止文件的内容被重复拷贝 /* ...

  3. yii2接收activeform表单信息

    第一种方法: $model->load(Yii::$app->request->post()); 第二种方法: 获取具体的某一项的值 $demo = $_POST['模型名']['字 ...

  4. Oracle nvl(),nvl2()函数介绍

    NVL函数 Oracle/PLSQL中的一个函数. 格式为: NVL( string1, replace_with) 功能:如果string1为NULL,则NVL函数返回replace_with的值, ...

  5. android自定义控件(5)-实现ViewPager效果

    对于系统的ViewGroup我们已经是十分熟悉了,最常用的LinearLayout和RelativeLayout几乎是天天要打交道,下面我们就来看看,如何一步一步将其实现: 一.首先当然也是最通常的新 ...

  6. linux下生成core dump文件方法及设置

    linux下生成core dump文件方法及设置    from:http://www.cppblog.com/kongque/archive/2011/03/07/141262.html core ...

  7. [译]git init

    git init git init命令用来创建一个新的Git仓储.可以用在一个已经存在的但是没有受Git版本控制的项目,或者用来初始化一个全新的没有任何文件的空仓储.git init通常是你开始一个新 ...

  8. VC++ 6.0使用定时器SetTimer;

    背景: windows中使用VC++6.0制作了个交互界面向下位机定时发送数据及显示下位机上传的数据.定时发送则需要使用定时器. 本文只做记录如何调用,原理以后再深究. 正文: 首先,我生成的窗体类名 ...

  9. centos 6.5 zabbix3.0.4 监控apache

    开启apache的server-status httpd.conf 末尾添加 [root@test3 /]# vim /usr/local/httpd-/conf/httpd.conf Extende ...

  10. linux 使用rpm安装软件时,遇到"warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID fd431d51: NOKEY "错误

    建议的做法: warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID fd431d51: NOKEY    网上资料说这是 ...