信息安全系统设计基础实验四:外设驱动程序设计 20135211李行之&20135216刘蔚然
2015-12-02 17:00
441 查看
北京电子科技学院(BESTI)
实 验 报 告
封面
课程:信息安全系统设计基础 班级:1352 姓名:(按贡献大小排名)李行之 刘蔚然学号:(按贡献大小排名)20135211 20135216 成绩: 指导教师:娄嘉鹏 实验日期:2015.12.1
实验密级: 预习程度: 实验时间:15:30—17:30 仪器组次:11 必修/选修:必修
实验序号:4 实验名称: 外设驱动程序设计
实验目的与要求: 1.在掌握基于 S3C2410 的 linux 开发环境的配置和使用的基础上进行交叉编译。 2.理解驱动程序的一般设计方法。 3.(要求)正确使用连接线等实验仪器,并注意保护实验箱。实验结束之后将实验箱送回。
实验仪器: - (名称) (型号) (数量)
- 嵌入式开发平台 UP-NETARM2410-CL 1
- PC机 1
正文(个人理解部分由【】标出)
一、实验内容:
(同实验一)本次实验建立在掌握嵌入式开发平台使用方法和配置方法的基础上,要求使用windows xp,linux(red hat),arm三个系统(即NFS方式);在linux系统中安装arm系统,然后对01_demo文件夹中的.c文件进行交叉编译。
二、实验原理
什么是驱动程序?目的:驱动程序是应用程序和硬件之间的一个软件层,为(许多个)应用程序提供硬件的所有功能。为了处理并发的情况,还需要考虑互斥量和锁等机制。
特点:应用程序一般有一个 main 函数,从头到尾执行一个任务;驱动程序却不同,它没有main函数,通过使用宏module_init(初始化函数名)。
用法:将初始化函数加入内核全局初始化函数列表中,在内核初始化时执行驱动的初始化函数,从而完成驱动的初始化和注册,之后驱动便停止等待被应用软件调用。驱动程序中有一个宏moudule_exit(退出处理函数名)注册退出处理函数。它在驱动退出时被调用。
主要代码
test_demo.c
#include <stdio.h> #include <stdlib.h> #include <fcntl.h>//其中定义了很多宏和诸如open,close函数 #include <unistd.h> #include <sys/ioctl.h>//ioctl函数的头文件 void showbuf(char *buf); int MAX_LEN=32; int main() { int fd; int i; char buf[255]; for(i=0; i<MAX_LEN; i++){//给数组元素依次赋值 buf[i]=i; } fd=open("/dev/demo",O_RDWR);//以既可以读又可以写的方式打开文件 if(fd < 0){ printf("####DEMO device open fail####\n"); return (-1); } printf("write %d bytes data to /dev/demo \n",MAX_LEN); showbuf(buf);//先显示一下要写入什么,然后写入 write(fd,buf,MAX_LEN); printf("Read %d bytes data from /dev/demo \n",MAX_LEN); read(fd,buf,MAX_LEN); showbuf(buf);//先读出来字符串到buf中,再显示 ioctl(fd,1,NULL); ioctl(fd,4,NULL); close(fd); return 0; } void showbuf(char *buf) { int i,j=0; for(i=0;i<MAX_LEN;i++){ if(i%4 ==0) printf("\n%4d: ",j++); printf("%4d ",buf[i]); } printf("\n*****************************************************\n"); }
这段代码很简单,然而会出现一个疑问:write函数、read函数在哪里定义的?ioctl函数优势做什么的?于是我接下来查看了实验指导书的原理部分和demo.c代码。
其实,上面这段代码中出现的函数都在demo.c代码中有了定义。比如,ioctl函数的定义(严格说来,驱动程序里定义的是方法):
static int demo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { printk("ioctl runing\n"); switch(cmd){ case 1:printk("runing command 1 \n");break; case 2:printk("runing command 2 \n");break; default: printk("error cmd number\n");break; } return 0; }
ioctl 方法主要用于对设备进行读写之外的其他控制,比如配置设备、进入或退出某种 操作模式,这些操作一般都无法通过read/write 文件操作来完成。
三、实验过程&困难排查
1.配置实验箱同实验一中一样,配置实验环境
连接arm开发板;
建立超级终端;
启动实验平台;
修改windows xp系统的ip使得它与arm机的ip在同一网段;
在red hat中安装arm编译器;
配置环境变量。
2.进入01_demo文件夹中,尝试直接make进行自动编译。出现如下图所示的错误。
(图1)
按照指导书的提示,进行如下操作建立linux连接:
cd /usr/src/ ln -sf linux-2.4.20-8 linux ls (结果)debug linux linux-2.4 linux-2.4.20-8 redhat
然而,仍然出现上图的错误。
3.这时,尝试按照如下内容修改01_demo文件夹中的Makefile
KERNELDIR = /usr/src/linux #KERNELDIR = /arm2410cl/ kernel/linux-2.4.18-2410cl/ INCLUDEDIR = $(KERNELDIR)/include #CROSS_COMPILE=armv41-unknown-linux- AS =$(CROSS_COMPILE)as LD =$(CROSS_COMPILE)ld CC =$(CROSS_COMPILE)gcc CPP =$(CC) -E AR =$(CROSS_COMPILE)ar NM =$(CROSS_COMPILE)nm STRIP =$(CROSS_COMPILE)strip OBJCOPY =$(CROSS_COMPILE)objcopy OBJDUMP =$(CROSS_COMPILE)objdump CFLAGS += -I.. CFLAGS += -Wall -O -D__KERNEL__ -DMODULE -I$(INCLUDEDIR) TARGET = demo OBJS = demo.o hello.o SRC = demo.c hello.c all: $(OBJS) demo.o: demo.c $(CC) -c $(CFLAGS) $^ -o $@ hello.o:hello.c $(CC) -c $(CFLAGS) $^ -o $@ install: install -d $(INSTALLDIR) install -c $(TARGET).o $(INSTALLDIR) clean: rm -f *.o *~ core .depend
(图2)
4.再次进行make之后,系统不再提示错误。然而少了最后对于testdemo.c的编译。于是,我们进行了手动编译。最后执行./testdemo,结果如下:
(图4)
四、总结
我们在实验四上花费了比预计更多的时间。事后总结,主要是对Makefile的更改“不彻底”。一旦严格按照指导书中的内容更改了Makefile,就可以顺利地完成编译。相关文章推荐
- JavaScript 字符串转日期
- 第二章 OSI参考模型和TCP/IP模型(续)
- 电子小制作:一个远程温度湿度监控方案
- 深度优先搜索
- Maven Dependency Scope
- NYOJ 214 最长上升子序列加强版(二分+dp)
- java_home should point to a jdk not a jre
- 使用sphinx创建搜索引擎(一)----简单索引
- java(6)--GUI学习
- 深度优先搜索
- 【图解HTTP】第一章 了解web及网络基础
- 微博发布时间处理
- pom添加多个源代码目录
- Java基本知识(连载)-分支和循环-2
- iOS开发笔记- 判断是否是数字
- 二、WorldWindJavaApplet
- mysql explain 解释器中的字段含义
- [原]iOS--字符编码,NSString和UTF-8间的转换
- dubbo搭建过程记录(适用本人)
- java List.subList方法中的超级大陷阱