您的位置:首页 > 其它

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

2017-12-01 22:21 453 查看

2017-2018-120155208实验四外设驱动程序设计

实验目的

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

在Ubuntu完成资源中全课中的“hqyj.嵌入式Linux应用程序开发标准教程.pdf”中的第十一章的test试验

提交编译,加载模块,卸载模块,测试运行的截图

实验一:

实验要求:

学习资源中全课中的“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>

#defineTEST_DEVICE_NAME"test_dev"

#defineBUFF_SZ1024

staticstructcdevtest_dev;

unsignedintmajor=0;

staticchar*data=NULL;

/*º¯ÊýÉùÃ÷*/

staticssize_ttest_read(structfile*file,char*buf,size_tcount,loff_t*f_pos);

staticssize_ttest_write(structfile*file,constchar*buffer,size_tcount,loff_t*f_pos);

staticinttest_open(structinode*inode,structfile*file);

staticinttest_release(structinode*inode,structfile*file);

staticssize_ttest_read(structfile*file,char*buf,size_tcount,loff_t*f_pos)

{

intlen;

if(count<0)

{

return-EINVAL;

}

len=strlen(data);

count=(len>count)?count:len;

if(copy_to_user(buf,data,count))

{

return-EFAULT;

}

returncount;

}

staticssize_ttest_write(structfile*file,constchar*buffer,size_tcount,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;

}

returncount;

}

staticinttest_open(structinode*inode,structfile*file)

{

printk("Thisisopenoperation\n");

data=(char*)kmalloc(sizeof(char)*BUFF_SZ,GFP_KERNEL);

if(!data)

{

return-ENOMEM;

}

memset(data,0,BUFF_SZ);

return0;

}

staticinttest_release(structinode*inode,structfile*file)

{

printk("Thisisreleaseoperation\n");

if(data)

{

kfree(data);

data=NULL;

}

return0;

}

staticvoidtest_setup_cdev(structcdev*dev,intminor,

structfile_operations*fops)

{

interr,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%daddingtest%d",err,minor);

}

}

staticstructfile_operationstest_fops=

{

.owner=THIS_MODULE,

.read=test_read,

.write=test_write,

.open=test_open,

.release=test_release,

};

intinit_module(void)

{

intresult;

dev_tdev=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"Testdevice:unabletogetmajor%d\n",major);

returnresult;

}

test_setup_cdev(&test_dev,0,&test_fops);

printk("Themajorofthetestdeviceis%d\n",major);

return0;

}

voidcleanup_module(void)

{

cdev_del(&test_dev);

unregister_chrdev_region(MKDEV(major,0),1);

printk("Testdeviceuninstalled\n");

}


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>

#defineTEST_DEVICE_FILENAME"/dev/test_dev"

#defineBUFF_SZ1024

intmain()

{

intfd,nwrite,nread;

charbuff[BUFF_SZ];

fd=open(TEST_DEVICE_FILENAME,O_RDWR);

if(fd<0)

{

perror("open");

exit(1);

}

do

{

printf("Inputsomewordstokernel(enter'quit'toexit):");

memset(buff,0,BUFF_SZ);

if(fgets(buff,BUFF_SZ,stdin)==NULL)

{

perror("fgets");

break;

}

buff[strlen(buff)-1]='\0';

if(write(fd,buff,strlen(buff))<0)

{

perror("write");

break;

}

if(read(fd,buff,BUFF_SZ)<0)

{

perror("read");

break;

}

else

{

printf("Thereadstringisfromkernel:%s\n",buff);

}

}while(strncmp(buff,"quit",4));

close(fd);

exit(0);

}


Makefile内容:

ifeq($(KERNELRELEASE),)

KERNELDIR?=/lib/modules/$(shelluname-r)/build

PWD:=$(shellpwd)

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:modulesmodules_installclean

else

obj-m:=test_drv.o

endif

两个脚本:

test_drv_load脚本内容:

#!/bin/sh
module="test_drv"
device="test_dev"
mode="664"
group="david"

#removestalenodes
rm-f/dev/${device}

#invokeinsmodwithallargumentswegot
#anduseapathname,asnewermodutilsdon'tlookin.bydefault
/sbin/insmod-f./$module.ko$*||exit1

major=`cat/proc/devices|awk"\\$2==\"$device\"{print\\$1}"`

mknod/dev/${device}c$major0

#giveappropriategroup/permissions
chgrp$group/dev/${device}
chmod$mode/dev/${device}


test_drv_unload脚本内容:

#!/bin/sh
module="test_drv"
device="test_dev"

#invokermmodwithallargumentswegot
/sbin/rmmod$module$*||exit1

#removenodes
rm-f/dev/${device}

exit0

依次运行,勿忘
make
之前要
makeclean


运行成功截图:





实验中的问题及解决过程

问题:第二次运行
sudo./test_drv_load
时不成功。

解决方式:通过重启虚拟机可以解决这一问题。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: