字符设备驱动(二)

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;    

}






















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值