嵌入式实验报告文档格式.docx
《嵌入式实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《嵌入式实验报告文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
![嵌入式实验报告文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/8/82d464eb-b694-4547-9874-e3a28f2ce72b/82d464eb-b694-4547-9874-e3a28f2ce72b1.gif)
C/OS-II全部以源代码的方式提供给读者,大约有5500行。
CPU相关的部分使用的是针对Intel80x86微处理器的代码。
虽然µ
C/OS-II可以在PC机上开发和测试,但是可以很容易地移植到不同架构的嵌入式微处理器上。
C/OS-II的特点
1、源代码:
C/OS-II全部以源代码的方式提供给使用者(约5500行)。
该源码清晰易读,结构协调,且注解详尽,组织有序;
2、可移植(portable):
µ
C/OS-II的源代码绝大部分是用移植性很强的ANSIC写的,与微处理器硬件相关的部分是用汇编语言写的。
C/OS-II可以移植到许许多多不同的微处理器上,条件是:
该微处理器具有堆栈指针,具有CPU内部寄存器入栈、出栈指令,使用的C编译器必须支持内嵌汇编,或者该C语言可扩展和可链接汇编模块,使得关中断和开中断能在C语言程序中实现;
3、可固化(ROMable):
C/OS-II是为嵌入式应用而设计的,意味着只要具备合适的系列软件工具(C编译、汇编、链接以及下载/固化)就可以将µ
C/OS-II嵌入到产品中作为产品的一部分;
4、可裁减(scalable):
可以只使用µ
C/OS-II中应用程序需要的系统服务。
可裁减性是靠条件编译实现的,只需要在用户的应用程序中定义那些µ
C/OS-II中的功能应用程序需要的部分就可以了;
5、可抢占性(preemptive):
C/OS-II是完全可抢占型的实时内核,即µ
C/OS-II总是运行就绪条件下优先级最高的任务;
6、多任务:
C/OS-II可以管理64个任务。
赋予每个任务的优先级必须是不相同的,这就是说µ
C/OS-II不支持时间片轮转调度法(该调度法适用于调度优先级平等的任务);
7、可确定性:
绝大多数µ
C/OS-II的函数调用和服务的执行时间具有可确定性。
也就是说用户能知道µ
C/OS-II的函数调用与服务执行了多长时间。
进而可以说,除了函数OSTimeTick()和某些事件标志服务,µ
C/OS-II系统服务的执行时间不依赖于用户应用程序任务数目的多少;
8、任务栈:
每个任务都有自己单独的栈。
C/OS-II允许每个任务有不同的栈空间,以便降低应用程序对RAM的需求;
9、系统服务:
C/OS-II提供许多系统服务,比如信号量、互斥信号量、事件标志、消息邮箱、消息队列、时间管理等等;
10、中断管理:
中断可以使正在执行的任务暂时挂起。
如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可以达255层;
11、稳定性和可靠性:
C/OS-II的每一种功能、每一个函数以及每一行代码都经过了考验和测试,具有足够的安全性与稳定性,能用于与人性命攸关、安全性条件极为苛刻的系统中。
2.3µ
C/OS-II主要源代码文件介绍
C/OS-II的源代码具体包括以下的文件:
PC.C:
源文件PC.H包含了对函数和环境的一些定义。
OS_CORE.COS_FLAG.COS_MBOX.COS_MEM.COS_MUTEX.COS_Q.COS_SEM.COS_TASK.COS_TIME.Cµ
COS-II.Cµ
COS-II.H:
这些文件是µ
C/OS-II中所有与处理器类型无关部分的源代码。
OS_CPU_A.SOS_CPU_C.COS_CPU.H:
这些文件是与处理器类型相关部分的源代码,在本实验系统中是面向80x86处理器的。
INCLUDES.H
给整个内核库提供了总体的include文件。
OS_CFG..H:
C/OS-II的配置文件,定义使用µ
C/OS-II中的哪些功能。
3.代码
3.1Pc.c
#define_CRT_SECURE_NO_WARNINGS
#include"
includes.h"
BOOLEANlock=FALSE;
HANDLEhStdOut=NULL;
externvoid(*interruptTable[])();
BOOLEANPC_GetKey(INT16S*c)
{
if(PC_CHECK_RECURSIVE_CALLS&
&
lock)//检查并避免递归调用{MessageBox(NULL,"
RecursivecallinPC_GetKey"
"
ucos-II"
MB_OK);
exit(-1);
}elseif(lock)
{returnFALSE;
}else
{lock=TRUE;
}
if(_kbhit())//检查是否按下按键
{*c=_getch();
//如果按下
lock=FALSE;
return(TRUE);
{*c=0x00;
//没有按下
return(FALSE);
}
voidPC_DispStr(INT8Ux,INT8Uy,INT8U*s,INT8Ucolor)
{COORDpos;
#ifdefDEBUG_PC
printf("
PC_DispStr:
%s\n"
s);
return;
#endif
lock)//检查并避免递归调用{MessageBox(NULL,"
RecursivecallinPC_DispStr"
{return;
if(hStdOut==NULL)//获取标准输出的句柄
hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
if((x>
79)||(y>
24))//检查有效的光标位置
MessageBox(NULL,"
InvalidscreenpositioninPC_DispStr()"
pos.X=x;
//设置光标位置
pos.Y=y;
SetConsoleCursorPosition(hStdOut,pos);
SetConsoleTextAttribute(hStdOut,color);
//设置文本颜色
puts(s);
//显示文本字符串
voidPC_DispChar(INT8Ux,INT8Uy,INT8Uc,INT8Ucolor)
PC_DispChar:
%c\n"
c);
RecursivecallinPC_DispChar"
24))//检查有效的光标位置
InvalidscreenpositioninPC_DispChar()"
//设置光标位置
putchar(c);
//显示字符
voidPC_DispClrScr(INT8Ucolor)
PC_DispClrScr\n"
);
RecursivecallinPC_DispClrScr"
if(hStdOut==NULL)//获取标准输出的句柄
pos.X=0;
pos.Y=0;
//将光标位置设置为窗口顶部
system("
cls"
//清屏
#defineNTIMERS16
staticINT16UPC_ElapsedOverhead=0;
staticLARGE_INTEGERPC_startTime[NTIMERS],PC_stopTime[NTIMERS],PC_frequency;
voidPC_ElapsedInit(void)
{staticBOOLEANinitDone=FALSE;
if(initDone)
return;
QueryPerformanceFrequency(&
PC_frequency);
//获得CPU频率
PC_ElapsedOverhead=0;
//在PC_Elapsed开始时测量头部文件PC_ElapsedStart(0);
//和PC_Elapsed结束时
PC_ElapsedOverhead=(INT16U)PC_ElapsedStop(0);
initDone=TRUE;
voidPC_ElapsedStart(INT8Un)
{if(n>
=NTIMERS)
QueryPerformanceCounter(&
PC_startTime[n]);
//读取CPU内存取的信息
INT32UPC_ElapsedStop(INT8Un)
{LARGE_INTEGERPC_diffTime;
if(n>
return0;
PC_stopTime[n]);
//读取CPU内存取的信息
PC_diffTime.QuadPart=PC_stopTime[n].QuadPart-PC_startTime[n].QuadPart;
//计算差值并将其转换为微秒。
return(INT32U)(PC_diffTime.QuadPart*(__int64)1000000/PC_frequency.QuadPart-PC_ElapsedOverhead);
voidPC_GetDateTime(char*s)
{SYSTEMTIMEnow;
GetLocalTime(&
now);
//获取本地日期和时间
sprintf(s,"
%04d-%02d-%02d%02d:
%02d:
%02d"
//转换成字符串
now.wYear,
now.wMonth,
now.wDay,
now.wHour,
now.wMinute,
now.wSecond);
voidPC_IntVectSet(INT8Uirq,void(*isr)(void))
{if((irq>
0)&
(irq<
8))
interruptTable[irq]=isr;
void*PC_IntVectGet(INT8Uirq)
{if(irq<
8)
returninterruptTable[irq];
else
returnNULL;
3.2TEST.C主程序
intmain(void)
PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);
//清屏
OSInit();
/*初始化uC/OS-II*/
RandomSem=OSSemCreate
(1);
/*随机数字信号*/
OSTaskCreate(TaskStart,(void*)0,&
TaskStartStk[TASK_STK_SIZE-1],0);
OSStart();
/*开始多任务处理*/
voidTaskStart(void*pdata)
INT16Skey;
pdata=pdata;
/*防止编译警告*/
TaskStartDispInit();
/*初始化显示*/
TaskStartCreateTasks();
/*创建所有应用程序任务*/
OSStatInit();
/*初始化uC/OS-II的统计*/
for(;
;
){
TaskStartDisp();
/*更新显示*/
if(PC_GetKey(&
key)==TRUE){/*查看按键是否已按下*/
if(key==0x1B){/*如果是,检查这是不是退出地址*/
exit(0);
/*结束程序*/
OSCtxSwCtr=0;
/*清除上下文切换计数器*/
OSTimeDlyHMSM(0,0,1,0);
/*等待一秒钟*/
staticvoidTaskStartDispInit(void)
PC_DispStr(0,0,"
uC/OS-II,TheReal-TimeKernel"
DISP_FGND_WHITE+DISP_BGND_RED);
#ifdef__WIN32__
PC_DispStr(0,1,"
OriginalversionbyJeanJ.Labrosse,80x86-WIN32portbyWernerZimmermann"
DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
#ifdef__LINUX__
OriginalversionbyJeanJ.Labrosse,80x86-LINUXportbyWernerZimmermann"
PC_DispStr(0,2,"
"
DISP_FGND_BLACK+DISP_BGND_WHITE);
PC_DispStr(0,3,"
EXAMPLE#1"
PC_DispStr(0,4,"
PC_DispStr(0,5,"
PC_DispStr(0,6,"
PC_DispStr(0,7,"
PC_DispStr(0,8,"
PC_DispStr(0,9,"
PC_DispStr(0,10,"
PC_DispStr(0,11,"
PC_DispStr(0,12,"
PC_DispStr(0,13,"
PC_DispStr(0,14,"
PC_DispStr(0,15,"
PC_DispStr(0,16,"
PC_DispStr(0,17,"
PC_DispStr(0,18,"
PC_DispStr(0,19,"
PC_DispStr(0,20,"
PC_DispStr(0,21,"
#Tasks:
CPUUsage:
%"
PC_DispStr(0,22,"
#Taskswitch/sec:
PC_DispStr(0,23,"
<
-PRESS'
ESC'
TOQUIT->
/*
staticvoidTaskStartDisp(void)
chars[80];
%5d"
OSTaskCtr);
/*显示#任务的运行*/
PC_DispStr(18,21,s,DISP_FGND_YELLOW+DISP_BGND_BLUE);
#ifOS_TASK_STAT_EN>
0
sprintf(s,"
%3d"
OSCPUUsage/*OSIdleCtr/(OSIdleCtrMax/100)*/);
/*显示CPU使用频率*/
PC_DispStr(36,21,s,DISP_FGND_YELLOW+DISP_BGND_BLUE);
PC_GetDateTime(s);
PC_DispStr(58,21,s,DISP_FGND_YELLOW+DISP_BGND_BLUE);
OSCtxSwCtr);
/*显示每秒上下文切换*/
PC_DispStr(18,22,s,DISP_FGND_YELLOW+DISP_BGND_BLUE);
uCOS-IIV%1d.%02dWIN32V%1d.%02d"
OSVersion()/100,OSVersion()%100,OSPortVersion()/100,OSPortVersion()%100);
/*显示uC/OS-II的版本号*/
uCOS-IIV%1d.%02dLINUXV%1d.%02d"
/*显示uC/OS-II的版本号*/
PC_DispStr(52,22,s,DISP_FGND_YELLOW+DISP_BGND_BLUE);
staticvoidTaskStartCreateTasks(void)
INT8Ui;
for(i=0;
i<
N_TASKS;
i++){/*创建n_tasks相同的任务*/
TaskData[i]='
0'
+i;
/*每个任务均显示自己的字母代号*/
OSTaskCreate(Task,(void*)&
TaskData[i],&
TaskStk[i][TASK_STK_SIZE-1],(INT8U)(i+1));
voidTask(void*pdata)
INT8Ux;
INT8Uy;
INT8Uerr;
#ifdef__WIN