zoukankan      html  css  js  c++  java
  • 20155312 20155325 2017-2018 1 实验四 外设驱动程序设计

    实验四外设驱动程序设计-1

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

    已提交至班课

    实验四外设驱动程序设计-2

    在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
    ");
    }
    
    • 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);
    }
    
    • 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_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}
    
    • 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
    

    实验四外设驱动程序设计-3

    在实验箱中通过交叉编译完成test实验
    提交编译,加载模块,卸载模块,测试运行的截图(要多张,全屏,体现学号信息)

    未完成

    遇见的问题

    • 问题1:并没有办法在自己的虚拟机上运行成功。

    • 解决:用之前实验拷的虚拟机实现。

    • 问题2:报错
      insmod: error inserting 'test_drv.ko':-1 File exists

    • 解决:搜到了一堆不明觉厉的东西。尝试过删除,比如照着这个链接 insmod: error inserting 'memdev.ko': -1 File exists

    最终研究决定重启,然后就可以继续运行下去了
    linux insmod error inserting ' ':-1file exists问题

    • 问题3:“ERROR: Removing 'test_drv': Device or resource busy”
    • 解决:我们并未解决好。
      队友的尝试过程记录地详细,贴出来

    步骤:

    1.sudo mv /usr/bin/gcc /usr/bin/gcc-bak删除旧链接

    2.sudo ln -s gcc-4.6 gcc
    再次用“ls -al /usr/bin/gcc”查看gcc版本,显示“lrwxrwxrwx 1 root root 7 11月 28 16:34 /usr/bin/gcc -> gcc-4.6”

    运行./test_drv_unload仍然出现错误提示

  • 相关阅读:
    POJ 2923 Relocation (状态压缩,01背包)
    HDU 2126 Buy the souvenirs (01背包,输出方案数)
    hdu 2639 Bone Collector II (01背包,求第k优解)
    UVA 562 Dividing coins (01背包)
    POJ 3437 Tree Grafting
    Light OJ 1095 Arrange the Numbers(容斥)
    BZOJ 1560 火星藏宝图(DP)
    POJ 3675 Telescope
    POJ 2986 A Triangle and a Circle
    BZOJ 1040 骑士
  • 原文地址:https://www.cnblogs.com/GDDFZ/p/7966974.html
Copyright © 2011-2022 走看看