zoukankan      html  css  js  c++  java
  • 2018-2019-1 20165319 20165328 实验四 外设驱动程序设计

    任务一

    实验要求

    学习资源中中全课中的“hqyj.嵌入式Linux应用程序开发标准教程.pdf”中的第十一章
    提交康奈尔笔记

    任务二

    实验要求

    在Ubuntu完成资源中全课中的“hqyj.嵌入式Linux应用程序开发标准教程.pdf”中的第十一章的test试验
    提交编译,加载模块,卸载模块,测试运行的截图(要多张,全屏,体现学号信息)
    实验内容

    该实验要求实现对虚拟设备(一段内存)的打开、关闭、读写的操作,并要通过编写测试程序来测试虚拟设备及其驱动运行是否正常

    test_drv.c:

    #include <linux/module.h>
      #include <linux/init.h>
      #include <linux/fs.h>
      #include <linux/kernel.h>
      #include <linux/slab.h>
      #include <linux/types.h>
      #include <linux/errno.h>
      #include <linux/cdev.h>
      #include <asm/uaccess.h>
      #define     TEST_DEVICE_NAME    "test_dev"
      #define     BUFF_SZ         1024
    
      static struct cdev test_dev;
      unsigned int major =0;
      static char *data = NULL;
      static ssize_t test_read(struct file *file, char *buf, size_t count, loff_t *f_pos);
    
      static ssize_t test_write(struct file *file,const char *buffer, size_t count,loff_t *f_pos);
    
      static int test_open(struct inode *inode, struct file *file);
    
      static int test_release(struct inode *inode,struct file *file);
      static ssize_t test_read(struct file *file, char *buf, size_t count, loff_t *f_pos)
      {
    
          int len;
          if (count < 0 )
          {
              return -EINVAL;
          }
          len = strlen(data);
          count = (len > count)?count:len;
          if (copy_to_user(buf, data, count))
          {
              return -EFAULT;
          }
          return count;
      }
      static ssize_t test_write(struct file *file, const char *buffer, size_t count, loff_t *f_pos)
      {
          if(count < 0)
          {
              return -EINVAL;
          }
          memset(data, 0, BUFF_SZ);
          count = (BUFF_SZ > count)?count:BUFF_SZ;
          if (copy_from_user(data, buffer, count))
          {
      return -EFAULT;
          }
          return count;
      }
      static int test_open(struct inode *inode, struct file *file)
      {
          printk("This is open operation
    ");
          data = (char*)kmalloc(sizeof(char) * BUFF_SZ, GFP_KERNEL);
          if (!data)
          {
              return -ENOMEM;
          }
          memset(data, 0, BUFF_SZ);
          return 0;
      }
      static int test_release(struct inode *inode,struct file *file)
      {
          printk("This is release operation
    ");
          if (data)
          {
              kfree(data);
              data = NULL;
          }
      return 0;
      }
      static void test_setup_cdev(struct cdev *dev, int minor,
      struct file_operations *fops)
      {
          int err, devno = MKDEV(major, minor);
          cdev_init(dev, fops);
          dev->owner = THIS_MODULE;
          dev->ops = fops;
          err = cdev_add (dev, devno, 1);
          if (err)
          {
              printk (KERN_NOTICE "Error %d adding test %d", err, minor);
          }
      }
      static struct file_operations test_fops = 
      {
          .owner   = THIS_MODULE,
          .read    = test_read,
          .write   = test_write,
          .open    = test_open,
          .release = test_release,
      };
      int init_module(void)
      {
          int result;
          dev_t dev = MKDEV(major, 0);
          if (major)
          {
              result = register_chrdev_region(dev, 1, TEST_DEVICE_NAME);
          }
          else 
          {
              result = alloc_chrdev_region(&dev, 0, 1, TEST_DEVICE_NAME);
              major = MAJOR(dev);
          }
          if (result < 0) 
              {
              printk(KERN_WARNING "Test device: unable to get major %d
    ", major);
              return result;
          }
          test_setup_cdev(&test_dev, 0, &test_fops);
          printk("The major of the test device is %d
    ", major);
          return 0;
      }
      void cleanup_module(void) 
      {
          cdev_del(&test_dev);
          unregister_chrdev_region(MKDEV(major, 0), 1);
          printk("Test device uninstalled
    ");
      }
    

    Makefile:

    ifeq ($(KERNELRELEASE),)
    
    
    
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    
    
    
    PWD := $(shell pwd)
    
    
    
    modules:
    
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
    
    
    
    modules_install:
    
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
    
    
    
    clean:
    
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
    
    
    
    .PHONY: modules modules_install clean
    
    
    
    else
    
        obj-m := test_drv.o
    
    endif  
    
    

    test.c:

    /* test.c */
    
    
    
    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <string.h>
    
    #include <sys/stat.h>
    
    #include <sys/types.h>
    
    #include <unistd.h>
    
    #include <fcntl.h>
    
    #define     TEST_DEVICE_FILENAME        "/dev/test_dev"
    
    #define     BUFF_SZ             1024
    
    
    
    int main()
    
    {
    
        int fd, nwrite, nread;
    
        char buff[BUFF_SZ];
    
    
    
        fd = open(TEST_DEVICE_FILENAME, O_RDWR);
    
        if (fd < 0)
    
        {
    
            perror("open");
    
            exit(1);
    
        }
    
            
    
        do
    
        {
    
            printf("Input some words to kernel(enter 'quit' to exit):");
    
            memset(buff, 0, BUFF_SZ);
    
            if (fgets(buff, BUFF_SZ, stdin) == NULL)
    
            {
    
                perror("fgets");
    
                break;
    
            }
    
            buff[strlen(buff) - 1] = '';
    
            
    
            if (write(fd, buff, strlen(buff)) < 0)
    
            {
    
                perror("write");
    
                break;
    
            }
    
            
    
            if (read(fd, buff, BUFF_SZ) < 0)
    
            {
    
                perror("read");
    
                break;
    
            }
    
            else
    
            {
    
                printf("The read string is from kernel:%s
    ", buff);
    
            }
    
            
    
        } while(strncmp(buff, "quit", 4));
    
        
    
        close(fd);
    
        exit(0);
    
    }  
    

    test_drv_load:

    #!/bin/sh
    module="test_drv"
    device="test_dev"
    mode="664"
    group="david"
    
    
    # remove stale nodes
    rm -f /dev/${device} 
    
    # invoke insmod with all arguments we got
    # and use a pathname, as newer modutils don't look in . by default
    /sbin/insmod -f ./$module.ko $* || exit 1
    
    major=`cat /proc/devices | awk "\$2=="$device" {print \$1}"`
    
    mknod /dev/${device} c $major 0
    
    # give appropriate group/permissions
    chgrp $group /dev/${device}
    chmod $mode  /dev/${device}#!/bin/sh
    module="test_drv"
    device="test_dev"
    mode="664"
    group="david"
    
    
    # remove stale nodes
    rm -f /dev/${device} 
    
    # invoke insmod with all arguments we got
    # and use a pathname, as newer modutils don't look in . by default
    /sbin/insmod -f ./$module.ko $* || exit 1
    
    major=`cat /proc/devices | awk "\$2=="$device" {print \$1}"`
    
    mknod /dev/${device} c $major 0
    
    # give appropriate group/permissions
    chgrp $group /dev/${device}
    chmod $mode  /dev/${device}  
    
    

    test_drv_unload:

    #!/bin/sh
    module="test_drv"
    device="test_dev"
    
    # invoke rmmod with all arguments we got
    /sbin/rmmod $module $* || exit 1
    
    # remove nodes
    rm -f /dev/${device}
    
    exit 0  
    
    

    运行截图:

  • 相关阅读:
    Android Studio 开发
    Jsp编写的页面如何适应手机浏览器页面
    电影
    Oracle 拆分列为多行 Splitting string into multiple rows in Oracle
    sql server 2008 自动备份
    WINGIDE 激活失败
    python安装 错误 “User installations are disabled via policy on the machine”
    ble编程-外设发送数据到中心
    iOS开发-NSString去掉所有换行及空格
    ios9 字符串与UTF-8 互相转换
  • 原文地址:https://www.cnblogs.com/gstgst/p/10055687.html
Copyright © 2011-2022 走看看