收藏 分销(赏)

嵌入式系统综合设计说明书分解.doc

上传人:精**** 文档编号:3771874 上传时间:2024-07-17 格式:DOC 页数:32 大小:867.50KB 下载积分:12 金币
下载 相关 举报
嵌入式系统综合设计说明书分解.doc_第1页
第1页 / 共32页
嵌入式系统综合设计说明书分解.doc_第2页
第2页 / 共32页


点击查看更多>>
资源描述
学校代码: 10128 学 号:201120201023 嵌入式系统综合设计说明书 题 目:智能车系统—MP3播放器设计与实现 学生姓名:杜继凤 组 员:王嘉敏 杜继凤 学 院:信息工程学院 班 级:计算机11-2班 指导教师:庄旭菲 王晓强 蒋贵良 刘志强 2014 年 3 月 15 日 摘要 嵌入式项目T-CAR 智能小车是嵌入式技术和物联网技术结合的产物。TCAR以三星高端微处理器为主控实现主要控制工作,将WIFI 无线通信与ZIGBEE 近距离无线组网通信相结合实现近距离和远程无线控制、信息采集等功能。T-CAR 即可作为互联网终端、物联网网关,也可以和工业控制、智能家居等系统融合使用。 本课题目的是在ARM-Linux嵌入式环境下实现网络功能,系统主要由硬件层、内核层、应用层三部分构成。由于Linux具有可移植度高、自由、免费等特性,最近几年,它在移动设备和个人电脑领域的应用也越来越广泛,因此我们选择Linux操作系统,鉴于以上应用领域对用户界面友好性方面的要求,几乎所有的此类应用都是采用图形用户界面。播放界面采用Qt设计,Qt是创造图形用户界面的最流行的跨平台GUI工具箱之一。这里将通过一个使用Qt技术的简单mp3播放器的实现,详细描述Linux环境下的图形界面编程技术。 本实训课程是嵌入式应用开发方向的实训课程,主要介绍嵌入式应用程序的开发技术,课程内容涉及C 语法及核心库、嵌入式Linux 开发环境、嵌入式Linux应用开发流程。在内容组织上,以案例贯穿课程的始终。通过一系列案例的学习使学员能基本掌握嵌入式Linux 应用程序开发的基本技术,能开发出有图形界面,可交互,具有一定业务逻辑的嵌入式Linux 应用程序。 关键字:嵌入式;QT;mp3播放器; 目录 前言 1 第一章 概述 2 1.1课程设计目的 2 1.2课程背景与要求 2 1.2.1课程设计背景 2 1.2.2课程设计要求 3 1.3课程设计环境 3 第二章 设计方案 4 2.1设计功能 4 2.2 设计思路 4 第三章 软件设计 5 3.1模块流程图 5 3.2 Madplay 移植 6 3.3程序清单 6 3.3.1音乐播放器服务器程序实现 6 3.3.2音乐播放器客户端程序实现 19 第四章 调试过程 24 4.1硬件连接 24 4.2软件连接 24 4.2.1 操作系统 24 4.2.2 系统软件 24 4.2.3 工具软件 24 4.2.4 文档和资源 25 4.3实验步骤 25 4.4 出现的问题和解决方法 25 4.5运行结果截屏 26 第五章 总结 28 参考文献 29 前言 随着社会的日益信息化,计算机和网络已经全面渗透到日常生活的每一个角落。对于我们每个人来说,需要的已经不再仅仅是那种放在桌上处理文档、进行工作管理和生产控制的计算机机器。任何一个普通人都可能拥有从小到大的各种使用嵌入式技术的电子产品,小到MP3、PDA等微型数字化产品,大到网络家电、智能家电、车载电子设备等。目前,各种各样的新型嵌入式系统设备在应用数量上已经远远超过了通用计算机。在工业和服务领域中,使用嵌入式技术的数字机床、智能工具、工业机器人、服务机器人正在逐渐改变着传统的工业生产和服务方式。 MP3是嵌入式的最主要应用之一,高端的MP3已经不仅仅着眼于实现音乐播放这一简单功能,而是同时具备了文本浏览、图片浏览、甚至视频播放等强大功能。本文重点讨论了基于WIFI 智能车的控制系统为主其中MP3的功能的实现,包括开发环境建立、内核配置与编译、Qt开发等一系列详细过程。 近几年,嵌入式系统技术得到了广泛的应用,普适计算、无线传感器网络、可重构计算等新兴技术的出现又为嵌入式系统技术的研究与应用注入了新的活力。智能手机、信息家电、汽车电子、家用机器人……嵌入式系统已“无处不在”。嵌入式系统是当今最热门的概念之一。 作为一个系统,往往是在硬件和软件双螺旋式交替发展的支撑下逐渐趋于稳定和成熟,嵌入式系统也不例外。 第一章 概述 嵌入式项目T-CAR 智能小车是嵌入式技术和物联网技术结合的产物。TCAR以三星高端微处理器为主控实现主要控制工作,将WIFI 无线通信与ZIGBEE 近距离无线组网通信相结合实现近距离和远程无线控制、信息采集等功能。T-CAR 即可作为互联网终端、物联网网关,也可以和工业控制、智能家居等系统融合使用。 1.1课程设计目的 嵌入式系统设计与实践课程设计介绍基本设计与实现方法,是为计算机科学与技术专业本科生开设的一门重要的专业课程。是对以前所学很多知识的汇总和深化。通过三周的设计,能把以前很多所学的理论联系实际,培养学生的实验动手能力和创新意识,使学生对嵌入式系统有更全面的认识,掌握嵌入式系统的设计与开发的方法,为将来进行嵌入式应用系统的设计与开发奠定基础。 1.2课程背景与要求 1.2.1课程设计背景 物联网是一个基于互联网、 传统电信网等信息承载体, 让所有能够被独立寻址的普通物理对象实现互联互通的网络。物联网通过智能感知、识别技术与普适计算、泛在网络的融合应用,被称为继计算机、互联网之后世界信息产业发展的第三次浪潮。物联网被视为互联网的应用拓展,应用创新是物联网发展的核心,以用户体验为核心的创新 2.0 是物联网发展的灵魂。随着物联网的发展,越来越多的物联网控制终端将涌现,对于相关技术的学习需求和基于该领域的就业机会将大增,本智能车就是在此前提下诞生的。 该智能车具有很强的操控性、可玩性,同时融入嵌入式物联网相关技术,使学员可在相对轻松愉悦的环境中学习各种技术,让嵌入式技术的学习变得不在枯燥。 本车设计之初既考虑了可产品化空间,也考虑了技术知识点的涵盖,使学习更能明确目标;同时本项目在选材上也考虑了项目的手工打造的可能性,意在锻炼学员的动手实践能力,只要学习者有兴趣,即可按所提供的材料清单和学习的相关技术自行打造,我们更希望能培养学习者的创客精神和创业欲望与意识。 1.2.2课程设计要求 要求采用C/S架构,完成对网络音乐播放器软件的分析、设计、编码、测试等工作。 音乐播放器功能说明:服务器实现完整的音乐播放器功能,客户端通过网络实现控制操作。 包括如下: 1、Madplay音乐播放器移植。 2、音乐播放器服务器设计,通过网络接收客户端请求并执行对应动作,实现音乐播放、暂停、上一首、下一首、播放列表、停止等功能; 3、QT客户端界面设计,要求利用qt设计控制客户端界面,实现通过网络向服务器发送命令请求等功能。 1.3课程设计环境 环境要求:操作系统:windows 7+ubuntu虚拟系统 平台:vim编辑器,GNU工具链,Qtcreator集成开发环境 开发语言:C/C++ 文档环境:windows office 第二章 设计方案 2.1设计功能 音乐播放器功能说明:服务器实现完整的音乐播放器功能,客户端通过网络实现控制操作。 包括如下: 1、Madplay音乐播放器移植; 2、音乐播放器服务器设计,通过网络接收客户端请求并执行对应动作,实现音乐播放、暂停、上一首、下一首、播放列表、停止等功能; 3、QT客户端界面设计,要求利用qt设计控制客户端界面,实现通过网络向服务器发送命令请求等功能。 2.2 设计思路 1、开发环境搭建,虚拟机配置相关vim编辑器,gcc编译器等相关软件配置。 2、madplay音乐播放器移植,包括libmad音频解码库的使用,,所以首先需要移植madplay,具体方法如下: 1)创建安装库的路径 sudo mkdir /opt/arm/madplay/lib 2)进入madplay 源码目录 执行./build 3 ) 测试将madplay 和库文件复制到根文件系统, 配置LD_LIBRARY_PATH,执行madplay xxx.mp3。 3、服务器端程序设计,采用C语言在Linux环境在完成音乐播放器功能。 4、利用Qtcreator设计客户端界面,实现向服务器发送控制命令等功能 第三章 软件设计 3.1模块流程图 播放 Filename 是否为空 获取播放文件信息:播放歌曲、当前播放位置等。 开始播放 激活进度条TimeSlider 显示时间长度、当前播放位置及文件名称 是否停 止播放 是否暂停 停止播放 暂停播放 图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 进入libmad 源码,依此执行./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 (6) 测试madplay 执行命令(配置环境变量):export LD_LIBRARY_PATH =$LD_LIBRARY_PATH/usr/local/lib 运行:madplay xx.mp3 3.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) |+ |空一个字节|+ 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(fd==NULL){ perror("fopen");} p1 = (struct song *)malloc(sizeof(struct song)); printf("==================================song list=====================================\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(&line,&len,fd)) != -1) //从文件中读取一行,直到出错或者到文件尾EOF 返回-1 {p2 = 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) perror("system"); return head;}/*MP3 音乐播放器-->播放音乐函数*/ void play(struct song *currentsong) {pid_t newfd; char *c_addr; void *tempaddr; char *p; int len; char my_song[2048]="./song/"; while(currentsong) {printf("currentsong size=%d\n",strlen(currentsong->songname));/*子进程创建孙子进程*/ newfd = fork(); if(newfd == -1) {perror("fork"); exit(1);} else if(newfd == 0) //孙子进程 {printf("play fork success!\n");/*把歌曲名加上根路径*/ strcat(my_song,currentsong->songname); p = my_song; len = strlen(p);/*去掉文件名最后的'\0'*/ my_song[len-1]='\0'; printf("THIS SONG IS %s size=%d\n",my_song,strlen(my_song)); /*运行madplay 播放器,播放MP3*/ execl("/usr/local/sbin/madplay","madplay",my_song,NULL);//播放当前列表MP3 音乐 printf("\n\n\n");} 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,&currentsong,4);/*使用wait 阻塞子进程,直到孙子进程播放完才能被唤醒;当被唤醒时,表示播放MP3 期间没有按键按下,则继续顺序播放下一首MP3*/ if(newfd == wait(NULL)) {currentsong = currentsong->next; printf("THE NEXT SONG IS %s\n",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 = pid; //子进程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);} else return;} /*MP3 音乐播放器-->暂停播放*/ void my_pause(pid_t pid) {if((play_flag == 1) && (play_pause_flag == 0)){ printf("=======================PAUSE!PRESS PLAY TO CONTINUE===================\n"); kill(pid,SIGSTOP); //对孙子进程发送SIGSTOP 信号 play_pause_flag = 1; play_flag = 0;} else return;} /*MP3 音乐播放器-->继续播放*/ void conti_play(pid_t pid) {printf("===============================CONTINUE=============================\n"); kill(pid,SIGCONT); //对孙子进程发送SIGCONT 信号} /*MP3 音乐播放器-->播放下一首*/ /*只有正在播放音乐的状态下,上一首和下一首才有作用*/ void next(pid_t next_pid) {int res; if(play_flag == 0){ return;} else{ struct song *nextsong; printf("===============================NEXTMP3=============================\n"); /*从共享内存获得孙子进程播放歌曲的节点指针*/ memcpy(&nextsong,p_addr + sizeof(pid_t)+1,4); /*指向下首歌曲的节点*/ nextsong = nextsong->next; /*杀死当前歌曲播放的子进程,孙子进程*/ res = kill(pid,SIGKILL); 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){ 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){ perror("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 TO START===================\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;} else return;} /*MP3 音乐播放器-->播放列表*/ /*搜索列表音乐名字与歌曲相匹配,并杀死正在播放歌曲进程而播放对应列表音乐*/ 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 error"); res=system("killall madplay"); if(res == -1) perror("system");} wait(NULL); startplay(&pid,head); return ;} struct song *nextsong=head->next; do{ if(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("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 buf[SIZE]; memset(buf,0,sizeof(buf)); while(1){ int len = recvfrom(server_sockfd,&cmd,4,0,(struct sockaddr*)&server_addr,&sin_size); if(len<0){ continue;} switch (cmd){ case PLAY: startplay(&pid,head); break; case PAUSE: my_pause(gradchild); break; case STOP: my_stop(gradchild); break; case NEXT: next(gradchild); break; case PREV: prev(gradchild); break; case LISTSONG: memset(buf,0,sizeof(buf)); len=recvfrom(server_sockfd,buf,sizeof(buf),0,(struct sockaddr*)&client_addr,&sin_size); if(len>0){ printf("recv listbuf = %s\n",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 = 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(res<0){ perror("create_socket");} //接收控制命令(死循环); recvcmd(); return 0;} 2.play.h #ifndef PLAYER_H #define PLAYER_H /*共享内存申请标记*/ #define PERM S_IRUSR|S_IWUSR #define SIZE 1024 struct song {char songname[1024]; struct song *prev; struct song *next;}; char *playsong; /*播放标记*/ int play_flag; int play_stop_flag; int play_pause_flag; /*保存接收到的字符串(推送过来的消息)*/ char temp_str[100]; unsigned int pos; extern void play(struct song *currentsong); extern 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,char *listsong); #endif 3.socket.c #include "socket.h" int 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 = INADDR_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 "common.h" #define PLAY 11 #define PAUSE 12 #define STOP 13 #define CONTINUE 14 #define NEXT 15 #define PREV 16 #define LISTSONG 18 extern int server_sockfd; extern socklen_t sin_size; extern struct sockaddr_in server_addr; extern struct sockaddr_in client_addr; extern int create_socket(); #endif mon.h #ifndef __COMMON_H #define __COMMON_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <linux/input.h> #include <termios.h> #include <signal.h> #include <sys/select.h> #include <errno.h> #include <sys/wait.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h> #define ERROR -1 #endif 6.makefile name=*.c BIN=player FLAGS=-g -O2 -Wall default:gcc $(FLAGS) $(name) -o $(BIN)__ 3.3.2音乐播放器客户端程序实现 1,player.cpp #include "player.h" #include "ui_player.h" #include "listmusic.h" #include "socket.h" player::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
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 应用文书 > 技术指导

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服