1、C/OS-II全部以源代码的方式提供给读者,大约有5500行。CPU相关的部分使用的是针对Intel80x86微处理器的代码。虽然C/OS-II可以在PC机上开发和测试,但是可以很容易地移植到不同架构的嵌入式微处理器上。C/OS-II的特点1、源代码:C/OS-II全部以源代码的方式提供给使用者(约5500行)。该源码清晰易读,结构协调,且注解详尽,组织有序;2、可移植(portable): C/OS-II的源代码绝大部分是用移植性很强的ANSI C写的,与微处理器硬件相关的部分是用汇编语言写的。C/OS-II可以移植到许许多多不同的微处理器上,条件是:该微处理器具有堆栈指针,具有CPU内部寄
2、存器入栈、出栈指令,使用的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-
3、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、系
4、统服务:C/OS-II提供许多系统服务,比如信号量、互斥信号量、事件标志、消息邮箱、消息队列、时间管理等等;10、中断管理: 中断可以使正在执行的任务暂时挂起。如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可以达255层;11、稳定性和可靠性:C/OS-II的每一种功能、每一个函数以及每一行代码都经过了考验和测试,具有足够的安全性与稳定性,能用于与人性命攸关、安全性条件极为苛刻的系统中。2.3 C/OS-II主要源代码文件介绍C/OS-II的源代码具体包括以下的文件:PC.C: 源文件PC.H包含了对函数和环境的一些定义。OS_CORE.C OS_
5、FLAG.C OS_MBOX.C OS_MEM.C OS_MUTEX.C OS_Q.C OS_SEM.C OS_TASK.C OS_TIME.C COS-II.C COS-II.H :这些文件是C/OS-II中所有与处理器类型无关部分的源代码。OS_CPU_A.S OS_CPU_C.C OS_CPU.H :这些文件是与处理器类型相关部分的源代码,在本实验系统中是面向80x86处理器的。INCLUDES.H给整个内核库提供了总体的include文件。OS_CFG.H:C/OS-II的配置文件,定义使用C/OS-II中的哪些功能。3. 代码3.1 Pc.c#define _CRT_SECURE_N
6、O_WARNINGS#include includes.hBOOLEAN lock=FALSE;HANDLE hStdOut = NULL;extern void (*interruptTable)();BOOLEAN PC_GetKey(INT16S *c) if (PC_CHECK_RECURSIVE_CALLS & lock) /检查并避免递归调用 MessageBox(NULL, Recursive call in PC_GetKey, ucos-II, MB_OK); exit(-1); else if (lock) return FALSE; else lock = TRUE; i
7、f (_kbhit() / 检查是否按下按键 *c = _getch(); / 如果按下 lock = FALSE; return (TRUE); *c = 0x00; / 没有按下 return (FALSE);void PC_DispStr(INT8U x, INT8U y, INT8U * s, INT8U color) COORD pos;#ifdef DEBUG_PC printf(PC_DispStr: %sn, s); return;#endif lock) /检查并避免递归调用 MessageBox(NULL, Recursive call in PC_DispStr retu
8、rn; if (hStdOut=NULL) /获取标准输出的句柄 hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); if (x79) | (y24) /检查有效的光标位置 MessageBox(NULL, Invalid screen position in PC_DispStr() pos.X = x; /设置光标位置 pos.Y = y; SetConsoleCursorPosition(hStdOut, pos); SetConsoleTextAttribute(hStdOut, color); /设置文本颜色 puts(s); /显示文本字符串voi
9、d PC_DispChar(INT8U x, INT8U y, INT8U c, INT8U color)PC_DispChar: %cn, c);Recursive call in PC_DispChar24) /检查有效的光标位置Invalid screen position in PC_DispChar() /设置光标位置 putchar(c); /显示字符void PC_DispClrScr(INT8U color)PC_DispClrScrn);Recursive call in PC_DispClrScrif (hStdOut=NULL) /获取标准输出的句柄 pos.X = 0;
10、 pos.Y = 0; /将光标位置设置为窗口顶部 system(cls / 清屏#define NTIMERS 16static INT16U PC_ElapsedOverhead=0;static LARGE_INTEGER PC_startTimeNTIMERS, PC_stopTimeNTIMERS, PC_frequency;void PC_ElapsedInit(void) static BOOLEAN initDone=FALSE; if (initDone) return; QueryPerformanceFrequency(&PC_frequency); /获得CPU频率 P
11、C_ElapsedOverhead = 0; /在PC_Elapsed开始时测量头部文件 PC_ElapsedStart(0); / 和PC_Elapsed结束时 PC_ElapsedOverhead = (INT16U) PC_ElapsedStop(0); initDone=TRUE;void PC_ElapsedStart(INT8U n) if (n = NTIMERS) QueryPerformanceCounter(&PC_startTimen); / 读取CPU内存取的信息INT32U PC_ElapsedStop(INT8U n) LARGE_INTEGER PC_diffTi
12、me; if (n return 0;PC_stopTimen); /读取CPU内存取的信息PC_diffTime.QuadPart = PC_stopTimen.QuadPart - PC_startTimen.QuadPart;/计算差值并将其转换为微秒。 return (INT32U) (PC_diffTime.QuadPart * (_int64) 1000000 / PC_frequency.QuadPart - PC_ElapsedOverhead);void PC_GetDateTime(char *s) SYSTEMTIME now; GetLocalTime(&now); /
13、获取本地日期和时间 sprintf(s, %04d-%02d-%02d %02d:%02d:%02d, /转换成字符串 now.wYear, now.wMonth, now.wDay, now.wHour, now.wMinute, now.wSecond);void PC_IntVectSet(INT8U irq, void (*isr)(void) if (irq 0) & (irq 8) interruptTableirq=isr;void *PC_IntVectGet(INT8U irq) if (irq 8) return interruptTableirq; else return
14、 NULL;3.2 TEST.C主程序int main (void)PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);/清屏 OSInit(); /*初始化uC/OS-II */RandomSem = OSSemCreate(1);/*随机数字信号 */ OSTaskCreate(TaskStart, (void *)0, &TaskStartStkTASK_STK_SIZE - 1, 0); OSStart(); /*开始多任务处理 */void TaskStart (void *pdata) INT16S key; pdata = pdata
15、; /*防止编译警告 */ TaskStartDispInit(); /* 初始化显示 */ TaskStartCreateTasks(); /* 创建所有应用程序任务 */ OSStatInit(); /*初始化uC/OS-II的统计 */ for (;) TaskStartDisp(); /*更新显示 */ if (PC_GetKey(&key) = TRUE) /*查看按键是否已按下 */ if (key = 0x1B) /*如果是,检查这是不是退出地址 */ exit(0); /*结束程序 */ OSCtxSwCtr = 0; /*清除上下文切换计数器 */ OSTimeDlyHMSM
16、(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);#ifdef _WIN32_ PC_DispStr( 0, 1, Original version by Jean J. Labrosse, 80x86-WIN32 port by Werner Zimmermann , DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);#ifd
17、ef _LINUX_ Original version by Jean J. Labrosse, 80x86-LINUX port by Werner Zimmermann 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, P
18、C_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 : CPU Usage: % PC_DispStr( 0, 22, #Task switch/sec: PC_DispStr( 0, 23, /* static void
19、 TaskStartDisp (void) char s80;%5d, OSTaskCtr); /*显示#任务的运行 */ PC_DispStr(18, 21, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);#if OS_TASK_STAT_EN 0sprintf(s, %3d, OSCPUUsage /*OSIdleCtr/(OSIdleCtrMax/100)*/);/*显示CPU使用频率 */ PC_DispStr(36, 21, s, DISP_FGND_YELLOW + DISP_BGND_BLUE); PC_GetDateTime(s); PC_Disp
20、Str(58, 21, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);, OSCtxSwCtr);/*显示每秒上下文切换*/ PC_DispStr(18, 22, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);uCOS-II V%1d.%02d WIN32 V%1d.%02d, OSVersion() / 100, OSVersion() % 100, OSPortVersion() / 100, OSPortVersion() % 100);/*显示uC/OS-II的版本号 */uCOS-II V%1d.%02d LINUX V%1
21、d.%02d /*显示uC/OS-II的版本号 */ PC_DispStr(52, 22, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);static void TaskStartCreateTasks (void) INT8U i; for (i = 0; i N_TASKS; i+) /*创建n_tasks相同的任务 */ TaskDatai = 0 + i; /*每个任务均显示自己的字母代号 */ OSTaskCreate(Task, (void *) &TaskDatai, &TaskStkiTASK_STK_SIZE - 1, (INT8U) (i + 1);void Task (void *pdata) INT8U x; INT8U y; INT8U err;#ifdef _WIN
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1