字符设备模板2

源代码:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/cdev.h>  

//module_param(mem_major, int, S_IRUGO);  

#define MEMDEV_MAJOR        260     /*预设的mem的主设备号*/
#define MEMDEV_NR_DEVS      2       /*设备数*/
#define MEMDEV_SIZE         4096
#define CHAR_DEV_NAME       "memdev"

static int mem_major = 0; //MEMDEV_MAJOR;  

struct class *pclass = NULL;  

struct cdev my_dev;   

int mem_open(struct inode *inode, struct file *filp)
{
    return 0;
}  

int mem_release(struct inode *inode, struct file *filp)
{
    return 0;
}  

/*
‘k‘为幻数,要按照Linux内核的约定方法为驱动程序选择ioctl编号,
应该首先看看include/asm/ioctl.h和Documentation/ioctl-number.txt这两个文件.

对幻数的编号千万不能重复定义,如ioctl-number.txt已经说明‘k‘的编号已经被占用的范围为:
‘k‘    00-0F    linux/spi/spidev.h    conflict!
‘k‘    00-05    video/kyro.h        conflict!
所以我们在这里分别编号为0x1a和0x1b
*/
#define CMD_MAGIC   ‘k‘
#define MEM_CMD1    _IO(CMD_MAGIC, 0x1a)
#define MEM_CMD2    _IO(CMD_MAGIC, 0x1b)

int temp_data = 0;

static int mem_ioctl( struct file *file, unsigned int cmd, unsigned long arg)
{
    switch(cmd)
    {
        case MEM_CMD1:
            if(copy_from_user(&temp_data,  (int *)arg, sizeof(int)))
                return -EFAULT;
            break;

        case MEM_CMD2:
            if(copy_to_user( (int *)arg, &temp_data, sizeof(int)))
                return -EFAULT;
            break;
    }

    //printk(KERN_NOTICE"ioctl CMD%d done!\n",temp);
    return 0;
}

static const struct file_operations mem_fops =
{
    .owner = THIS_MODULE,
    .unlocked_ioctl = mem_ioctl,
    .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, CHAR_DEV_NAME);
    } else { /* 动态分配设备号 */
        result = alloc_chrdev_region(&devno, 0, 2, CHAR_DEV_NAME);
        mem_major = MAJOR(devno);
    }   

    if (result < 0)
        return result;  

    cdev_init(&my_dev, &mem_fops);
    my_dev.owner = THIS_MODULE;
    my_dev.ops = &mem_fops;
    cdev_add(&my_dev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);  

    pclass = class_create(THIS_MODULE, CHAR_DEV_NAME);
    if (IS_ERR(pclass))
    {
        printk("class_create failed!/n");
        goto failed;
    }  

    device_create(pclass, NULL, devno, NULL, CHAR_DEV_NAME);
    return 0;  

failed:
    cdev_del(&my_dev);
    unregister_chrdev_region(devno, 1);
    return result;
}  

static void memdev_exit(void)
{
    device_destroy(pclass, MKDEV(mem_major, 0));
    class_destroy(pclass);

    cdev_del(&my_dev);
    unregister_chrdev_region(MKDEV(mem_major, 0), 2);
}  

MODULE_AUTHOR("derek yi");
MODULE_LICENSE("GPL");  

module_init(memdev_init);
module_exit(memdev_exit);  

makefile:

ifneq ($(KERNELRELEASE),)

obj-m:=memdev.o

else

KERNELDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)

default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
    rm -rf *.o *.mod.c *.mod.o *.ko

endif

测试代码:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define CMD_MAGIC   ‘k‘
#define MEM_CMD1    _IO(CMD_MAGIC, 0x1a) // write
#define MEM_CMD2    _IO(CMD_MAGIC, 0x1b) // read

int main()
{
    int fd;
    int ret;
    int wdata, rdata;

    fd = open("/dev/memdev", O_RDWR);
    if( fd < 0 ) {
        printf("open memdev WRONG!\n");
        return 0;
    }

    ret = ioctl(fd, MEM_CMD2, &rdata);
    printf("ioctl: ret=%d rdata=%d\n", ret, rdata);

    wdata = 42;
    ret = ioctl(fd, MEM_CMD1, &wdata);

    ret = ioctl(fd, MEM_CMD2, &rdata);
    printf("ioctl: ret=%d rdata=%d\n", ret, rdata);

    close(fd);
    return 0;
}
时间: 2024-10-26 21:53:11

字符设备模板2的相关文章

字符设备模板1

源代码: /****************************************************************************** *Name: memdev.c *Desc: 字符设备驱动程序的框架结构,该字符设备并不是一个真实的物理设备, * 而是使用内存来模拟一个字符设备 *Parameter: *Return: *Author: derek *Date: 2013-6-4 ***************************************

字符设备模板

linux驱动 makefile写法: ifneq ($*KERNELRELEASE),) obj-m :=hello.o else KERNELDIR?=/lib/modules/$(shell uname -r) /build PWD :=$(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules endif 初始化和关闭: static int __init initialization_funciton(void) { *

Linux驱动开发之字符设备模板

/***************************** ** 驱动程序模板* 版本:V1* 使用方法(末行模式下):* :%s/xxx/"你的驱动名称"/g********************************/ #include <linux/mm.h>#include <linux/miscdevice.h>#include <linux/slab.h>#include <linux/vmalloc.h>#includ

字符设备集中编程模型

1.重要数据结构 - struct file_operaions - struct inode - struct file 2.杂设备驱动模板:struct miscdevice - 注册:int misc_register(struct miscdevice *misc) - 注销:int misc_deregister(struct miscdevice *misc) 3.早期标准字符设备驱动模板: - 注册:int register_chrdev(unsigned int major, c

linux字符设备驱动

一.字符设备.字符设备驱动与用户空间访问该设备的程序三者之间的关系. 如图,在Linux内核中使用cdev结构体来描述字符设备,通过其成员dev_t来定义设备号(分为主.次设备号)以确定字符设备的唯一性.通过其成员file_operations来定义字符设备驱动提供给VFS的接口函数,如常见的open().read().write()等. 在Linux字符设备驱动中,模块加载函数通过register_chrdev_region( ) 或alloc_chrdev_region( )来静态或者动态获

20150216简单的Linux字符设备驱动程序

20150216简单的Linux字符设备驱动程序 2015-02-16 李海沿 关于字符设备驱动程序详细的知识点,本文就不再介绍了,很多同志,看了知识点,还是一头雾水,写不出来,所以,本文从实战出发,带领各位同胞们来实现一个字符设备驱动程序,改程序可作为字符设备的通用模板. 好了废话不多说,先上驱动程序,在驱动程序中加入详细注释: 1 /****************************** 2 linux 字符设备驱动程序 3 *****************************/

深入浅出~Linux设备驱动之字符设备驱动

一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流的设备,常见的字符设备有鼠标.键盘.串口.控制台和LED设备等. 块设备:是指可以从设备的任意位置读取一定长度数据的设备.块设备包括硬盘.磁盘.U盘和SD卡等. 每一个字符设备或块设备都在/dev目录下对应一个设备文件.linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作字符设备和块设备

字符设备驱动之Led驱动学习记录

一.概述 Linux内核就是由各种驱动组成的,内核源码中大约有85%的各种渠道程序的代码.一般来说,编写Linux设备驱动大致流程如下: 1.查看原理图,数据手册,了解设备的操作方法. 2.在内核中找到相近的驱动程序,以它为模板开发. 3.实现驱动的初始化:比如像内核注册这个驱动程序 4.设计要实现的操作:open,close,read,write等 5.实现中断服务(不是必须的) 6.编译该驱动程序到内核中,或insmod命令加载 7.测试驱动程序. 二.驱动程序的加载与卸载 module_i

【转】深入浅出:Linux设备驱动之字符设备驱动

深入浅出:Linux设备驱动之字符设备驱动 一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流的设备,常见的字符设备有鼠标.键盘.串口.控制台和LED设备等. 块设备:是指可以从设备的任意位置读取一定长度数据的设备.块设备包括硬盘.磁盘.U盘和SD卡等. 每一个字符设备或块设备都在/dev目录下对应一个设备文件.linux用户程序通过设备文件(或称