实验四外设驱动程序设计-1
- 学习资源中全课中的“hqyj.嵌入式Linux应用程序开发标准教程.pdf”中的第十一章
提交康奈尔笔记的照片(可以多张)
实验四外设驱动程序设计-2
- 在Ubuntu完成资源中全课中的“hqyj.嵌入式Linux应用程序开发标准教程.pdf”中的第十一章的test试验
提交编译,加载模块,卸载模块,测试运行的截图(要多张,全屏,体现学号信息)
Makefile
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/3.2.0-24-generic/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
elseobj-m := test_drv.o
endif
test.c
/* test.c */#include #include #include #include #include #include #include #define TEST_DEVICE_FILENAME "/dev/test_dev"#define BUFF_SZ 1024int main(){int fd, nwrite, nread;char buff[BUFF_SZ];fd &#61; open(TEST_DEVICE_FILENAME, O_RDWR);if (fd <0){perror("open");exit(1);}do{printf("Input some words to kernel(enter &#39;quit&#39; to exit):");memset(buff, 0, BUFF_SZ);if (fgets(buff, BUFF_SZ, stdin) &#61;&#61; NULL){perror("fgets");break;}buff[strlen(buff) - 1] &#61; &#39;\0&#39;;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\n", buff);}} while(strncmp(buff, "quit", 4));close(fd);exit(0);}
test_drv.c
/* test_drv.c */#include #include #include #include #include #include #include #include #include #define TEST_DEVICE_NAME "test_dev"#define BUFF_SZ 1024static struct cdev test_dev;unsigned int major &#61;0;static char *data &#61; 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 &#61; strlen(data);count &#61; (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 &#61; (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\n");data &#61; (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\n");if (data){kfree(data);data &#61; NULL;}return 0;}static void test_setup_cdev(struct cdev *dev, int minor,struct file_operations *fops){int err, devno &#61; MKDEV(major, minor);cdev_init(dev, fops);dev->owner &#61; THIS_MODULE;dev->ops &#61; fops;err &#61; cdev_add (dev, devno, 1);if (err){printk (KERN_NOTICE "Error %d adding test %d", err, minor);}}static struct file_operations test_fops &#61; {.owner &#61; THIS_MODULE,.read &#61; test_read,.write &#61; test_write,.open &#61; test_open,.release &#61; test_release,};int init_module(void){int result;dev_t dev &#61; MKDEV(major, 0);if (major){result &#61; register_chrdev_region(dev, 1, TEST_DEVICE_NAME);}else {result &#61; alloc_chrdev_region(&dev, 0, 1, TEST_DEVICE_NAME);major &#61; MAJOR(dev);}if (result <0) {printk(KERN_WARNING "Test device: unable to get major %d\n", major);return result;}test_setup_cdev(&test_dev, 0, &test_fops);printk("The major of the test device is %d\n", major);return 0;}void cleanup_module(void) {cdev_del(&test_dev);unregister_chrdev_region(MKDEV(major, 0), 1);printk("Test device uninstalled\n");}
test_drv_load
#!/bin/sh
module&#61;"test_drv"
device&#61;"test_dev"
mode&#61;"664"
group&#61;"linux"# remove stale nodes
rm -f /dev/${device} # invoke insmod with all arguments we got
# and use a pathname, as newer modutils don&#39;t look in . by default
/sbin/insmod -f ./$module.ko $* || exit 1major&#61;&#96;cat /proc/devices | awk "\\$2&#61;&#61;\"$device\" {print \\$1}"&#96;mknod /dev/${device} c $major 0# give appropriate group/permissions
chgrp $group /dev/${device}
chmod $mode /dev/${device}
test_drv_unload
#!/bin/sh
module&#61;"test_drv"
device&#61;"test_dev"# invoke rmmod with all arguments we got
/sbin/rmmod $module $* || exit 1# remove nodes
rm -f /dev/${device}exit 0
- 遇到的问题
首先要注意Makefile文件中的空格和tab 的区别
其次要在test_drv_load中把组改成虚拟机用户所在的组&#xff0c;老师给的虚拟机所在的组就是linux,不能用原来的David&#xff0c;否则会出现无效的组
再有Makefile中要改成这个KERNELDIR ?&#61; /lib/modules/3.2.0-24-generic/build