zoukankan      html  css  js  c++  java
  • 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   否则会显示设备打开失败。
     
  • 相关阅读:
    Splay复习
    带权并查集复习-HDU3038
    罗素悖论-图灵停机问题
    数独解法c++实现
    状压DP NOI2001 炮兵阵地
    区间第k大数
    分块随笔T2
    分块感想
    webkit的高级属性
    设计模式
  • 原文地址:https://www.cnblogs.com/Windeal/p/4284680.html
Copyright © 2011-2022 走看看