嵌入式Linux实验报告.doc_第1页
嵌入式Linux实验报告.doc_第2页
嵌入式Linux实验报告.doc_第3页
嵌入式Linux实验报告.doc_第4页
嵌入式Linux实验报告.doc_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

嵌 入 式 程 序 设 计实 验 报 告评 语:成绩教 师:年 月 日班 级: 学 号: 姓 名: 地 点: EII-506 时 间: 2013年6月 实验一开发环境的搭建与配置一、 【实验目的】1) 熟悉嵌入式Linux开发平台。2) 掌握嵌入式Linux开发平台的开发环境搭建与配置。3) 了解minicom配置串口通信参数的过程。4) 了解嵌入式Linux的启动过程。5) 掌握程序交叉编译运行及调试的一般方法。6) 掌握网络文件系统NFS的配置方法。7) 掌握嵌入式系统内核的编译、文件系统的打包及镜像的下载方法。二、 【实验内容】1) 连接实验开发板与宿主机。2) 在虚拟机中的CentOS(宿主机)搭建开发环境。3) 在宿主机中配置minicom。4) 分析嵌入式Linux的启动过程。5) 在宿主机上编写简单的C语言程序并用交叉编译工具进行编译,然后传输到目标机上运行。6) 在宿主机上编写简单的C语言程序并用交叉编译工具进行编译,用gdbserver进行远程调试。7) 配置NFS并用NFS进行文件拷贝。8) 嵌入式系统内核编译与文件系统的打包。9) 内核文件镜像与文件系统镜像的下载(从宿主机下载到目标机)。三、 【实验步骤】1. 连接实验开发板,对虚拟机进行设置2. 工具链的配置3. tftp的安装4. 进入minicom软件,配置串口通信参数有关串口通信选项的含义:Filenames and paths:选择需要传输的文件和路径File transfer protocols:选择传输文件的通信协议Serial port setup:设置串口通信参数Save setup as dfl:将设置好的各项参数保存为dflSave setup as:将设置好的各项参数保存为自定义的文件名Exit:退出返回到minicom设置好后的终端Exit from Minicom:从minicom命令中退出返回Linux终端将光标移到Serial port setup,按回车键会弹出串口通信参数的配置菜单。5. 实验开发板的启动6. 嵌入式Linux系统的启动过程分析1) 启动BootloaderBootloader是嵌入式系统的引导加载程序,它是系统上电后运行的第一段程序,其作用类似于PC机上的BIOS。在本系统中这段程序的起始地址为0x00000000。Bootloader在完成初始化RAM、初始化串口、检测处理器类型、设置Linux启动参数后,开始调用Linux内核。本系统Linux内核镜像zImage放在Flash中,Bootloader首先把它拷贝到RAM中,然后跳转到RAM中对zImage进行解压缩。解压缩后启动内核。2) 加载内核内核启动后先进行一系列与内核相关的初始化,然后调用第一个用户进程init进程并等待用户进程的执行。具体的过程如下:进行与体系结构相关的第一个初始化工作,首先通过检测出来的处理器类型进行处理器内核的初始化,然后进行内存结构的初始化,最后开启MMU,创建内核页表,映射所有的物理内存和IO空间;创建异常向量表和初始化中断处理函数;初始化系统核心进程调度器和时钟中断处理机制;初始化串口控制台,在minicom中看到的系统启动过程中的信息都是通过串口输出的;创建和初始化系统cache,为各种内存调用机制提供缓存,包括动态内存分配、虚拟文件系统及页缓存;初始化内存管理,检测内存大小及被内核占用的内存情况;初始化系统的进程间通信机制(IPC);创建init进程,结束内核的启动。3) 执行init进程。内核被加载后,第一个运行的程序便是/sbin/init,init进程是所有进程的发起者和控制者,它的进程号是1。init进程首先读取/etc/inittab文件,并依据此文件来进行初始化工作(首先进行一系列的硬件初始化,然后通过命令行传递过来的参数挂载根文件系统。最后执行一些其它的进程)。init配置文件每行的基本格式为“id:runlevel_ignored:action:process”,其中某些部分可以为空。各部分的具体内容如下:id:指定启动进程的控制终端,如果所启动的进程并不是可以交互的shell,应该会有个控制终端(在PC机上该字段表示配置行的惟一标识)。runlevel_ignored:该字段是忽略掉的,配置inittab时空着它就行了(在PC机上该字段用来配置所启动进程适用的系统运行级别)。4) 执行/bin/login程序。有些嵌入式系统在init进程执行完后会执行/bin/login。login程序会提示使用者输入账号及密码,接着编码并确认密码的正确性,如果账号与密码相符,则为使用者初始化环境,并将控制权交给shell,即等待用户登录。本系统在执行完init进程后直接开始执行/bin/sh,进入shell交互程序(跳过了执行/bin/login这一步)。这个可以通过图27中的语句“ttyS0:askfirst:-bin/sh”来说明。7. 程序的交叉编译及运行8. gdbserver远程调试9. NFS的配置10. 内核配置与编译11. 文件系统的打包12. 内核与文件系统的下载实验二并发Web服务器的实现一、 【实验目的】1) 熟悉Linux网络编程。2) 了解Web服务器原理。3) 掌握嵌入式Linux多进程、多线程、I/O多路复用三种方式并发服务器的实现。二、 【实验内容】1) 用多进程实现Web服务器。2) 用多线程实现Web服务器。3) 用I/O多路复用方式实现Web服务器。三、 【实验步骤】1.环境配置2.实现多进程Web服务器1) 用arm-linux-gcc命令编译源程序,得到可执行程序web_server_process。2) 用vi文本编译器创建文件index.html,用于测试Web服务器。3) 编辑文件index.html,然后保存并退出vi编辑器。4) 在/mnt/nfs/web目录下创建子目录cgi-bin,并用vi文本编辑器在cgi-bin目录下创建文件hello.cgi,用于测试Web服务器。5) 编辑文件hello.cgi,然后保存并退出vi编辑器。6) 用ls命令可以看到root用户对文件hello.cgi没有执行权限,通过chmod命令来修改hello.cgi的权限,使它称为可执行文件。7) 用命令service启动宿主机上的nfs服务,并用exportfs命令查看nfs的共享目录。然后在目标机上挂载nfs8) 在目标机中运行web_server_process。9) 打开宿主机的浏览器,输入/file,查看执行结果10) 在宿主机的浏览器中输入,查看执行结果。11) 在宿主机的浏览器中输入/index.html,查看执行结果。12) 在宿主机的浏览器中输入/cgi-bin/hello.cgi,查看执行结果。13) 在宿主机的浏览器中输入/web_server_process.c,查看执行结果。3.实现多线程Web服务器1) 用arm-linux-gcc命令编译源程序,得到可执行程序web_server_thread。2) 在目标机中运行web_server_thread。3) 在宿主机的浏览器中输入,查看执行结果。4) 在宿主机的浏览器中输入/cgi-bin/hello.cgi,查看执行结果。5) 在宿主机的浏览器中输入/web_server_thread.c,查看执行结果。4.实现I/O多路复用方式的Web服务器1) 用arm-linux-gcc命令编译源程序,得到可执行程序web_server_select。2) 在目标机中运行web_server_select。3) 在宿主机的浏览器中输入,查看执行结果。4) 在宿主机的浏览器中输入/cgo-bin/hello.cgi,查看执行结果。5) 在宿主机的浏览器中输入/web_server_select.c,查看执行结果。实验三 嵌入式Linux驱动一、 【实验目的】1) 熟悉嵌入式Linux驱动程序编写框架。2) 了解七段数码管驱动程序的工作原理,熟练掌握该驱动程序在嵌入式开发平台的移植和注册使用。3) 了解16键矩阵键盘驱动程序的工作原理,熟练掌握该驱动程序在嵌入式开发平台的移植和注册使用。二、 【实验内容】1) 学习Linux驱动源代码,分析代码中各个函数模块的功能作用。2) 在宿主机上交叉编译七段数码管驱动程序,然后移植到目标机上。3) 在目标机上注册驱动程序,验证驱动的功能。三、 【实验步骤】1.了解七段数码管工作原理七段数码管是显示数字的电子元件,因为借助七个发光二极管以不同组合来显示数字,所以称为七段数码管(如图1)。七段数码管分为共阴极和共阳极,共阳极的七段数码管的正极(或者阳极)为八个发光二极管的共有正极,其他接点为独立发光二极管的负极(或者阴极),使用者只需要把正极接电,不同的负极接地就可以控制七段数码管显示不同的数字。共阴极的七段数码管与共阳极的只是接电的接法相反而已。图12.开发板七段数码管电路介绍开发板上有四个七段共阴数码管,2个一组,第一组七段数码管使用系统LED_CS2作为其位选使能信号,两个数码管的段选信号分别使用数据总线的D0D7位和D8D15位,如图2所示。图2第二组七段数码管使用系统LED_CS3作为其位选使能信号,两个数码管的段选信号分别使用数据总线的D0D7位和D8D15位,如图3所示。图3分析可知,对七段数码管的操作主要是对其位选和段选信号的控制。其中位选信号决定显示哪个七段数码管,段选信号决定其显示的字型信息(共阴极七段数码管段选控制信息如表1),这也是驱动程序和硬件关联的主要部分。D7D6D5D4D3D2D1D0字型DpGFEDCBA编码0011111110X3F1000001100X062010110110X5B3010011110X4F4011001100X665011011010X6D6011111010X7D7000001110X078011111110X7F9011011110X6FA011101110X77B011111000X7CC001110010X39D010111100X5EE011110010X79F011100010X71表13.七段数码管驱动程序分析1) 添加驱动程序所需的头文件和变量:SEG_CS1和SEG_CS2就是上面硬件接口所提及的两组七段数码管的位选使能信号,LED10数组中保存的就是在共阴极数码管上面显示09的段选信号。Seg这个结构体用于保存4个数码管即时显示的数字的段选信号。#include #include #include #include #include MODULE_LICENSE(GPL);/用于声明描述内核模块的许可权限,如果不声明LICENSE,模块被加载时将收到内核被污染(kernel tainted)的警告char LED_MODULE=0;#define DEVICE_NAMExidian_seg7#define SEG_CS1 0x10300000 #define SEG_CS2 0x10400000static char LED10=0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7F, 0x6F;unsigned long *CS1_Address, *CS2_Address;structsegchar LED1_Val;char LED2_Val;char LED3_Val;char LED4_Val;char negative;2) 同时更新所有七段数码管驱动显示函数:CS1_address对应第一组七段数码管的位选信号,该组第一个数码管的段选信号保存在short变量的低8位,该组第二个数码管的段选信号保存在short变量的高8位。CS2_address对应第二组七段数码管,其余操作和第一组的七段数码管一致。static void Updateled(struct seg *seg_7)unsigned short buff=0x00;buff=seg_7-LED1_Val;buff=buff|( seg_7-LED2_Val LED3_Val;buff=buff|( seg_7-LED4_Valnegative=0)value=value & (0x17);elsevalue=(0x1LED1_Val=value;else if(position=2)seg_7-LED2_Val=value;else if(position=3)seg_7-LED3_Val=value;else if(position=4)seg_7-LED4_Val=value;4) 实现七段数码管驱动写操作函数:把用户写入的数码管显示更新数据,转换成为要显示数字对应的段选信号,并且保存在led_forall数组中,并且调用Value_setting更新显示数据,最后调用Updateled()更新实际的数码管显示信息。staticssize_t seg7_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)int i;structseg *seg_7=file-private_data;charled_forall4;printk(KERN_EMERG The Module is written,seg7_writen);if(count!=4)printk(KERN_EMERG the count of input is not 4!);return 0;if(copy_from_user(led_forall, buffer, 4)returnEFAULT;for(i=1;iprivate_data;if (!arg) return -EINVAL;if (copy_from_user(&val, (int *)arg, sizeof(char) return -EFAULT;switch(cmd)case 1:value_seting(seg_7, 1, val);break;case 2:value_seting(seg_7, 2, val);break;case 3:value_seting(seg_7, 3, val);break;case 4:value_seting(seg_7, 4, val);break;case 0:seg_7-negative = LED_MODULE;break;default:printk(KERN_EMERGioctl parameter input error,please input number 0-4);break; Updateled(seg_7);return 0; 6) 实现七段数码管驱动打开操作函数。staticint seg7_open(struct inode *inode, struct file *filp)structseg *seg_7;printk(KERN_EMERG The Module is open,seg7_openn);seg_7=kmalloc(sizeof(struct seg), GFP_KERNEL);/分配内存(在内核空间)seg_7-negative=LED_MODULE;filp-private_data=seg_7;return 0;7) 实现七段数码管驱动释放函数。staticint seg7_release(struct inode *inode, struct file *filp)printk(KERN_EMERG The Module is release,seg7_releasen);kfree(filp-private_data);return 0;8) 七段数码管驱动文件结构体定义:定义七段数码管驱动程序的打开,写入,释放,Ioctl操作,属主信息。static struct file_operationsEmdoor_fops = open:seg7_open,write:seg7_write,release:seg7_release,ioctl:seg7_ioctl,owner: THIS_MODULE,;9) 实现七段数码管驱动初始化函数:映射七段数码管的位选信号的物理实际地址,注册设备。staticint _init seg7_init(void)int ret;printk(KERN_EMERG The Module is Init,seg7_initn);CS1_Address=ioremap(SEG_CS1, 4);CS2_Address=ioremap(SEG_CS2, 4);ret = register_chrdev(56, DEVICE_NAME, &Emdoor_fops);if (ret 0) printk(DEVICE_NAME cant get major numbern);return ret;return 0;10) 实现七段数码管驱动模块退出函数与模块描述:取消对七段数码管的位选信号的物理地址的映射,释放设备。static void _exit seg7_exit(void)printk(KERN_EMERG The Module is Exit,seg7_exitn);iounmap(CS1_Address);iounmap(CS2_Address);unregister_chrdev(56, DEVICE_NAME);module_init(seg7_init);module_exit(seg7_exit);MODULE_AUTHOR(Mr.han);MODULE_DESCRIPTION(This is a 7 Segment Led driver demo);11) 七段数码管驱动程序的MakefileCFLAGS +=$(DEBFLAGS) -Wallifneq ($(KERNELRELEASE),)obj-m :=xidian_seg7.oelseKERNELDIR ?=./linux-2.6PWD :=$(shellpwd)ALL:$(MAKE) $(CFLAGS) -C $(KERNELDIR) M=$(PWD) modulesendifclean:rm -fr *.o *.ko *.symvers * core .depend .*.cmd *.mod.c .tmp_versions4.编写七段数码管驱动的测试程序和Makefile文件1) seg7_test.c源代码:#include #include #include #include #include typedef unsigned char u8;#define SEG_DEV/dev/xidian_seg7 char number=0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7F, 0x6F;voidclear_led(intfd)int i;charval=0;for(i=1;i=4;i+) ioctl(fd, i, &val); sleep(1);voiddisplay_led(intfd)int i;charval=0x7f;for(i=1;i=4;i+) ioctl(fd, i, &val); sleep(1);voidappear_same(intfd)chari,j,base=0;for (j=0, base=0 ;j=9; j+, base+) for(i=1; i=4; i+)ioctl(fd, i, number+base);sleep(1);voidappear_roll(intfd)char i, j, base=0;for (j=0, base=0; j=9; j+, base+)for(i=1; i0) printf(#SEG Device has been open#%d n,fd); else fd = open(SEG_DEV, O_RDWR);if(fd0) appear_same(fd);clear_led(fd); elseprintf(#SEG Device is NOT open# n);display_menu();break;case 2:if(fd0) appear_roll(fd);clear_led(fd); elseprintf(#SEG Device is NOT open# n);display_menu();break;case 3:if(fd0)display_led(fd);elseprintf(#SEG Device is NOT open# n);display_menu();break;case 4:if(fd0)clear_led(fd);elseprintf(#SEG Device is NOT open# n);display_menu();break;case 5:if(fd0)printf(“please input a number(0 = number =9999):”);scanf(“%d”, &num);if (num 9999)printf(“can not display this number.n”);else led0=num/1000;led1=(num%1000)/100;led2=(num%100)/10;led3=num%10;write(fd,led,4); elseprintf(#SEG Device is NOT open# n);display_menu();break;case c:case C:if(fd0) clear_led(fd);sleep(1);close(fd);printf(#SEG Device is closed success# n);fd=-1;display_menu();break;case x:case X:if(fd0) clear_led(fd);sleep(1);close(fd);exit(0);break;return(0);2) 测试程序的Makefile文件内容:seg7_test:seg7_test.carm-linux-gcc seg7_test.c -o seg7_testclean:rm -f seg7_test5.七段数码管驱动的交叉编译6.驱动程序的移植、注册与测试7.熟悉16键矩阵键盘工作原理矩阵键盘又称为行列式键盘,它是用4条I/O线做为行线,4条I/O线作为列线组成的键盘。在行线和列线的每一个交叉点上,设置一个按键。这样键盘中按键的个数是4*4个(如图1),这种行列式键盘结构能够有效的提高嵌入式系统MCU的I/O的利用率(如果采用直连式的键盘,16个按键需要16个I/O口,此举节省了8个I/O口)。图1以图1为例,介绍一下16键矩阵键盘的工作原理,P10、P11、P12、P13作为列检测口,P14、P15、P16、P17作为行检测口。假设按键“1”(对应于S2)被按下,找其按键的特征编码,从P10P13输出低电平,从P14P17输出高电平,系统读取P14P17的状态为“0111”,其值为“70H”。然后从P10P13输出高电平,从P14P17输出低电平,系统读取P10P13的状态为“1011”,其值为“0BH”,将两次读出的P0口状态值进行逻辑或运算就得到其按键的特征编码为“7BH”。每个按键其特征编码都不同,所以可以通过这种方法区分16个按键及其键值。8.实验板矩阵键盘硬件电路和操作的说明实验板行扫描线分别连接与PX270的KP_MKOUT0、KP_MKOUT1、KP_MKOUT2、KP_MKOUT6端口相连,列扫描线分别与PX270的KP_MKIN0、KP_MKIN1、KP_MKIN2、KP_MKIN5端口相连。图2PX270支持最大8根行扫描线,8根列扫描线总计64个按键的矩阵键盘,通过对键盘控制寄存器KPC的操作,我们可以自由的定制键盘的扫描工作方式,行扫描线,列扫描线的个数。现在对矩阵键盘驱动中要使用的KPC寄存器主要控制位进行简要的说明(如图3)。图3BIT11:MIE: 矩阵键盘中断使能 1:矩阵键盘中断 0:矩阵键盘不中断BIT12:ME: 矩阵键盘工作模式使能 1:矩阵键盘工作 0:矩阵键盘不工作BIT13BIT20:MS0MS7:行扫描线使能 1:对应的行扫描线工作 0:对应的行扫描线不工作BIT23BIT25:MKCN:行扫描线个数统计 000: 0个 111:7个BIT26BIT28:MKRN:列扫描线个数统计 000: 0个 111:7个BIT29:ASACT:激活矩阵扫描自动扫描过程 1:激活 0:不激活BIT30:AS:矩阵扫描工作模式选择 1:自动扫描 0:手动扫描设置好KPC之后,就可以调用PX270的键盘扫描功能模块进行键值的扫描。现在就实验板实际连接的电路对扫描的键值加以说明。实验板的16键矩阵键盘的行扫描线是KP_MKOUT0、KP_MKOUT1、KP_MKOUT2、KP_MKOUT6,列扫描线是KP_MKIN0、KP_MKIN1、KP_MKIN2、KP_MKIN5,其对应PX270内置的列扫描线位于第0、1、2、6列,对应的行扫描线为0、1、2、5行。以按下16键矩阵键盘的第4行,第4列的按键为例,根据前面对矩阵键盘工作原理的分析可以知道,其对应的键值应该是PX270第6列,第5行所对应的键值。故实验板上16键矩阵键盘的键值如下表所示:第列第一列第二列第六列第行0x00(0,0)0x01(0,1)0x02(0,2)0x06(0,6)第一行0x10(1,0)0x11(1,1)0x12(1,2)0x16(1,6)第二行0x20(2,0)0x21(2,1)0x22(2,2)0x26(2,6)第五行0x50(5,0)0x51(5,1)0x52(5,2)0x56(5,6)表19.16键矩阵键盘驱动程序分析10.编写驱动的测试程序和Makefile文件11. 16键矩阵键盘驱动程序的交叉编译12.驱动程序的移植、注册与测试实验四 Qt编写简单的计算器一、【实验目的】1) 熟悉QtCreator的简单操作。2) 了解Qt程序编写框架。3) 了解信号和槽机制,熟练掌握信号与槽在应用程序中的使用。二、【实验内容】1) 查看API手册,学习简单的Qt类的使用,如QLineEdit、QPushButton等。2) 用QtCreator创建工程,用Qt编写计算器程序。3) 对计算器程序进行移植。三、【实验步骤】1.创建工程2.计算器程序的实现计算器程序主要分以下两部分工作:一是实现计算器的图形界面;二是实现按键事件和该事件对应的功能绑定,即信号和对应处理槽函数的绑定。3.计算器程序源代码的分析说明3.计算器程序在X86上的编译运行4.计算器程序的移植上面所说的可执行程序是由QtCreator调用用X86上的qmake命令生成Makefile文件后调用make命令自动生成。下面将通过交叉编译工具链中的qmake命令生成Makefile文件并用make命令生成ARM上的可执行程序。程序在目标机显示屏中的运行结果如图所示。由于本程序没有集成键盘动作,只能通过鼠标点击按钮来进行操作。可以用目标机显示屏的触屏笔或者连接一个USB口的鼠标进行程序测试。实验五 Webserver的移植一、【实验目的】1) 掌握应用程序移植的一般方法。2) 学习如何使用GoAhead Web服务器。二、【实验内容】1) 修改We

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论