华北电力大学科技学院嵌入式实验报告.docx
- 文档编号:6202436
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:29
- 大小:99.42KB
华北电力大学科技学院嵌入式实验报告.docx
《华北电力大学科技学院嵌入式实验报告.docx》由会员分享,可在线阅读,更多相关《华北电力大学科技学院嵌入式实验报告.docx(29页珍藏版)》请在冰豆网上搜索。
华北电力大学科技学院嵌入式实验报告
科技学院
课程设计(综合实验)报告
(2014--2015年度第1学期)
名称:
嵌入式系统
题目:
嵌入式实验报告
院系:
信息工程系
班级:
学号:
学生姓名:
指导教师:
郭军
设计周数:
5周
成绩:
日期:
2014年12月11日
实验一熟悉Linux开发环境
1、实验目的
熟悉Linux开发环境,学会基于S3C2410的Linux开发环境的配置和使用。
使用Linux的armv4l-unknown-linux-gcc编译,使用基于NFS方式的下载调试,了解嵌入式开发的基本过程。
2、实验内容及工具(包括软件调试工具)
本次实验使用Redhatlinux9.0操作系统环境安装ARMLinux的开发库及编译器。
新建一个目录,编写hello.c和makefile文件。
学习在linux下的编程和编译过程,以及ARM开发板的使用和开发环境的设置。
下载已经编译好的文件到嵌入式控制器中运行。
硬件:
UP-NETARM2410-S嵌入式实验仪、PC机Pentumn500以上,硬盘10G以上。
软件:
PC机操作系统REDHATLINUX9.0+MINICOM+AMRLINUX开发环境。
三、实验步骤
1.建立工作目录
mkdirhello
cdhello
2.编写程序源代码
在LINUX下的文本编辑器有许多,常用的是vim,Xwindow界面下的gedit等,我们在开发过程中推荐使用vim,用户需要学习vim的操作方法,实际的hello.c源代码较简单。
如下:
#include
main()
{
printf(“helloworld\n”);
}
3.编写Makefile
CC=armv4l-unknown-linux-gcc
EXEC=hello
OBJS=hello.o
CFLAGS+=
LDFLAGS+=-elf2flt–static
all:
$(EXEC)
$(EXEC):
$(OBJS)
$(CC)$(LDFLAGS)-o$@$(OBJS)
clean:
-rm-f$(EXEC)*.elf*.gdb*.o
这个makefile显示了几个主要的部分:
●CC指明编译器的宏。
●EXEC表示生成的执行文件名称的宏。
●OBJS目标文件列表宏。
●CFLAGS编译参数宏。
●LDFLAGS连接参数宏。
●all:
编译主入口。
●clean:
清除编译结果节。
注意:
“$(CC)$(LDFLAGS)-o$@$(OBJS)”和“-rm-f$(EXEC)*.elf*.gdb*.o”前空白由一个Tab制表符生成,不能单纯由空格来代替。
4.编译应用程序
在hello目录下运行make,如果进行了修改,重新编译则运行:
makeclean
make
注意编译、修改程序都是在开发计算机上进行,不要在MINICOM的终端方式下进行。
5.下载调试
在宿主PC计算机上启动NFS服务,并设置好共享的目录,之后在开发板上运行:
mount-tnfs192.168.0.10:
/arm2410/host(实际IP地址要根据实际情况修改。
)
挂接宿主机的根目录。
成功之后在开发板上进入/host目录便相应进入宿主机的/arm2410目录,再进入开发程序目录运行刚刚编译好的hello程序,查看运行结果。
开发板挂接宿主计算机目录只需要挂接一次便可,只要开发板没有重起,就可以一直保持连接。
这样可以反复修改、编译、调试,不需要下载到开发板的过程。
实验二、多线程应用程序设计
一、实验目的
1.了解多线程程序设计的基本原理。
2.学习pthread库函数的使用。
二、实验内容
读懂pthread.c的源代码,熟悉几个重要的PTHREAD库函数的使用。
掌握共享锁和信号量的使用方法。
进入/arm2410/exp/basic/02_pthread目录,运行make产生pthread程序,使用NFS方式连接开发主机进行运行实验。
三、实验设备及工具
硬件:
UP-NETARM2410-S嵌入式实验仪,PC机pentumn500以上,硬盘40G以上,内存大于128M。
软件:
PC机操作系统REDHATLINUX9.0+MINICOM+AMRLINUX开发环境。
四、实验原理
1.多线程程序的优缺点
多线程程序作为一种多任务、并发的工作方式,有以下的优点:
1)提高应用程序响应。
这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(timeconsuming)置于一个新的线程,可以避免这种尴尬的情况。
2)使多CPU系统更加有效。
操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。
3)改善程序结构。
一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
LIBC中的pthread库提供了大量的API函数,为用户编写应用程序提供支持。
2.实验源代码结构流程图
实验为著名的生产者-消费者问题模型的实现,主程序中分别启动生产者线程和消费者线程。
生产者线程不断顺序地将0到1000的数字写入共享的循环缓冲区,同时消费者线程不断地从共享的循环缓冲区读取数据。
流程图如图2-1所示:
图2-1实验源代码结构流程图
3.生产者写入共享的循环缓冲区函数PUT
voidput(structprodcons*b,intdata)
{
pthread_mutex_lock(&b->lock);//获取互斥锁
while((b->writepos+1)%BUFFER_SIZE==b->readpos){//如果读写位置相同
pthread_cond_wait(&b->notfull,&b->lock);
//等待状态变量b->notfull,不满则跳出阻塞。
}
b->buffer[b->writepos]=data;//写入数据
b->writepos++;
if(b->writepos>=BUFFER_SIZE)b->writepos=0;
pthread_cond_signal(&b->notempty);//设置状态变量
pthread_mutex_unlock(&b->lock);//释放互斥锁
}
4.消费者读取共享的循环缓冲区函数GET
intget(structprodcons*b)
{
intdata;
pthread_mutex_lock(&b->lock);//获取互斥锁
while(b->writepos==b->readpos){//如果读写位置相同
pthread_cond_wait(&b->notempty,&b->lock);
//等待状态变量b->notempty,不空则跳出阻塞。
否则无数据可读。
}
data=b->buffer[b->readpos];//读取数据
b->readpos++;
if(b->readpos>=BUFFER_SIZE)b->readpos=0;
pthread_cond_signal(&b->notfull);//设置状态变量
pthread_mutex_unlock(&b->lock);//释放互斥锁
returndata;
}
5.生产、消费流程图:
生产消费流程图如下图2-2所示:
图2-2生产消费流程图
6.主要的多线程API
1、线程创建函数:
intpthread_create(pthread_t*thread_id,__constpthread_attr_t*__attr,
void*(*__start_routine)(void*),void*__restrict__arg);
2、获得父进程ID:
pthread_tpthread_self(void)
3、测试两个线程号是否相同:
intpthread_equal(pthread_t__thread1,pthread_t__thread2)
4、线程退出:
voidpthread_exit(void*__retval)
5、等待指定的线程结束:
intpthread_join(pthread_t__th,void**__thread_return)
6、互斥量初始化:
pthread_mutex_init(pthread_mutex_t*,__constpthread_mutexattr_t*)
7、销毁互斥量:
intpthread_mutex_destroy(pthread_mutex_t*__mutex);
8、再试一次获得对互斥量的锁定(非阻塞):
intpthread_mutex_trylock(pthread_mutex_t*__mutex);
9、锁定互斥量(阻塞):
intpthread_mutex_lock(pthread_mutex_t*__mutex);
10、解锁互斥量
intpthread_mutex_unlock(pthread_mutex_t*__mutex)
11、条件变量初始化
intpthread_cond_init(pthread_cond_t*__restrict__cond,
__constpthread_condattr_t*__restrict__cond_attr)
12、销毁条件变量COND
intpthread_cond_destroy(pthread_cond_t*__cond)
13、唤醒线程等待条件变量
intpthread_cond_signal(pthread_cond_t*__cond)
14、等待条件变量(阻塞)
intpthread_cond_wait(pthread_cond_t*__restrict__cond,
pthread_mutex_t*__restrict__mutex)
15、在指定的时间到达前等待条件变量
intpthread_cond_timedwait(pthread_cond_t*__restrict__cond,
pthread_mutex_t*__restrict__mutex,
__conststructtimespec*__restrict__abstime)
五、实验步骤
1.进入exp/basic/02_pthread目录,使用vi编辑器或其他编辑器阅读理解源代码。
2.运行make产生pthread可执行文件。
3.切换到minicom终端窗口,使用NFSmount开发主机的/arm2410到/host目录。
4.进入/host/exp/basic/pthread目录,运行pthread,观察运行结果的正确性。
5.修改一些参数,再次运行调试,加深对多线程的理解。
6.参考源代码:
#include
#include
#include
#include"pthread.h"
#defineBUFFER_SIZE16
/*Circularbufferofintegers.*/
structprodcons{
intbuffer[BUFFER_SIZE];/*theactualdata*/
pthread_mutex_tlock;/*mutexensuringexclusiveaccesstobuffer*/
intreadpos,writepos;/*positionsforreadingandwriting*/
pthread_cond_tnotempty;/*signaledwhenbufferisnotempty*/
pthread_cond_tnotfull;/*signaledwhenbufferisnotfull*/
};
/*--------------------------------------------------------*/
/*Initializeabuffer*/
voidinit(structprodcons*b)
{
pthread_mutex_init(&b->lock,NULL);
pthread_cond_init(&b->notempty,NULL);
pthread_cond_init(&b->notfull,NULL);
b->readpos=0;
b->writepos=0;
}
/*--------------------------------------------------------*/
/*Storeanintegerinthebuffer*/
voidput(structprodcons*b,intdata)
{
pthread_mutex_lock(&b->lock);
/*Waituntilbufferisnotfull*/
while((b->writepos+1)%BUFFER_SIZE==b->readpos){
printf("waitfornotfull\n");
pthread_cond_wait(&b->notfull,&b->lock);
}
/*Writethedataandadvancewritepointer*/
b->buffer[b->writepos]=data;
b->writepos++;
if(b->writepos>=BUFFER_SIZE)b->writepos=0;
/*Signalthatthebufferisnownotempty*/
pthread_cond_signal(&b->notempty);
pthread_mutex_unlock(&b->lock);
}
/*--------------------------------------------------------*/
/*Readandremoveanintegerfromthebuffer*/
intget(structprodcons*b)
{
intdata;
pthread_mutex_lock(&b->lock);
/*Waituntilbufferisnotempty*/
while(b->writepos==b->readpos){
printf("waitfornotempty\n");
pthread_cond_wait(&b->notempty,&b->lock);
}
/*Readthedataandadvancereadpointer*/
data=b->buffer[b->readpos];
b->readpos++;
if(b->readpos>=BUFFER_SIZE)b->readpos=0;
/*Signalthatthebufferisnownotfull*/
pthread_cond_signal(&b->notfull);
pthread_mutex_unlock(&b->lock);
returndata;
}
/*--------------------------------------------------------*/
#defineOVER(-1)
structprodconsbuffer;
/*--------------------------------------------------------*/
void*producer(void*data)
{
intn;
for(n=0;n<1000;n++){
printf("put-->%d\n",n);
put(&buffer,n);
}
put(&buffer,OVER);
printf("producerstopped!
\n");
returnNULL;
}
/*--------------------------------------------------------*/
void*consumer(void*data)
{
intd;
while
(1){
d=get(&buffer);
if(d==OVER)break;
printf("%d-->get\n",d);
}
printf("consumerstopped!
\n");
returnNULL;
}
/*--------------------------------------------------------*/
intmain(void)
{
pthread_tth_a,th_b;
void*retval;
init(&buffer);
pthread_create(&th_a,NULL,producer,0);
pthread_create(&th_b,NULL,consumer,0);
/*Waituntilproducerandconsumerfinish.*/
pthread_join(th_a,&retval);
pthread_join(th_b,&retval);
return0;
}
实验三、串行端口程序设计
一、实验目的
1了解在linux环境下串行程序设计的基本方法。
2掌握终端的主要属性及设置方法,熟悉终端IO函数的使用。
3学习使用多线程来完成串口的收发处理。
二、实验内容
读懂程序源代码,学习终端IO函数tcgetattr(),tcsetattr(),tcflush()的使用方法,学习将多线程编程应用到串口的接收和发送程序设计中。
三、实验设备及工具
硬件:
UP-NETARM2410-S嵌入式实验仪,PC机pentumn500以上,硬盘40G以上,内存大于128M。
软件:
PC机操作系统REDHATLINUX9.0+MINICOM+AMRLINUX开发环境
四、实验原理
Linux操作系统从一开始就对串行口提供了很好的支持,为进行串行通讯提供了大量的函数,我们的实验主要是为掌握在LINUX中进行串行通讯编程的基本方法。
1.程序流程图
程序流程图如图2-3所示:
图2-3程序流程图
2.串口操作需要的头文件
#include
#include
#include
#include
#include
#include
#include
#include
#include
3.打开串口
在Linux下串口文件是位于/dev下,串口一为/dev/ttyS0,串口二为/dev/ttyS1,打开串口是通过使用标准的文件打开函数操作:
intfd;
/*以读写方式打开串口*/
fd=open("/dev/ttyS0",O_RDWR);
if(-1==fd){
perror("提示错误!
");
}
4.设置串口
最基本的设置串口包括波特率设置,效验位和停止位设置。
串口的设置主要是设置structtermios结构体的各成员值。
structtermio
{unsignedshortc_iflag;/*输入模式标志*/
unsignedshortc_oflag;/*输出模式标志*/
unsignedshortc_cflag;/*控制模式标志*/
unsignedshortc_lflag;/*localmodeflags*/
unsignedcharc_line;/*linediscipline*/
unsignedcharc_cc[NCC];/*controlcharacters*/
};
设置这个结构体很复杂,可以参考man手册或者由赵克佳、沈志宇编写的《UNIX程序编写教程》,我这里就只考虑常见的一些设置:
波特率设置:
下面是修改波特率的代码:
structtermiosOpt;
tcgetattr(fd,&Opt);
cfsetispeed(&Opt,B19200);/*设置为19200Bps*/
cfsetospeed(&Opt,B19200);
tcsetattr(fd,TCANOW,&Opt);
校验位和停止位的设置:
无效验8位
Option.c_cflag&=~PARENB;
Option.c_cflag&=~CSTOPB;
Option.c_cflag&=~CSIZE;
Option.c_cflag|=~CS8;
奇效验(Odd)7位
Option.c_cflag|=~PARENB;
Option.c_cflag&=~PARODD;
Option.c_cflag&=~CSTOPB;
Option.c_cflag&=~CSIZE;
Option.c_cflag|=~CS7;
偶效验(Even)7位
Option.c_cflag&=~PARENB;
Option.c_cflag|=~PARODD;
Option.c_cflag&=~CSTOPB;
Option.c_cflag&=~CSIZE;
Option.c_cflag|=~CS7;
Space效验7位
Option.c_cflag&=~PARENB;
Option.c_cflag&=~CSTOP
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 华北 电力大学 科技学院 嵌入式 实验 报告