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

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

    任务一

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

    任务二

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

    test_drv.c

    /* 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

    /* 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_load

    #!/bin/sh
    module="test_drv"
    device="test_dev"
    
    # invoke rmmod with all arguments we got
    sudo /sbin/rmmod $module $* || exit 1
    
    # remove nodes
    rm -f /dev/${device}
    
    exit 0
    
    3. 实验步骤
    • 在虚拟设备驱动源码目录下编译并加载驱动模块

      $ make clean;make
      $ ./test_drv_load
      
    • 编译并运行测试程序

      $ gcc –o test test.c
      $ ./test
      
    • 卸载驱动程序

      $ ./test_drv_unload
      
    • 通过dmesg命令查看内核打印的消息

      $ dmesg|tail –n 10
      ……
      The major of the test device is 250 
      This is open operation 
      This is release operation 
      Test device uninstalled 
      
    4. 实验截图

  • 相关阅读:
    【BZOJ 2124】【CodeVS 1283】等差子序列
    【BZOJ 1036】【ZJOI 2008】树的统计Count
    【BZOJ 1901】【ZJU 2112】Dynamic Rankings
    【BZOJ 3924】【ZJOI 2015】幻想乡战略游戏
    【BZOJ 4103】【THUSC 2015】异或运算
    【BZOJ 4513】【SDOI 2016】储能表
    【HDU 3622】Bomb Game
    【BZOJ 3166】【HEOI 2013】Alo
    【BZOJ 3530】【SDOI 2014】数数
    【BZOJ 4567】【SCOI 2016】背单词
  • 原文地址:https://www.cnblogs.com/akashi/p/10056082.html
Copyright © 2011-2022 走看看