第一篇:嵌入式实时操作系统 项目开发总结报告
项目开发总结报告
分 类:软件项目计划 使用者:E-fanciers
Version: 1.0
项 目 承 担 队伍:烟台大学
计算机学院 E-fanciers小组撰 写 人(签名): 许超 于歌
完 成 日 期: 2009-7-16 本文档使用小组: E-fanciers小组
评审负责人(签名): 孝瑞
评 审 日 期: 2009-7-19
目 录
一、引言.............................................3
1.1编写目的.......................................3 1.2项目背景.......................................3 1.3定义...........................................3 1.4参考资料:.....................................3
二、开发结果........................错误!未定义书签。
2.1产品..........................错误!未定义书签。2.2主要功能......................错误!未定义书签。2.3所用工时.......................................4 2.3所用机时.......................................4 2.3进度...........................................4
三、评价............................................4
3.1生产率评价.....................................4 3.2技术方案评价...................................4 3.3产品质量评价...................................4
四、经验与教训.......................................4
一.引言
1.编写目的(阐明编写总结报告的目的,指明读者对象。)
详细陈述项目开发过程,对项目开发做最后的总结完善,说明项目开发过程中遇到的难题及解决方案。
2.项目背景(说明项目的来源、委托单位、开发单位及主管部门。)
随着微电子技术、计算机技术和网络通信技术的发展,嵌入式系统已广泛应用在各个领域,包括消费电子、汽车电子、网络通信、工业设备、航空航天和国防军事等。随着嵌入式技术的发展,工业领域也一改过去传统的单片机应用模式,逐渐将一些新嵌入式技术引入到系统中。特别是作为软件基础的嵌入式操作系统已广泛为业界所接受,借以提高系统的开发效率和运行效率。是否采用嵌入式操作系统,已成为工业设备品质优劣的标志之一。
当今的嵌入式操作系统领域呈现百家争鸣的状态。据最近的调查数据显示,嵌入式操作系统有数十种之多的。这种多样性存在是必然的,是由嵌入式系统的定制性所决定的,是针对各个领域和行业的不同需求的应对。也就是说,各个嵌入式操作系统都有自己的应用领域,针对不同的应用没有绝对的优劣之分,不会出现一种操作系统垄断的局面。自主开发嵌入式操作系统绝对不是多余的,也是是对这种多样性的自然顺应,应该可拥有自己的用武之地。有些国内嵌入式厂商将希望寄托在Linux之上,以为它可以帮助解决所面临的版税和安全等问题。但事实并非完全如此,至少在嵌入式系统领域。首先,Linux还是泊来货,国人并未掌握其核心技术和进程,也并未解决对外依赖的问题。其次,Linux是为桌面系统而设计的,并不能很好地满足嵌入式系统高效性和灵活性的要求;再次,Linux的一统也违背了嵌入式系统应用灵活定制的本质特性。
3.定义(列出报告中用到的专门术语定义和缩写词的原意。)
int taskInit(void);
/*创建一个任务, 返回: 返回任务编号tid, >0: 成功, 其他: 失败.*/ /*name: 任务名称, entryPtr : 任务函数入口, stack_size: 任务栈大小, priority: 任务优先级*/ int taskCreate(char *name, void *entryPtr, int stack_size, int priority);/*启动一个任务, 让taskCreat创建的任务参加调度*/ int taskStart(unsigned char tid);/*tid: 任务编号, 由taskCreate返回*/ int taskPriorityGet(unsigned char tid);int taskPrioritySet(unsigned char tid, int newPriority);/*获取和设置任务优先级, 用于动态调整*/ int taskSuspend(unsigned char tid);/*将任务挂起, 该任务退出调度*/ int taskDelete(unsigned char tid);/*将任务删除 该任务退出调度且回收任务分配的资源*/ int semCreate(void);/*互斥信号量创建, 返回信号量标识sid, <0: 失败*/ int semTake(int sid);int semGive(int sid);/*互斥信号量获取和释放*/ int taskSleep(int ticks);/*任务睡眠(非忙等), 由任务自己调用, 主动阻塞一段时间.时间单位为tick, 即10ms*/ 4.参考资料(列出这些资料的作者、标题、编号、发表日期、出版单位或资料来源,可包括:(1)项目开发计划;(2)需求规格说明书;(3)概要设计说明书;(4)详细设计说明书;(5)用户操作手册;(6)测试计划;(7)测试分析报告(8)本报告引用的其他资料、采用的开发标准或开发规范。)(1)软件项目计划(2)需求规格说明(3)软件编写向导
(4)国家软件开发文档标准模板
二.开发结果
1.产品(可包括:(1)列出各部分的程序名称、源程序行数(包括注释行)或目标程序字节数及程序总计数量、存储形式;产品文档名称等。)
2.主要功能及性能 基本功能
1.基于参考硬件平台,建立硬件抽象层,完成基本硬件初始化,建立时钟中断; 2.在硬件抽象层基础上,建立多任务操作系统环境; 3.任务调度采用同级时间片轮询机制;
4.实现任务间基本通讯机制:互斥信号量(共享内存); 5.实现基本的时钟管理机制:任务睡眠阻塞;
6.实现一个RS232串口驱动。基于串口驱动实现一个命令行Shell(用一个独立的任务实现),可在超级终端显示信息和执行命令。
扩展功能
7.任务区分优先级,在同级轮询调度基础上添加优先级调度机制; 8.不同优先级任务之间实现抢占调度;
9.在抢占调度的基础上实现优先级逆转保护,避免逻辑死锁问题; 10.将代码移植到另一个硬件平台上运行,验证代码移植性。3.所用工时(按人员的不同层次分别计时。)
编码成员工时:60小时/周,共约400小时;
编写文档成员:共约60小时。
4.所用机时
5小时/天,共约300小时的机时。
5.进度(给出计划进度与实际进度的对比。)
根据敏捷开发方法的指导,每天查漏补缺,实际进度基本和计划进度一致。三.评价
1.生产率评价(如平均每人每周源程序行数、文档的字数等。)
源程序:200行/周
文档:1500字/周
2.技术方案评价
严格遵循开发流程,运用科学开发方法。
3.产品质量评价
按照大赛要求完成了应有功能的基础上有所添加自己小组的特色,譬如,设置相应的出错处理机制,为加强该系统的安全性与稳定性也做了相应的措施,总体来说,我们小组开发的嵌入式实时操作系统功能良好,稳定性强。
四.经验与教训
经过近两个月的对嵌入式实时操作系统的开发,经验学到了不少,当然也得到了很多教训,因为小组的不注意,导致2138开发板没法继续工作,有的时候会很耽误时间,有的时候进度报告拖后一点才写,也因此导致过进度不明了,不过,大多数时候,我们小组成员都认真对待大赛,努力想把自己小组的作品做的更完美,最后终于成功交付任务,完成大赛。
第二篇:嵌入式实时操作系统(dynaLinux),及其开发平台(精)
嵌入式实时操作系统(dynaLinux),及其开发平台
公司简介:
注册时间:2003年3月24日 经济性质:合资 从事领域:电子信息
资产状况:注册资金100万人民币 人员状况:12人 股本结构: 中方:方沛宇 60万元 杨海英 10万元
外方:今村博宣 20万元 日本力扬株式会社 10万元 项目情况:
我们采用独自的技术彻底改造了其Linux内核,使其成为一种完全意义上的实时操作系统。dynaLinux具有以下特点:(1)导入了基于OSPM/ACPI的动态电源管理机构,可以根据CPU的使用状态动态控制耗电量。(2)高速的boot机制。(3)坚固的安定性。(4)支持无MMU的CPU。
应用领域主要是面向:信息家电、PDA、手机、车载终端、GPS 等 国内外市场分析:
Linux操作系统在嵌入式系统中的应用近来成为一种趋势。据有关部门预测到2005年嵌入式系统中Linux的份额将占50%以上。但基于分时系统而架构的Linux存在许多先天的不足,故现有的嵌入式Linux还不能称为完全意义上的实时。我们采用独自的技术彻底改造了其Linux内核,使其成为一种完全意义上的实时操作系统。鉴于dynaLinux的优势,本公司被被富士通指定为支持其FR-V CPU的Linux提供商和全球技术总支持。融资和技术转让方案:
总项目投资:100万人民币 已完成投资状况:50万人民币 项目进展阶段:已完成Dyna-Linux(v 1.0)的开发 融资或转让方式:投资或融资 联系方式:
公司名称:北京华科力扬科技有限公司
通讯地址:北京市海淀区上地信息路2号国际创业园D栋612 邮编:100085 联系人:赵强 电话:82893150 传真:82781836 Email:zhaoq@dyna.cn
第三篇:嵌入式Linux实时操作系统习题总结
第1章
1.嵌入式系统是指操作系统和功能软件集成于计算机硬件系统之中。嵌入式系统一般有3个主要的组成部分:硬件、实时操作系统以及应用软件。
2.嵌入式系统的三要素是嵌入、专用、计算机;即以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
3.目前国际较为知名的有:VxWorks、NeutrinoRTOS、Nucleus Plus、OS/
9、VRTX、LynuxOS,RTLinux、BlueCat RT等。
4.嵌入式系统一般由硬件层、中间层、软件层和功能层组成。其作用分别如下:
(1)硬件层 :由嵌入式微处理器、外围电路和外设组成。操作系统和应用程序都可以固化在ROM或者Flash中。为方便使用,有的模块在此基础上增加了LCD、键盘、USB接口,以及其他一些功能的扩展电路。
(2)中间层 :硬件层与软件层之间为中间层,其作用将系统软件与底层硬件部分隔离,使得系统的底层设备驱动程序与硬件无关;
(3)软件层 :主要是操作系统,有的还包括文件系统、图形用户接口和网络系统等。操作系统是一个标准的内核,将中断、I/O、定时器等资源都封装起来,以方便用户使用。(4)功能层 :由基于操作系统开发的应用程序组成,用来完成对被控对象的控制功能。5.非占先式调度法也称作合作型多任务(cooperative multitasking),各个任务彼此合作共享一个CPU。中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。当系统响应时间很重要时,要使用占先式(preemptive)内核。最高优先级的任务一旦就绪,总能得到CPU的控制权。当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了。6.在实时系统中,如果系统在指定的时间内未能实现某个确定的任务,会导致系统的全面失败,这样的系统被称硬实时系统。在弱实时系统中,超时却不会发生致命的错误。其实时性的要求比硬实时系统要差一些。
7.嵌入式系统的设计步骤及各部分的主要工作如下。(1)需求分析阶段,罗列出用户的需求;
(2)体系结构设计阶段,描述系统的功能如何实现;
(3)详细设计阶段,进行硬件系统与软件系统的分类划分,以决定哪些功能用硬件实现,哪些用软件实现;
(4)系统集成,把系统的软件、硬件和执行装置集成在一起,进行调试,发现并改进在设计过程中的错误;
(5)系统测试,对设计好的系统进行测试,看其是否满足给定的要求。8.Linux作为嵌入式操作系统的优势主要有以下几点:
(1)可应用于多种硬件平台。
(2)Linux的高度模块化使添加部件非常容易。
(3)Linux是一个和Unix相似、以内核为基础的、具有完全的内存访问控制,支持大量硬件的一种通用操作系统。
(4)Linux可以随意地配置,不需要任何的许可证或商家的合作关系。
(5)Linux带有Unix用户熟悉的完善的开发工具。其强大的语言编译器GCC,C++等也可以很容易得到,不但成熟完善,而且使用方便。9. Linux执行进程调度一般是在以下情况发生的:(1)正在执行的进程运行完毕;
(2)正在执行的进程调用阻塞原语将自己阻塞起来进入等待状态;(3)正在执行的进程调用了P原语操作,从而因资源不足而被阻塞;(4)执行中的进程提出I/O请求后被阻塞;(5)系统分配的时间片已经用完;
(6)就绪队列中的某个进程的优先级变得高于当前运行进程的优先级。
第4章
1、Linux 内核的编译菜单有好几个版本,运行:
(1)make config:进入命令行,可以一行一行的配置,但使用不十分方便。
(2)make menuconfig:大多数开发人员使用的Linux 内核编译菜单,使用方便。
(3)make xconfig:在2.4.X 以及以前版本中xconfig 菜单是基于TCL/TK 的图形库的。
2、在完成内核的裁减之后,内核的编译就只要执行以下几条命令: make clean
编译内核之前先把环境给清理干净。make dep
编译相关依赖文件 make zImage
创建内核镜像文件 make modules 创建内核模块。
make install
把相关文件拷贝到默认的目录。
3、此命令是装载压缩映像文件zImage到flash存储器中,地址是kernel分区,并采用xmodem传输协议。
4、此命令是设置网卡1的地址192.168.1.1,掩码为255.255.255.0,不写netmask参数则默认为255.255.255.0。
5、此命令将nfs服务的共享目录sharedir加载到/mnt/nfs。
6、此命令是装载根文件系统root.cramfs到flash存储器中,地址是根文件系统分区,并采用xmodem传输协议。
7、这个命令的操作同时进行了分区和格式化,0~128K存放vivi,128K~192K存放VIVI控制台指令,192K~1216K存放kernel,1216K~4288K存放root,其余部分存放应用程序。
第6章
1.使用虚拟地址寻址整个系统的主存和辅存的方式在现代操作系统中被称为虚拟内存。虚拟内存的管理方法使系统既可以运行体积比物理内存还要大的应用程序,也可以实现“按需调页”策略,既满足了程序的运行速度,又节约了物理内存空间。2.进程内存区域涉及到5种数据段,即:
①代码段:代码段是用来存放可执行文件的操作指令。
②数据段:数据段用来存放可执行文件中已初始化全局变量。③BSS段:BSS段包含了程序中未初始化的全局变量。④堆(heap):用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。
⑤栈:栈是用户存放程序临时创建的局部变量。3.在Linux系统中,内核在最高级执行,也称为“系统态”,在这一级任何操作都可以执行。而应用程序则执行在最低级,即所谓的“用户态”。在这一级处理器禁止对硬件的直接访问和对内存的未授权访问。模块是在所谓的“内核空间”中运行的,而应用程序则是在“用户空间”中运行的。它们分别引用不同的内存映射,也就是程序代码使用不同的“地址空间”。4.共享内存区域是被多个进程共享的一部分物理内存。如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信。共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。5.内存管理利用虚拟文件系统支持交换,交换进程(swapd)定期由调度程序调度,这也是内存管理依赖于进程调度的唯一原因。当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。
第9章
1.参考答案:
Mutex互斥量,用于操作某个临界资源时对该资源上锁,以实现互斥地对独占资源的使用。Semophore信号灯,信号灯内有一计数器,可以用于对多个同类资源的分配。
Condition条件变量,条件变量用于等待信号。当一个线程需要等待某个信号时,就可到条件变量上等待,当信号具备时,系统会唤醒该线程继续运行。2.参考答案:
本地:共享内存+信号量,适合于大量数据传输。Linux支持系统V和POSIX的共享内存和信号量。(5分)
远程:Socket+应用协议。适合于跨网络的(大量)数据传输。Linux支持BSD的socket。应用层协议需要自行设计。(5分)
3.答案要点:程序是编译后形成的可执行代码,是静止的。进程是程序的一次执行,是活动的。线程是进程的可执行单元,同一进程的不同线程共享进程的资源和地址空间。4.两种实现方法,一种是继承Thread,另外一种是实现接口Runnable。
同步的实现方法有两种,分别是synchronized, wait与notify。用synchronized可以对一段代码、一个对象及一个方法进行加锁。用wait与notify可以使对象处于等待及唤醒方式导致同步,因为每个对象都直接或间接的继承了Object类。
5、什么是BootLoader?主要有几种工作模式及主要功能是什么? 答:
Bootloader就是操作系统内核运行的一段小程序,完成进行初始化系统硬件设置的任务,(2分)
分为启动加载模式和下载模式。(1启动加载模式
启动加载(Boot laoding)模式是指 Bootloader 从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,整个过程并没有用户的介入。(2分)(2)下载模式
在下载模式下,目标机上的 Bootloader 将先通过串口连接或网络连接等通信手段从宿主机下载文件。(2分)
6、简述Bootloader有何作用?
答案要点:(1)首先,bootloader是在特定硬件平台运行的程序,严重依赖于硬件平台,需要移植;(2)是系统上电之后,第一个运行的程序,系统在上电或复位时通常都从地址 0x0 处开始执行,而在这个地址处安排的通常就是系统的 Boot Loader 程序;(3)bootloader程序的设计目标是启动嵌入式操作系统,嵌入式操作系统的启动需要一定的条件,这些条件由bootloader来满足;(4)Bootloader一般具有对存储器和网络接口操作的功能;如擦除、读写Flash,通过USB、串口下载文件等
第四篇:实时操作系统报告
实时操作系统课程实验报告
专业:通信1001 学号:3100601025 姓名:陈治州
完成时间:2013年6月11日
实验 简易电饭煲的模拟
一.实验目的:
掌握在基于嵌入式实时操作系统µC/OS-II的应用中,基于多任务的模式的编程方法。锻炼综合应用多任务机制,任务间的通信机制,内存管理等的能力。
二.实验要求:
1.按“S”开机,系统进入待机状态,时间区域显示当前北京时间,默认模式“煮饭”;2.按“C”选择模式,即在“煮饭”、“煮粥”和“煮面”模式中循环选择;
3.按“B”开始执行模式命令,“开始”状态选中,时间区域开始倒计时,倒计时完成后进入“保温”状态,同时该状态显示选中,时间区域显示保温时间;
4.按“Q”取消当前工作状态,系统进入待机状态,时间区域显示北京时间,模式为当前模式;
5.按“X”退出系统,时间区域不显示。
6.煮饭时长为30,煮粥时长为50,煮面时长为40.三.实验设计:
1.设计思路:
以老师所给的五个程序为基础,看懂每个实验之后,对borlandc的操作有了大概的认识,重点以第五个实验Task_EX为框架,利用其中界面显示与按键扫描以及做出相应的响应,对应实现此次实验所需要的功能。
本次实验分为界面显示、按键查询与响应、切换功能、时钟显示与倒计时模块,综合在一起实验所需功能。2.模块划分图:(1)界面显示:
Main()Taskstart()Taskstartdispinit()在TaskStartDispInit()函数中,使用PC_DispStr()函数画出界面。(2)按键查询与响应:
Main()Taskstart()在TaskStart()函数中,用if(PC_GetKey(&key)== TRUE)判断是否有按键输入。然后根据key的值,判断输入的按键是哪一个;在响应中用switch语句来执行对应按键的响应。(3)切换功能:
l计数“C”按键的次数M=l%3Switch(m)M=0,1,2对应于煮饭,煮粥,煮面,然后使用PC_DispStr()函数在选择的选项前画上“@”指示,同时,在其余两项钱画上“ ”以“擦出”之前画下的“@”,注意l自增。
四.主要代码:
#include “stdio.h” #include “includes.h” #include “time.h” #include “dos.h” #include “sys/types.h” #include “stdlib.h” #define TASK_STK_SIZE
512
#define N_TASKS
OS_STK
TaskStk[N_TASKS][TASK_STK_SIZE];
OS_STK
TaskStartStk[TASK_STK_SIZE];
INT8U
TaskData[N_TASKS];
void Task0(void *pdata);
void TaskStart(void *pdata);
static void TaskStartDispInit(void);
void main(void){
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
OSTaskCreate(TaskStart,(void *)0, &TaskStartStk[TASK_STK_SIZE-1], 4);
OSStart();
} void TaskStart(void *pdata){ #if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;#endif
INT8U l,m;
INT16S key;
l=0;
pdata = pdata;
TaskStartDispInit();
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSStatInit();
for(;;){
if(PC_GetKey(&key)== TRUE)
{
switch(key)
{
case 0x1B:
PC_DOSReturn();
break;
case 0x43:
{ m=(l%3);
switch(m)
{ case 0: {
PC_DispStr(26,6, “@”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
PC_DispStr(40,6, “ ”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(55,6, “ ”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);} break;
case 1: { PC_DispStr(26,6, “ ”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
PC_DispStr(40,6, “@”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
PC_DispStr(55,6, “ ”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);} break;case 2: { PC_DispStr(26,6, “ ”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
PC_DispStr(40,6, “ ”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(55,6, “@”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);}
break;}
l++;} break;
} } OSCtxSwCtr = 0;
OSTimeDlyHMSM(0, 0, 1, 0);
} } static void TaskStartDispInit(void){ PC_DispStr(0, 0, “
uC/OS-II, The Real-Time Kernel
”, DISP_FGND_WHITE + DISP_BGND_RED + DISP_BLINK);PC_DispStr(0, 1, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 2, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 3, “
dianfanbao shiyan
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 4, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 5, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 6, “
kai shi.zhu fan.zhu zhou.zhu mian.”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 7, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 8, “
bao wen.”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 9, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 10, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 11, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 12, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 13, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 14, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 15, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 16, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 17, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 18, “
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);PC_DispStr(0, 19, “ 'S':kai ji.”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY + DISP_BLINK);PC_DispStr(0, 20, “ 'C':mo shi qie huan.”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY + DISP_BLINK);PC_DispStr(0, 21, “ 'B':kai shi zhi xin.”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY + DISP_BLINK);PC_DispStr(0, 22, “ 'Q':qu xiao dang qian gong zuo zhuang tai.”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY + DISP_BLINK);PC_DispStr(0, 23, “ 'X':tui chu xi tong.”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY + DISP_BLINK);
PC_DispStr(0, 24, “
<-PRESS 'ESC' TO QUIT->
”, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY + DISP_BLINK);}
五.运行界面:
(1)主界面:
(2)显示北京时间:
(3)模式切换:
(4)倒计时:
(5)保温执行时间:
六.总结:
本次实验主要以老师所给的实验事例为基础,并结合老师课堂讲的内容,理解编写程序。做实验本实验前,先执行了一下事例程序,以此了解borlandc的一些基本操作;然后就是看懂每个实验的框架和主要部分;接着,将事例程序中的部分思想运用到本次实验中,其中以显示界面的思想运用的最多;除此以外,在模式切换上花了最大的精力,最终的解决方法是以变量l作为一个计数值,并运用switch语句在选择的模式上画上“@”,同时还得注意在未选择的模式上画上空格来“擦除”之前画上的@;在查询按键上,同样运用switch语句......这次实验收获不少,不仅对之前学的C语言有了更进一步的巩固,而且还强化了ucos里面的多任务的一些认识;同时,以前对DOS界面很陌生,但本次实验使用的正是DOS界面,通过几天的经历,对DOS中的编译、“help”等各个方面有了更深入的认识,不再害怕使用DOS了。
对本课程有很大的兴趣,在以后的课余时间里我会不断学习这些知识。
第五篇:嵌入式操作系统实验报告
实验一 嵌入式开发环境的建立
一、实验目的
通过此实验系统,读者可以了解嵌入式实时操作系统 uC/OS-II 的内核机制和运行原理。本实验系统展示了 uC/OS-II 各方面的管理功能,包括信号量、队列、内存、时钟等。在各个实验中具体介绍了 uC/OS-II 的相关函数。读者在做实验的同时能够结合理论知识加以分析,了解各个函数的作用和嵌入式应用程序的设计方法,最终对整个 uC/OS-II 和嵌入式操作系统的应用有较为清楚的认识。
二、实验步骤
1.安装集成开发环境LambdaEDU 集成开发环境LambdaEDU 的安装文件夹为 LambdaEDU,其中有一个名为“Setup.exe” 的文件,直接双击该文件便可启动安装过程。具体的安装指导请看“LambdaEDU 安装手 册.doc”文件。
当 LambdaEDU 安装完毕之后,我们看到的是一个空的界面,现在就开始一步一步地将 我们的实验项目建立并运行起来。
2.建立项目
为了我们的实验运行起来,需要建立1 个项目基于x86 虚拟机的标准应用项目。通过点 击“文件”、“新建”、“项目”开始根据向导创建一个项目。
在随后出现的对话框中选择“Tool/标准应用项目”,点击下一步,开始创建一个标准的 可执行的应用程序项目。
在随后出现的对话框中填入项目名称“ucos_x86_demo”。点击“下一步”。
选择“pc386 uC/OS-II 应用(x86)”作为该项目的应用框架。点击“下一步”
选择“pc386_elf_tra_debug”作为该项目的基本配置。点击“完成”。
新创建的项目“ucos_x86_demo”将会被添加到项目列表。src 文件夹下保存了该项目中 包含的源文件。ucos2 文件夹中包含了移植到x86 虚拟机的全部代码。init.c 文件是基于ucos2 和本虚拟机的一个应用程序。在进行ucos2 内核实验中,只需要替换init.c 文件,即可。文
件名不限,但是文件名中最好不要使用英文符号和数字以外的其他字符,3.构建项目
到这里,项目配置全部完成。接下来就可以进行构建项目了。
第一次构建本项目,在此项目上点击右键,选择“重建BSP 及项目”。即可开始构建。
之后弹出的对话框显示了构建的进度。可以点击“在后台运行”,以隐藏该对话框
在构建的同时,在右下角的“构建信息”视图输出构建过程中的详细信息:
注:“重新构建”将本项目中的全部源代码进行一次完全的编译和连接,花费时间较多。“构建项目”则仅仅将新修改过的源代码进行编译和连接,花费时间最少。“重建BSP及项 目”,不但要完成“重新构建”的全部工作,另外还要编译与该项目有关的的LambdaEDU 中内置的部分代码,花费时间最多。但是在项目刚建立后,第一次构建时需要选择“重建 BSP 及项目”。以后的构建中选择“重新构建”或“构建项目”即可。另外,在替换了源代 码中的文件后,需要选择“重新构建”来完成该项目的构建。
4.配置虚拟机和目标机代理
(1)制作X86启动盘
在 LambdaEDU 中依次点击“工具”、“Bochs”、“制作虚拟机启动映象”。对启动盘进行一些参数设置后(如下图所示),系统将自动为你生成一个PC 虚拟机的 启动盘映像。
(2)配置虚拟机 选择使用的网络适配器(网卡)后,点击“确定”完成配置。
注意:如果计算机上有多网卡,请将其他网卡停用(包括 VMware 虚拟机添加的虚拟 网卡)。
(3)创建目标机代理
配置好虚拟机后,创建目标机代理:点击LambdaEDU 左下方窗口中绿色的十字符号,在弹出的窗口中选择“基于TA 的连接方式”,并点击“下一步”。
在弹出的“新目标机连接配置中”的这些参数,应该与之前制作启动盘时设置的参数一致。
注意:
名字:输入目标机的名字(缺省是 default),注意如果和现有目标机重名的话,改个名 字。
连接类型:默认选择 UDP IP地址:这里输入目标机(在本实验系统中是虚拟机)的 IP地址;
最后点击“确定”,在目标机管理窗口中,可以看到新增加了一个名为default 的目标机 节点
(4)调试应用 启动虚拟机。
虚拟机启动后的画面如下(其中显示的IP 地址创建虚拟机启动盘时填入的IP 地址)中设置的IP 地址):
在成功完成构建的项目ucos_x86_demo 中的“pc386_elf_tra_debug”上点击鼠标右键,在弹出的菜单中选择“调试”,启动调试器调试生成的程序:
第一次进行调试/运行,需要选择目标机,如下图,选择“Default”,点击“确定”,开 始向目标机(虚拟机)下载应用程序。程序下载完成后,会弹出一个“确认透视图切换”对话框,选择“是”,切换到调试透 视图。
调试的界面如下:
点击绿色的按钮,全速运行。
注意:全速运行后,程序不能够被暂停和停止。
三、实验过程中遇到的问题及体会
在设置IP地址时,要求该IP地址与本计算机在同一个子网中,同时要求该 IP地址没有被网络上其他计算机使用。此外,通过构建开发环境,处次体验到了嵌入式开发工作的乐趣。
实验二 任务的基本管理
一、实验目的
1.理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程; 2.掌握 uC/OS-II 中任务管理的基本方法(创建、启动、挂起、解挂任务); 3.熟练使用 uC/OS-II 任务管理的基本系统调用。
二、实验原理及程序结构
1.实验设计
为了展现任务的各种基本状态及其变迁过程,本实验设计了 Task0、Task1 两个任务: 任务 Task0 不断地挂起自己,再被任务 Task1 解挂,两个任务不断地切换执行。通过本实验,读者可以清晰地了解到任务在各个时刻的状态以及状态变迁的原因。2.运行流程 描述如下:
(1)系统经历一系列的初始化过程后进入 boot_card()函数,在其中调用 ucBsp_init()进 行板级初始化后,调用 main()函数;
(2)main()函数调用 OSInit()函数对 uC/OS-II 内核进行初始化,调用 OSTaskCreate 创 建起始任务 TaskStart;
(3)main()函数调用函数 OSStart()启动 uC/OS-II 内核的运行,开始多任务的调度,执 行当前优先级最高的就绪任务 TaskStart;(4)TaskStart 完成如下工作:
a、安装时钟中断并初始化时钟,创建 2 个应用任务;
b、挂起自己(不再被其它任务唤醒),系统切换到当前优先级最高的就绪任务Task0。之后整个系统的运行流程如下:
t1 时刻,Task0 开始执行,它运行到 t2 时刻挂起自己;
t2 时刻,系统调度处于就绪状态的优先级最高任务 Task1 执行,它在 t3 时刻唤醒Task0,后者由于优先级较高而抢占 CPU;
Task0 执行到 t4 时刻又挂起自己,内核调度 Task1 执行; Task1 运行至 t5 时刻再度唤醒 Task0; ……
3.µC/OS-Ⅱ中的任务描述
一个任务通常是一个无限的循环,由于任务的执行是由操作系统内核调度的,因此任务是绝不会返回的,其返回参数必须定义成 void。在μC/OS-Ⅱ中,当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的 CPU 使用权就会被抢占,高优先级任务会立刻得到 CPU 的控制权(在系统允许调度和任务切换的前提下)。μC/OS-Ⅱ可以管理多达 64 个任务,但目前版本的μC/OS-Ⅱ有两个任务已经被系统占用了(即空闲任务和统计任务)。必须给每个任务赋以不同的优先级,任务的优先级号就是任务编号(ID),优先级可以从 0 到 OS_LOWEST_PR10-2。优先级号越低,任务的优先级越高。μC/OS-Ⅱ总是运行进入就绪态的优先级最高的任务。4.源程序说明(1)TaskStart任务
TaskStart 任务负责安装操作系统的时钟中断服务例程、初始化操作系统时钟,并创建所 有的应用任务:
UCOS_CPU_INIT();/* Install uC/OS-II's clock tick ISR */ UCOS_TIMER_START();/*Timer 初始化*/ TaskStartCreateTasks();/* Create all the application tasks */ OSTaskSuspend(OS_PRIO_SELF);
具体负责应用任务创建的 TaskStartCreateTasks 函数代码如下,它创建了两个应用任务 Task0 和 Task1:
void TaskStartCreateTasks(void){
INT8U i;
for(i = 0;i < N_TASKS;i++)// Create tasks {
TaskData[i] = i;// Each task will display itsown information }
OSTaskCreate(Task0,(void *)&TaskData[0], &TaskStk[0][TASK_STK_SIZE1], 6);}
TaskStart 任务完成上述操作后将自己挂起,操作系统将调度当前优先级最高的应用任务Task0 运行。(2)应用任务
应用任务 Task0 运行后将自己挂起,之后操作系统就会调度处于就绪状态的优先级最高的任务,具体代码如下: void Task0(void *pdata){
INT8U i;INT8U err;i=*(int *)pdata;for(;;){
printf(“Application tasks switched %d times!nr”,++count);
printf(“TASK_0 IS RUNNING..............................................................nr”);printf(“task_1 is suspended!nr”);
printf(“**************************************************nr”);err=OSTaskSuspend(5);// suspend itself } }
应用任务 Task1 运行后将 Task0 唤醒,使其进入到就绪队列中: void Task1(void *pdata){
INT8U i;INT8U err;i=*(int *)pdata;for(;;){
OSTimeDly(150);
printf(“Application tasks switched %d times!nr”,++count);printf(“task_0 is suspended!nr”);printf(“TASK_1 IS RUNNING..............................................................nr”);printf(“**************************************************nr”);OSTimeDly(150);
err=OSTaskResume(5);/* resume task0 */ } }
三、运行及观察应用输出信息
按照本实验手册第一部分所描述的方法建立应用项目并完成构建,当我们在 LambdaEDU 调试器的控制下运行构建好的程序后,将看到在μC/OS-Ⅱ内核的调度管理下,两个应用任务不断切换执行的情形:
四、本实验中用到的µC/OS-Ⅱ相关函数
4.1 OSTaskCreate()
OSTaskCreate()建立一个新任务。任务的建立可以在多任务环境启动之前,也可以在 正在运行的任务中建立。中断处理程序中不能建立任务。一个任务必须为无限循环结构,且 不能有返回点。
OSTaskCreate()是为与先前的μC/OS 版本保持兼容,新增的特性在 OSTaskCreateExt()函数中。
无论用户程序中是否产生中断,在初始化任务堆栈时,堆栈的结构必须与 CPU 中断后 寄存器入栈的顺序结构相同。详细说明请参考所用处理器的手册。函数原型:
INT8U OSTaskCreate(void(*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio);
参数说明:
task 是指向任务代码首地址的指针。
pdata 指向一个数据结构,该结构用来在建立任务时向任务传递参数。
ptos 为指向任务堆栈栈顶的指针。任务堆栈用来保存局部变量,函数参数,返回地址 以及任务被中断时的 CPU 寄存器内容。任务堆栈的大小决定于任务的需要及预计的中断嵌 套层数。计算堆栈的大小,需要知道任务的局部变量所占的空间,可能产生嵌套调用的函数,及中断嵌套所需空间。如果初始化常量 OS_STK_GROWTH 设为 1,堆栈被设为从内存高地址 向 低 地 址 增 长,此时 ptos 应 该 指 向任 务堆 栈 空 间 的 最 高 地 址。反 之,如 果OS_STK_GROWTH 设为 0,堆栈将从内存的低地址向高地址增长。prio 为任务的优先级。每个任务必须有一个唯一的优先级作为标识。数字越小,优先级越高。返回值:
OSTaskCreate()的返回值为下述之一: OS_NO_ERR:函数调用成功。
OS_PRIO_EXIST:具有该优先级的任务已经存在。
OS_PRIO_INVALID:参数指定的优先级大于 OS_LOWEST_PRIO。 OS_NO_MORE_TCB:系统中没有 OS_TCB 可以分配给任务了。注意:
任务堆栈必须声明为 OS_STK 类型。
在任务中必须调用μC/OS 提供的下述过程之一:延时等待、任务挂起、等待事件发生(等待信号量,消息邮箱、消息队列),以使其他任务得到 CPU。用 户 程 序 中 不 能 使 用 优 先 级 0,1,2,3,以 及 OS_LOWEST_PRIO-3, OS_LOWEST_PRIO-2, OS_LOWEST_PRIO-1, OS_LOWEST_PRIO。这些优先级μC/OS 系统
保留,其余的 56 个优先级提供给应用程序。4.2 OSTaskSuspend()
OSTaskSuspend()无条件挂起一个任务。调用此函数的任务也可以传递参数
OS_PRIO_SELF,挂起调用任务本身。当前任务挂起后,只有其他任务才能唤醒。任务挂起 后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用 函数 OSTaskResume()。
任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么 任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正 在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。函数原型:
INT8U OSTaskSuspend(INT8U prio);参数说明:
prio 为指定要获取挂起的任务优先级,也可以指定参数 OS_PRIO_SELF,挂起任务本 身。此时,下一个优先级最高的就绪任务将运行。返回值:
OSTaskSuspend()的返回值为下述之一: OS_NO_ERR:函数调用成功。
OS_TASK_ SUSPEND_IDLE:试图挂起 µC/OS-II 中的空闲任务(Idle task)。此为非法操作。
OS_PRIO_INVALID :参数指定的优先级大于 OS_LOWEST_PRIO 或没有设定 OS_PRIO_SELF 的值。
OS_TASK_ SUSPEND _PRIO:要挂起的任务不存在。注意:
在程序中 OSTaskSuspend()和 OSTaskResume()应该成对使用。用 OSTaskSuspend()挂起的任务只能用 OSTaskResume()唤醒。4.3 OSTaskResume()
OSTaskResume()唤醒一个用 OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。函数原型:
INT8UOSTaskResume(INT8U prio);参数说明:
prio 指定要唤醒任务的优先级。返回值:
OSTaskResume()的返回值为下述之一: OS_NO_ERR:函数调用成功。
OS_TASK_RESUME_PRIO:要唤醒的任务不存在。
OS_TASK_NOT_SUSPENDED:要唤醒的任务不在挂起状态。
OS_PRIO_INVALID:参数指定的优先级大于或等于 OS_LOWEST_PRIO。
五、实验过程中遇到的问题及体会
实验过程中体会到了嵌入式开发的乐趣,对上课老师所讲的内容有了进一步的认识与理解。17 实验三 信号量:哲学家就餐问题的实现
一、实验目的
掌握在基于嵌入式实时操作系统 uC/OS-II 的应用中,任务使用信号量的一般原理。通 过经典的哲学家就餐实验,了解如何利用信号量来对共享资源进行互斥访问。
二、实验原理及程序结构
1.实验设计
掌握在基于嵌入式实时操作系统 uC/OS-II 的应用中,任务使用信号量的一般原理。通 过经典的哲学家就餐实验,了解如何利用信号量来对共享资源进行互斥访问。2.源程序说明
五个哲学家任务(ph1、ph2、ph3、ph4、ph5)主要有两种过程:思考(即睡眠一段时
间)和就餐。每个哲学家任务在就餐前必须申请并获得一左一右两支筷子,就餐完毕后释放 这两支筷子。五个哲学家围成一圈,每两人之间有一支筷子。一共有五支筷子,在该实验中 用了五个互斥信号量来代表。每个任务的代码都一样,如下所示: void Task(void *pdata){
INT8U err;INT8U i;INT8U j;
i=*(int *)pdata;j=(i+1)% 5;
uC/OS-II 实验指导书 for(;;){
TaskThinking2Hungry(i);OSSemPend(fork[i], 0, &err);
OSSemPend(fork[j], 0, &err);/* Acquire semaphores to eat */ TaskEat(i);
OSSemPost(fork[j]);
OSSemPost(fork[i]);/* Release semaphore */ OSTimeDly(200);/* Delay 10 clock tick */ } }
操作系统配置
修改 uC_OS-II/OS_CFG.h: :: :
#define OS_MAX_EVENTS 10 /*最多可以有 10 个事件*/ #define OS_MAX_FLAGS 5 /*最多可以有 5 个事件标志*/
#define OS_MAX_MEM_PART 5 /*最多可以划分 5 个内存块*/ #define OS_MAX_QS 2 /*最多可以使用 2 个队列*/ #define OS_MAX_TASKS 8 /*最多可以创建 8 个任务*/
#define OS_LOWEST_PRIO 14 /*任务优先级不可以大于 14*/ #define OS_TASK_IDLE_STK_SIZE 1024 /*空闲任务堆栈大小*/ #define OS_TASK_STAT_EN 1 /*是否允许使用统计任务*/ #define OS_TASK_STAT_STK_SIZE 1024 /*统计任务堆栈大小*/ #define OS_FLAG_EN 1 /*是否允许使用事件标志功能*/
#define OS_FLAG_WAIT_CLR_EN 1 /*是否允许等待清除事件标志*/ #define OS_FLAG_ACCEPT_EN 1 /*是否允许使用 OSFlagAccept()*/ #define OS_FLAG_DEL_EN 1 /*是否允许使用 OSFlagDel()*/
#define OS_FLAG_QUERY_EN 1 /*是否允许使用 OSFlagQuery()*/ #define OS_MBOX_EN 0 /*是否允许使用邮箱功能*/
#define OS_MEM_EN 0 /*是否允许使用内存管理的功能*/
#define OS_MUTEX_EN 0 /*是否允许使用互斥信号量的功能*/ #define OS_Q_EN 0 /*是否允许使用队列功能*/ #define OS_SEM_EN 1 /*是否允许使用信号量功能*/
#define OS_SEM_ACCEPT_EN 1 /*是否允许使用 OSSemAccept()*/ #define OS_SEM_DEL_EN 1 /*是否允许使用OSSemDel()*/
#define OS_SEM_QUERY_EN 1 /*是否允许使用OSSemQuery()*/ #define OS_TASK_CHANGE_PRIO_EN 1 /* 是 否 允 许 使 用 OSTaskChangePrio()*/
#define OS_TASK_CREATE_EN 1 /*是否允许使用 OSTaskCreate()*/
#define OS_TASK_CREATE_EXT_EN 1 /*是否允许使用 OSTaskCreateExt()*/ #define OS_TASK_DEL_EN 1 /*是否允许使用 OSTaskDel()*/
#define OS_TASK_SUSPEND_EN 1 /* 是 否 允 许 使 用 OSTaskSuspend()and OSTaskResume()*/
#define OS_TASK_QUERY_EN 1 /*是否允许使用 OSTaskQuery()*/ #define OS_TIME_DLY_HMSM_EN 1 /* 是 否 允 许 使 用 OSTimeDlyHMSM()*/
#define OS_TIME_DLY_RESUME_EN 1 /* 是 否 允 许 使 用 OSTimeDlyResume()*/
#define OS_TIME_GET_SET_EN 1 /* 是否允许使用 OSTimeGet()和 OSTimeSet()*/
#define OS_SCHED_LOCK_EN 1 /* 是 否 允 许 使 用 OSSchedLock()和 OSSchedUnlock()*/
#define OS_TICKS_PER_SEC 200 /*设置每秒之内的时钟节拍数目*/
三、运行及观察应用输出信息
开始,所有的哲学家先处于 thinking 状态,然后都进入 hungry 状态:
后首先获得两个信号量的 1、3 号哲学家开始 eating,待他们释放相关信号量之后,哲
学家 2、5、4 获得所需的信号量并 eating: 应用如此这般地循环执行程序下去„„
四、本实验中用到的µC/OS-Ⅱ相关函数
4.1 OSSemCreate()
OSSemCreate()函数建立并初始化一个信号量。信号量的作用如下: 允许一个任务和其他任务或者中断同步 取得设备的使用权 标志事件的发生
函数原型:
OS_EVENT *OSSemCreate((((WORD value))))参数说明:
value 参数是所建立的信号量的初始值,可以取 0 到 65535 之间的任何值。返回值:
OSSemCreate()函数返回指向分配给所建立的信号量的控制块的指针。如果没有可用的 控制块,OSSemCreate()函数返回空指针。注意:
必须先建立信号量,然后使用。4.2 OSSemPend()
OSSemPend()函数用于任务试图取得设备的使用权,任务需要和其他任务或中断同
步,任务需要等待特定事件的发生的场合。如果任务调用 OSSemPend()函数时,信号量 的值大于零,OSSemPend()函数递减该值并返回该值。如果调用时信号量等于零,OSSemPend()函数函数将任务加入该信号量的等待队列。OSSemPend()函数挂起当前 任务直到其他的任务或中断置起信号量或超出等待的预期时间。如果在预期的时钟节拍内信 号量被置起,μC/OS-Ⅱ默认最高优先级的任务取得信号量恢复执行。一个被 OSTaskSuspend()函数挂起的任务也可以接受信号量,但这个任务将一直保持挂起状态直到通过调用 OSTaskResume()函数恢复任务的运行。函数原型: :: :
Void OSSemPend(OS_EVNNT *pevent, INT16U timeout, int8u *err);参数说明: :: :
pevent
是指向信号量的指针。该指针的值在建立该信号量时可以得到。(参考 OSSemCreate()函数)。
Timeout
允许一个任务在经过了指定数目的时钟节拍后还没有得到需要的信号量时 恢复就绪状态。如果该值为零表示任务将持续地等待信号量,最大的等待时间为 65535 个时
钟节拍。这个时间长度并不是非常严格的,可能存在一个时钟节拍的误差。
Err 是指向包含错误码的变量的指针。OSSemPend()函数返回的错误码可能为下述几 种:
OS_NO_ERR :信号量不为零。
OS_TIMEOUT :信号量没有在指定数目的时钟周期内被设置。
OS_ERR_PEND_ISR :从中断调用该函数。虽然规定了不允许从中断调用该函数,但 µC/OS-Ⅱ仍然包含了检测这种情况的功能。
OS_ERR_EVENT_TYPE :pevent 不是指向信号量的指针。返回值: 无 注意:
必须先建立信号量,然后使用。不允许从中断调用该函数。
4.3 OSSemPost()
OSSemPost()函数置起指定的信号量。如果指定的信号量是零或大于零,OSSemPost()函数递增该信号量并返回。如果有任何任务在等待信号量,最高优先级的任务将得到信
号量并进入就绪状态。任务调度函数将进行任务调度,决定当前运行的任务是否仍然为最高 优先级的就绪状态的任务。函数原型:
INT8U OSSemPost(OS_EVENT *pevent);参数说明:
pevent
是指向信号量的指针。该指针的值在建立该信号量时可以得到。(参考 OSSemCreate()函数)。返回值:
OSSemPost()函数的返回值为下述之一:
OS_NO_ERR :信号量被成功地设置
OS_SEM_OVF :信号量的值溢出
OS_ERR_EVENT_TYPE :pevent 不是指向信号量的指针 注意:
必须先建立信号量,然后使用。4.4 OSTimeDly()
OSTimeDly()将一个任务延时若干个时钟节拍。如果延时时间大于 0,系统将立即进 行任务调度。延时时间的长度可从 0 到 65535 个时钟节拍。延时时间 0 表示不进行延时,函
数将立即返回调用者。延时的具体时间依赖于系统每秒钟有多少时钟节拍(由文件 SO_CFG.H 中的常量 OS_TICKS_PER_SEC 设定)。函数原型:
void OSTimeDly(INT16U ticks);参数说明:
ticks 为要延时的时钟节拍数。返回值:
无
注意:
注意到延时时间 0 表示不进行延时操作,而立即返回调用者。为了确保设定的延时时间,建议用户设定的时钟节拍数加 1。例如,希望延时 10 个时钟节拍,可设定参数为 11。
五、实验过程中遇到的问题及体会
在实验前要对该问题进行深入的理解,即五个哲学家任务(ph1、ph2、ph3、ph4、ph5)主要有两种过程:思考(即睡眠一段时间)和就餐。每个哲学家任务在就餐前必须申请并获得一左一右两支筷子,就餐完毕后释放这两支筷子。五个哲学家围成一圈,每两人之间有一支筷子。只有理解了,才能更好的进行实验。