《嵌入式系统综合设计说明书分解.doc》由会员分享,可在线阅读,更多相关《嵌入式系统综合设计说明书分解.doc(32页珍藏版)》请在三一办公上搜索。
1、学校代码: 10128学 号:201120201023嵌入式系统综合设计说明书题 目:智能车系统MP3播放器设计与实现学生姓名:杜继凤 组 员:王嘉敏 杜继凤学 院:信息工程学院班 级:计算机11-2班指导教师:庄旭菲 王晓强 蒋贵良 刘志强 2014 年 3 月 15 日 摘要嵌入式项目T-CAR 智能小车是嵌入式技术和物联网技术结合的产物。TCAR以三星高端微处理器为主控实现主要控制工作,将WIFI 无线通信与ZIGBEE 近距离无线组网通信相结合实现近距离和远程无线控制、信息采集等功能。T-CAR 即可作为互联网终端、物联网网关,也可以和工业控制、智能家居等系统融合使用。本课题目的是在A
2、RM-Linux嵌入式环境下实现网络功能,系统主要由硬件层、内核层、应用层三部分构成。由于Linux具有可移植度高、自由、免费等特性,最近几年,它在移动设备和个人电脑领域的应用也越来越广泛,因此我们选择Linux操作系统,鉴于以上应用领域对用户界面友好性方面的要求,几乎所有的此类应用都是采用图形用户界面。播放界面采用Qt设计,Qt是创造图形用户界面的最流行的跨平台GUI工具箱之一。这里将通过一个使用Qt技术的简单mp3播放器的实现,详细描述Linux环境下的图形界面编程技术。本实训课程是嵌入式应用开发方向的实训课程,主要介绍嵌入式应用程序的开发技术,课程内容涉及C 语法及核心库、嵌入式Linu
3、x 开发环境、嵌入式Linux应用开发流程。在内容组织上,以案例贯穿课程的始终。通过一系列案例的学习使学员能基本掌握嵌入式Linux 应用程序开发的基本技术,能开发出有图形界面,可交互,具有一定业务逻辑的嵌入式Linux 应用程序。关键字:嵌入式;QT;mp3播放器;目录前言1第一章概述21.1课程设计目的21.2课程背景与要求21.2.1课程设计背景21.2.2课程设计要求31.3课程设计环境3第二章设计方案42.1设计功能42.2 设计思路4第三章 软件设计53.1模块流程图53.2 Madplay 移植63.3程序清单63.3.1音乐播放器服务器程序实现63.3.2音乐播放器客户端程序实
4、现19第四章 调试过程244.1硬件连接244.2软件连接244.2.1 操作系统244.2.2 系统软件244.2.3 工具软件244.2.4 文档和资源254.3实验步骤254.4 出现的问题和解决方法254.5运行结果截屏26第五章 总结28参考文献29前言随着社会的日益信息化,计算机和网络已经全面渗透到日常生活的每一个角落。对于我们每个人来说,需要的已经不再仅仅是那种放在桌上处理文档、进行工作管理和生产控制的计算机机器。任何一个普通人都可能拥有从小到大的各种使用嵌入式技术的电子产品,小到MP3、PDA等微型数字化产品,大到网络家电、智能家电、车载电子设备等。目前,各种各样的新型嵌入式系
5、统设备在应用数量上已经远远超过了通用计算机。在工业和服务领域中,使用嵌入式技术的数字机床、智能工具、工业机器人、服务机器人正在逐渐改变着传统的工业生产和服务方式。MP3是嵌入式的最主要应用之一,高端的MP3已经不仅仅着眼于实现音乐播放这一简单功能,而是同时具备了文本浏览、图片浏览、甚至视频播放等强大功能。本文重点讨论了基于WIFI 智能车的控制系统为主其中MP3的功能的实现,包括开发环境建立、内核配置与编译、Qt开发等一系列详细过程。近几年,嵌入式系统技术得到了广泛的应用,普适计算、无线传感器网络、可重构计算等新兴技术的出现又为嵌入式系统技术的研究与应用注入了新的活力。智能手机、信息家电、汽车
6、电子、家用机器人嵌入式系统已“无处不在”。嵌入式系统是当今最热门的概念之一。作为一个系统,往往是在硬件和软件双螺旋式交替发展的支撑下逐渐趋于稳定和成熟,嵌入式系统也不例外。第一章 概述嵌入式项目T-CAR 智能小车是嵌入式技术和物联网技术结合的产物。TCAR以三星高端微处理器为主控实现主要控制工作,将WIFI 无线通信与ZIGBEE 近距离无线组网通信相结合实现近距离和远程无线控制、信息采集等功能。T-CAR 即可作为互联网终端、物联网网关,也可以和工业控制、智能家居等系统融合使用。1.1课程设计目的嵌入式系统设计与实践课程设计介绍基本设计与实现方法,是为计算机科学与技术专业本科生开设的一门重
7、要的专业课程。是对以前所学很多知识的汇总和深化。通过三周的设计,能把以前很多所学的理论联系实际,培养学生的实验动手能力和创新意识,使学生对嵌入式系统有更全面的认识,掌握嵌入式系统的设计与开发的方法,为将来进行嵌入式应用系统的设计与开发奠定基础。1.2课程背景与要求1.2.1课程设计背景物联网是一个基于互联网、 传统电信网等信息承载体, 让所有能够被独立寻址的普通物理对象实现互联互通的网络。物联网通过智能感知、识别技术与普适计算、泛在网络的融合应用,被称为继计算机、互联网之后世界信息产业发展的第三次浪潮。物联网被视为互联网的应用拓展,应用创新是物联网发展的核心,以用户体验为核心的创新 2.0 是
8、物联网发展的灵魂。随着物联网的发展,越来越多的物联网控制终端将涌现,对于相关技术的学习需求和基于该领域的就业机会将大增,本智能车就是在此前提下诞生的。该智能车具有很强的操控性、可玩性,同时融入嵌入式物联网相关技术,使学员可在相对轻松愉悦的环境中学习各种技术,让嵌入式技术的学习变得不在枯燥。本车设计之初既考虑了可产品化空间,也考虑了技术知识点的涵盖,使学习更能明确目标;同时本项目在选材上也考虑了项目的手工打造的可能性,意在锻炼学员的动手实践能力,只要学习者有兴趣,即可按所提供的材料清单和学习的相关技术自行打造,我们更希望能培养学习者的创客精神和创业欲望与意识。1.2.2课程设计要求要求采用C/S
9、架构,完成对网络音乐播放器软件的分析、设计、编码、测试等工作。音乐播放器功能说明:服务器实现完整的音乐播放器功能,客户端通过网络实现控制操作。包括如下:1、Madplay音乐播放器移植。2、音乐播放器服务器设计,通过网络接收客户端请求并执行对应动作,实现音乐播放、暂停、上一首、下一首、播放列表、停止等功能;3、QT客户端界面设计,要求利用qt设计控制客户端界面,实现通过网络向服务器发送命令请求等功能。1.3课程设计环境环境要求:操作系统:windows 7+ubuntu虚拟系统 平台:vim编辑器,GNU工具链,Qtcreator集成开发环境开发语言:C/C+文档环境:windows offi
10、ce第二章 设计方案2.1设计功能音乐播放器功能说明:服务器实现完整的音乐播放器功能,客户端通过网络实现控制操作。包括如下:1、Madplay音乐播放器移植;2、音乐播放器服务器设计,通过网络接收客户端请求并执行对应动作,实现音乐播放、暂停、上一首、下一首、播放列表、停止等功能;3、QT客户端界面设计,要求利用qt设计控制客户端界面,实现通过网络向服务器发送命令请求等功能。2.2 设计思路1、开发环境搭建,虚拟机配置相关vim编辑器,gcc编译器等相关软件配置。2、madplay音乐播放器移植,包括libmad音频解码库的使用,所以首先需要移植madplay,具体方法如下:1)创建安装库的路径
11、 sudo mkdir /opt/arm/madplay/lib2)进入madplay 源码目录 执行./build3 ) 测试将madplay 和库文件复制到根文件系统, 配置LD_LIBRARY_PATH,执行madplay xxx.mp3。3、服务器端程序设计,采用C语言在Linux环境在完成音乐播放器功能。4、利用Qtcreator设计客户端界面,实现向服务器发送控制命令等功能第三章 软件设计3.1模块流程图播放Filename是否为空获取播放文件信息:播放歌曲、当前播放位置等。开始播放激活进度条TimeSlider显示时间长度、当前播放位置及文件名称是否停止播放是否暂停停止播放暂停播
12、放图1.1模块流程图3.2 Madplay 移植1) 首先建立一个mp3 文件夹,进入到mp3 文件夹后再建立两个文件夹,一个存放源码,一个存放安装文件。在home 下,mkdir 两个文件夹:madplay-src、madplay。依次解压四个源码包到madplay 目录下:tar zxvf XXX.tar.gz(2) 编译zlib-1.1.4进入zlib 源文件目录,依此执行./configure9 / 26make make install(3) 编译libid3tag进入tag 源码目录,依此执行./configure make make install(4) 编译libmad进入li
13、bmad 源码,依此执行./configuremake注:使用的是高版本的ARM-LINUX-GCC 如4.4.6 编译器,MAKE 时可能会出现”CCL:ERROR:UNRECOGNIZED COMMAND LINE OPTION “-FFORCE-MEM”错误,这是因为这个高版本的GCC 没有”-FFORCEMEM”参数,解决的办法是在LIBMAD 文件中的MAKEFILE 里面查找”-FFORCE-MEM”,将其删除即可 make install(5) 编译madplay进入madplay 源码目录,依此执行./configure -with alsa make make install
14、(6) 测试madplay执行命令(配置环境变量):export LD_LIBRARY_PATH=$LD_LIBRARY_PATH/usr/local/lib运行:madplay xx.mp33.3程序清单3.3.1音乐播放器服务器程序实现1.player.c#include common.h#include socket.h#include player.h/*孙子进程id 号*/pid_t gradchild;/*子进程id 号*/pid_t pid;/*共享内存描述标记*/int shmid;char *p_addr;/*共享内存内容格式*/*|gradchild(孙子进程PID) |+
15、 |空一个字节|+ currentsong(当前播放列表的节点指针)|*/*listhead for music*/struct song* head;/*创建歌曲名的双向循环链表*/struct song *creat_song_list(void)FILE *fd;ssize_t size;size_t len;char *line = NULL;struct song *p1;struct song *p2;int res=system(ls ./song song_list);if(res = -1) perror(system);fd = fopen(song_list,rb);if
16、(fd=NULL)perror(fopen);p1 = (struct song *)malloc(sizeof(struct song);printf(=songlist=n);res=system(ls ./song);if(res = -1) perror(system);printf(n);printf(=n);size = getline(&line,&len,fd);strncpy(p1-songname,line,strlen(line);head = p1;int n=strlen(line);(head-songname)n=0;while(size = getline(&l
17、ine,&len,fd) != -1) /从文件中读取一行,直到出错或者到文件尾EOF 返回-1p2 = p1;p1 = (struct song *)malloc(sizeof(struct song);strncpy(p1-songname,line,strlen(line);p2-next = p1;p1-prev = p2;int n=strlen(line);(p1-songname)n=0;p1-next = head;head-prev = p1;p1 = NULL;p2 = NULL;res=system(rm -rf song_list);if(res = -1) perro
18、r(system);return head;/*MP3 音乐播放器-播放音乐函数*/void play(struct song *currentsong)pid_t newfd;char *c_addr;void *tempaddr;char *p;int len;char my_song2048=./song/;while(currentsong)printf(currentsong size=%dn,strlen(currentsong-songname);/*子进程创建孙子进程*/newfd = fork();if(newfd = -1)perror(fork);exit(1);else
19、 if(newfd = 0) /孙子进程printf(play fork success!n);/*把歌曲名加上根路径*/strcat(my_song,currentsong-songname);p = my_song;len = strlen(p);/*去掉文件名最后的0*/my_songlen-1=0;printf(THIS SONG IS %s size=%dn,my_song,strlen(my_song);/*运行madplay 播放器,播放MP3*/execl(/usr/local/sbin/madplay,madplay,my_song,NULL);/播放当前列表MP3 音乐pr
20、intf(nnn);else /子进程/*内存映射*/tempaddr = shmat(shmid,0,0);c_addr = (char *)tempaddr;/*把孙子进程的id 和当前播放歌曲的节点指针传入共享内存*/memcpy(c_addr,&newfd,sizeof(pid_t);memcpy(c_addr + sizeof(pid_t)+1,¤tsong,4);/*使用wait 阻塞子进程,直到孙子进程播放完才能被唤醒;当被唤醒时,表示播放MP3 期间没有按键按下,则继续顺序播放下一首MP3*/if(newfd = wait(NULL)currentsong = cu
21、rrentsong-next;printf(THE NEXT SONG IS %sn,currentsong-songname);/*MP3 音乐播放器-调用play 函数播放音乐*/void startplay(pid_t *childpid,struct song *my_song)pid_t pid;/如果没有音乐正在播放并且不是处于暂停状态if(play_flag = 0) & (play_pause_flag != 1)play_flag = 1;play_stop_flag = 0;/*创建子进程*/pid = fork();if(pid 0) /父进程*childpid = pi
22、d; /子进程PID 初始化sleep(1);/*读取共享内存保存的pid,初始化孙子进程的pid*/*p_addr 指向共享内存,保存的是孙子进程的ID*/memcpy(&gradchild,p_addr,sizeof(pid_t);else if(0 = pid) /子进程/*子进程播放MP3 函数*/play(my_song);/如果没有音乐正在播放并处于暂停状态else if(play_flag = 0) & (play_pause_flag = 1)play_flag = 1;play_pause_flag = 0;conti_play(gradchild);elsereturn;/
23、*MP3 音乐播放器-暂停播放*/void my_pause(pid_t pid)if(play_flag = 1) & (play_pause_flag = 0)printf(=PAUSE!PRESS PLAY TOCONTINUE=n);kill(pid,SIGSTOP); /对孙子进程发送SIGSTOP 信号play_pause_flag = 1;play_flag = 0;elsereturn;/*MP3 音乐播放器-继续播放*/void conti_play(pid_t pid)printf(=CONTINUE=n);kill(pid,SIGCONT); /对孙子进程发送SIGCON
24、T 信号/*MP3 音乐播放器-播放下一首*/*只有正在播放音乐的状态下,上一首和下一首才有作用*/void next(pid_t next_pid)int res;if(play_flag = 0)return;elsestruct song *nextsong;printf(=NEXTMP3=n);/*从共享内存获得孙子进程播放歌曲的节点指针*/memcpy(&nextsong,p_addr + sizeof(pid_t)+1,4);/*指向下首歌曲的节点*/nextsong = nextsong-next;/*杀死当前歌曲播放的子进程,孙子进程*/res = kill(pid,SIGKI
25、LL);if(res = -1)perror(kill next pid error);return;res = kill(next_pid,SIGKILL);if(res = -1)perror(kill next next_pid error);res=system(killall madplay);if(res = -1) perror(system);/wait(NULL);play_flag = 0;startplay(&pid,nextsong);/*MP3 音乐播放器-播放上一首*/void prev(pid_t prev_pid)int res;if(play_flag = 0
26、)return;else struct song *prevsong;/*从共享内存获得孙子进程播放歌曲的节点指针*/printf(=PRIORMP3=n);memcpy(&prevsong,p_addr + sizeof(pid_t)+1,4);/*指向上首歌曲的节点*/prevsong = prevsong-prev;/*杀死当前歌曲播放的子进程,孙子进程*/res = kill(pid,SIGKILL);if(res = -1)perror(kill prev pid error);return;res = kill(prev_pid,SIGKILL);if(res = -1)perro
27、r(kill prev prev_pid error);res=system(killall madplay);if(res = -1) perror(system);/wait(NULL);play_flag = 0;startplay(&pid,prevsong);/*MP3 音乐播放器-停止播放*/void my_stop(pid_t g_pid)int res;if(play_stop_flag = 1)/如果已经停止,直接返回return;if(play_flag = 1) | (play_pause_flag = 1)printf(=STOP!PRESS PLAY TOSTART=
28、n);res = kill(pid,SIGKILL); /对子进程发送SIGKILL 信号if(res = -1)perror(stop pid error);return;res = kill(g_pid,SIGKILL); /对孙子进程发送SIGKILL 信号if(res = -1)perror(stop g_pid error);res=system(killall madplay);if(res = -1) perror(system);play_flag = 0;play_stop_flag = 1;play_pause_flag = 0;elsereturn;/*MP3 音乐播放器
29、-播放列表*/*搜索列表音乐名字与歌曲相匹配,并杀死正在播放歌曲进程而播放对应列表音乐*/void playlist(pid_t childpid,char *listsong)int res;play_flag = 0;if(strncmp(head-songname,listsong,4) = 0)res = kill(pid,SIGKILL);if(res = -1)perror(playlist kill pid error);return;res = kill(childpid,SIGKILL);if(res = -1)perror(playlist kill childpid er
30、ror);res=system(killall madplay);if(res = -1) perror(system);wait(NULL);startplay(&pid,head);return ;struct song *nextsong=head-next;doif(strncmp(nextsong-songname,listsong,4)=0)res = kill(pid,SIGKILL);if(res = -1)perror(playlist kill pid error);return;res = kill(childpid,SIGKILL);if(res = -1)perror
31、(playlist kill childpid error);res=system(killall madplay);if(res = -1) perror(system);wait(NULL);startplay(&pid,nextsong);return;nextsong=nextsong-next;while(nextsong!=head);/*接收客户端命令*/void recvcmd(void)int cmd=0;char bufSIZE;memset(buf,0,sizeof(buf);while(1)int len = recvfrom(server_sockfd,&cmd,4,
32、0,(structsockaddr*)&server_addr,&sin_size);if(len0)printf(recv listbuf = %sn,buf);playlist(gradchild,buf);break;default:puts(not find the cmd!);break;int main()/*创建播放列表*/head=creat_song_list();/*共享内存:用于存放子进程ID,播放列表位置*/void *tempaddr;if(shmid = shmget(IPC_PRIVATE,5,PERM)= -1)perror(shmget);tempaddr =
33、 shmat(shmid,0,0);if(tempaddr = (void *)-1)perror(shmat);p_addr = (char *)tempaddr;memset(p_addr,0,1024);/*初始化MP3 播放停止标志*/play_flag=0;play_stop_flag=0;play_pause_flag=0;/初始化网络int res=create_socket();if(res0)perror(create_socket);/接收控制命令(死循环);recvcmd();return 0;2.play.h#ifndef PLAYER_H#define PLAYER_
34、H/*共享内存申请标记*/#define PERM S_IRUSR|S_IWUSR#define SIZE 1024struct songchar songname1024;struct song *prev;struct song *next;char *playsong;/*播放标记*/int play_flag;int play_stop_flag;int play_pause_flag;/*保存接收到的字符串(推送过来的消息)*/char temp_str100;unsigned int pos;extern void play(struct song *currentsong);ex
35、tern struct song *creat_song_list(void);extern void startplay(pid_t *childpid,struct song *my_song);extern void my_pause(pid_t pid);extern void my_stop(pid_t g_pid);extern void conti_play(pid_t pid);extern void next(pid_t next_pid);extern void prev(pid_t prev_pid);extern void playlist(pid_t childpid
36、,char *listsong);#endif3.socket.c#include socket.hint server_sockfd;socklen_t sin_size;struct sockaddr_in server_addr;struct sockaddr_in client_addr;int create_socket()memset(&server_addr, 0, sizeof(server_addr);/* 初始化网络信息*/server_addr.sin_family = AF_INET; /设置为IP 通信server_addr.sin_addr.s_addr = INA
37、DDR_ANY; /无限制server_addr.sin_port = htons(8000);if (server_sockfd = socket(PF_INET,SOCK_DGRAM,0) 0) return -1;if(bind(server_sockfd, (struct sockaddr *)&server_addr,sizeof(struct sockaddr) 0) return -1;return 1;sin_size = sizeof(struct sockaddr_in);4.socket.h#ifndef SOCKET_H#define SOCKET_H#include
38、common.h#define PLAY 11#define PAUSE 12#define STOP 13#define CONTINUE 14#define NEXT 15#define PREV 16#define LISTSONG 18extern int server_sockfd;extern socklen_t sin_size;extern struct sockaddr_in server_addr;extern struct sockaddr_in client_addr;extern int create_socket();#endifmon.h#ifndef _COMM
39、ON_H#define _COMMON_H#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ERROR -1#endif6.makefilename
40、=*.cBIN=playerFLAGS=-g -O2 -Walldefault:gcc $(FLAGS) $(name) -o $(BIN)_3.3.2音乐播放器客户端程序实现1,player.cpp#include player.h#include ui_player.h#include listmusic.h#include socket.hplayer:player(QWidget *parent) :QDialog(parent),ui(new Ui:player)ui-setupUi(this);init_socket();player:player()delete ui;void player:on_play_clicked()int cmd = 0;int len;cmd = PLAY;len=sendto(client_sockfd, &cmd, 4,0, (struct sockaddr *)&client_addr,sin_size);if (len 0) QMessageBox:question(this, tr(结果),QString(tr(发送网络数据失败);return;void player:on_pause_clicked()int cmd = PAUSE;int