Linux设备驱动——简单的字符驱动

本文介绍Linux字符设备的静态注册方法,
其中涉及到的模块加载,不了解的可以先参考


1. 还是线上源代码:

//memdev.h
#ifndef _MEMDEV_H_
#define _MEMDEV_H_
 
#ifndef MEMDEV_MAJOR
#define MEMDEV_MAJOR 200
#endif
 
#ifndef MEMDEV_NR_DEVS
#define MEMDEV_NR_DEVS 2
#endif
 
#ifndef MEMDEV_SIZE
#define MEMDEV_SIZE 4096
#endif
 
struct mem_dev{
    char* data;
    unsigned long size;
 
};
 
#endif
 
//memdev.c  
# include < linux / module.h >
# include < linux / types.h >
# include < linux / fs.h >
# include < linux / errno.h >
# include < linux / mm.h >
# include < linux / sched.h >
# include < linux / init.h >
# include < linux / cdev.h >
# include < asm / io.h >
# include < asm / system.h >
# include < asm / uaccess.h >
# include < linux / wait.h >
# include < linux / completion.h >
 
# include "memdev.h"
 
MODULE_LICENSE( "Dual BSD/GPL" );
 
static int   mem_major = MEMDEV_MAJOR;
 
struct mem_dev * mem_devp; /*设备结构体指针*/
 
struct cdev cdev;
 
/*文件打开函数*/
int mem_open( struct inode * inode, struct file * filp)
{
printk( "open own file " );
     return 0 ;
}
 
/*文件操作结构体*/
static const struct file_operations mem_fops=
{
  .owner = THIS_MODULE,
  .open = mem_open,
};
 
/*设备驱动模块加载函数*/
static int memdev_init( void )
{
   int result;
   int i;
 
  dev_t devno = MKDEV(mem_major, 0 );
 
   /* 静态申请设备号*/
    result = register_chrdev_region(devno, 2 , "memdev" );
   if (result < 0 )
     return result;
 
   /*初始化cdev结构*/
  cdev_init( & cdev, & mem_fops);
 
   /* 注册字符设备 */
  cdev_add( & cdev, MKDEV(mem_major, 0 ), MEMDEV_NR_DEVS);
 
   return result;
}
 
/*模块卸载函数*/
static void memdev_exit( void )
{
  cdev_del( & cdev);    /*注销设备*/
  unregister_chrdev_region(MKDEV(mem_major, 0 ),2 ); /*释放设备号*/
}
 
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 memdev.mod*  module* memdev.o memdev.ko Module.*
endif
 
 
2. 测试
    首先先make下,生成memdev.ko
    然后insmod memdev.ko生成memdev模块
    创建设备节点:sudo mknod /dev/memdev_t c 200 0
    接下开使用设备文件
    下面是一个测试程序

  // memusr.c
#include <stdio.h>
#include <string.h>
 
int main()
{
    FILE *fp0;
    /*打开设备文件*/
    fp0 = fopen("/dev/memdev_t","r+");
    if (fp0 == NULL) {
        printf("Open Memdev0 Error! ");
        return -1;
    }
}
 
 
 
 
 
 
编译运行,然后使用dmesg可以看到日志文件里输出
[38439.741816] Hello World!
[38657.654345] Goodbye
[40393.039520] open own file
 
记得要使用sudo 运行memusr   否则会显示设备打开失败。
 
原文地址:https://www.cnblogs.com/Windeal/p/4284680.html