Presentation is loading. Please wait.

Presentation is loading. Please wait.

5. µC/OS-II应用实例.

Similar presentations


Presentation on theme: "5. µC/OS-II应用实例."— Presentation transcript:

1 5. µC/OS-II应用实例

2 第五章 µC/OS-II应用实例 Borland C 与实例一 实例二 实例三 实例四

3 5.1 Borland C 与实例一 使用计算机作为硬件平台,借助Borland C 和TASM5.0(Borland Turbo Assembler 5.0)软件,实现µC/OS-II的四个实例,其中实例一和实例二直接取自《µC/OS-II原理与ARM应用程序设计》一书 。

4 5.1p01 在Borland C++上实现实例一(1)

5 5.1p02 在Borland C++上实现实例一(2)

6 5.1p03 在Borland C++上实现实例一(3)

7 5.1p04 在Borland C++上实现实例一(4)
子目录名 包括的文件名 文件来源 bsp pc.c和pc.h 《嵌入式实时操作系统µC/OS-II(第2版)》一书附带光盘 config os_cfg.h Micrium-uCOS-II-V286.ZIP app_cfg.h 新建文本文件 ports os_cpu.h,os_cpu_a.asm和os_cpu_c.c ucosii os_core.c,os_dbg.c,os_flag.c,os_mbox.c,os_mem.c,os_mutex.c,os_q.c,os_sem.c,os_task.c,os_time.c,os_tmr.c,ucos_ii.c和ucos_ii.h ucpu object user ex5_1.c和includes.h

8 5.1p05 在Borland C++上实现实例一(5)

9 5.1p06 在Borland C++上实现实例一(6)

10 5.1p07 在Borland C++上实现实例一(7)

11 5.1p08 在Borland C++上实现实例一(8)

12 5.1p09 在Borland C++上实现实例一(9)

13 5.1q01 实例一编译与运行(1)

14 5.1q02 实例一编译与运行(2) 将pc.c文件中的TRUE改为OS_TRUE,FALSE改为OS_FALSE
在文件os_cpu.h的末尾添加如下的函数声明: void OSCtxSw(void); void OSTickISR(void); void OSStartHighRdy(void); void OSIntCtxSw(void);

15 5.1q03 实例一编译与运行(3)

16 5.1q04 实例一编译与运行(4)

17 5.1q05 实例一编译与运行(5)

18 5.1q06 实例一编译与运行(6)

19 5.1q07 实例一编译与运行(7)

20 5.1q08 实例一编译与运行(8)

21 5.1r01 实例一程序解释 实例一工程中需要编写的文件主要是ex5_1.c,位于“D:\xtucosii\ex5_1\user”目录下,下面将该文件分三部分解释,即变量与声明部分、主函数与主任务体以及其他的任务体。

22 5.1r02 ex5_1.c文件中的常量、变量与声明部分 1 #include "includes.h" 2 3 #define TASK_STK_SIZE #define N_TASKS OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; 7 OS_STK TaskStartStk[TASK_STK_SIZE]; 8 char TaskData[N_TASKS]; 9 OS_EVENT *RandomSem; void Task(void *data); 12 void TaskStart(void *data); 13 static void TaskStartCreateTasks(void); 14 static void TaskStartDispInit(void); 15 static void TaskStartDisp(void);

23 5.1r03 头文件includes.h 1 #include <stdio.h> 2 #include <string.h> 3 #include <ctype.h> 4 #include <stdlib.h> 5 #include <conio.h> 6 #include <dos.h> 7 #include <setjmp.h> 8 9 #include "os_cpu.h" 10 #include "os_cfg.h" 11 #include "ucos_ii.h" 12 #include "pc.h"

24 5.1r04 main函数和TaskStart函数(1)
1 void main (void) 2 { 3 PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); 4 5 OSInit(); 6 7 PC_DOSSaveReturn(); 8 PC_VectSet(uCOS, OSCtxSw); 9 10 RandomSem = OSSemCreate(1); OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 0); 13 OSStart(); 14 }

25 5.1r05 main函数和TaskStart函数(2)
16 void TaskStart (void *pdata) 17 { 18 #if OS_CRITICAL_METHOD == 3 19 OS_CPU_SR cpu_sr; 20 #endif 21 //char s[100]; 22 INT16S key; pdata = pdata; TaskStartDispInit();

26 5.1r06 main函数和TaskStart函数(3)
29 OS_ENTER_CRITICAL(); 30 PC_VectSet(0x08, OSTickISR); 31 PC_SetTickRate(OS_TICKS_PER_SEC); 32 OS_EXIT_CRITICAL(); OSStatInit(); TaskStartCreateTasks();

27 5.1r07 main函数和TaskStart函数(4)
38 for (;;) { 39 TaskStartDisp(); if (PC_GetKey(&key) == OS_TRUE) { 43 if (key == 0x1B) { 44 PC_DOSReturn(); 45 } 46 } OSCtxSwCtr = 0; 49 OSTimeDlyHMSM(0, 0, 1, 0); 50 } 51 }

28 5.1r08 文件ex5_1.c中其他函数(1) 1 static void TaskStartDispInit (void) 2 { 3 PC_DispStr(0,0,"uC/OS-II,TheReal-Time Kernel",DISP_FGND_WHITE+DISP_BGND_RED+ DISP_BLINK); 4 PC_DispStr( 0, 1, " Jean J. Labrosse ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 5 PC_DispStr( 0, 2, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 6 PC_DispStr( 0, 3, " EXAMPLE #1 ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 7 PC_DispStr( 0, 4, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 8 PC_DispStr( 0, 5, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 9 PC_DispStr( 0, 6, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 10 PC_DispStr( 0, 7, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 11 PC_DispStr( 0, 8, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 12 PC_DispStr( 0, 9, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 13 PC_DispStr( 0, 10, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 14 PC_DispStr( 0, 11, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 15 PC_DispStr( 0, 12, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 16 PC_DispStr( 0, 13, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);

29 5.1r09 文件ex5_1.c中其他函数(2) 17 PC_DispStr( 0, 14, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 18 PC_DispStr( 0, 15, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 19 PC_DispStr( 0, 16, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 20 PC_DispStr( 0, 17, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 21 PC_DispStr( 0, 18, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 22 PC_DispStr( 0, 19, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 23 PC_DispStr( 0, 20, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 24 PC_DispStr( 0, 21, " ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 25 PC_DispStr(0, 22, "#Tasks: CPU Usage: %", DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY); 26 PC_DispStr(0,23," #Task switch/sec: ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 27 PC_DispStr( 0, 24, " <-PRESS 'ESC' TO QUIT-> ",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY+DISP_BLINK); 28 }

30 5.1r10 文件ex5_1.c中其他函数(3) 30 static void TaskStartDisp (void) 31 { 32 char s[80]; sprintf(s, "%5d", OSTaskCtr); 36 PC_DispStr(18, 22, s, DISP_FGND_YELLOW + DISP_BGND_BLUE); #if OS_TASK_STAT_EN > 0 39 sprintf(s, "%3d", OSCPUUsage); 40 PC_DispStr(36, 22, s, DISP_FGND_YELLOW + DISP_BGND_BLUE); 41 #endif

31 5.1r11 文件ex5_1.c中其他函数(4) 43 sprintf(s, "%5d", OSCtxSwCtr); 44 PC_DispStr(18, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE); sprintf(s, "V%1d.%02d", OSVersion() / 100, OSVersion() % 100); 47 PC_DispStr(75, 24, s, DISP_FGND_YELLOW + DISP_BGND_BLUE); switch (_8087) { 50 case 0: 51 PC_DispStr(71, 22, " NO FPU ", DISP_FGND_YELLOW + DISP_BGND_BLUE); 52 break; case 1: 55 PC_DispStr(71, 22, " 8087 FPU", DISP_FGND_YELLOW + DISP_BGND_BLUE); 56 break;

32 5.1r12 文件ex5_1.c中其他函数(5) 58 case 2: 59 PC_DispStr(71, 22, "80287 FPU", DISP_FGND_YELLOW + DISP_BGND_BLUE); 60 break; case 3: 63 PC_DispStr(71, 22, "80387 FPU", DISP_FGND_YELLOW + DISP_BGND_BLUE); 64 break; 65 } 66 }

33 5.1r13 文件ex5_1.c中其他函数(6) 68 static void TaskStartCreateTasks (void) 69 { 70 INT8U i; for (i = 0; i < N_TASKS; i++) { 74 TaskData[i] = '0' + i; 75 OSTaskCreate(Task, (void *)&TaskData[i], &TaskStk[i][TASK_STK_SIZE - 1], i + 1); 76 } 77 }

34 5.1r14 文件ex5_1.c中其他函数(7) 79 void Task (void *pdata) 80 { 81 INT8U x; 82 INT8U y; 83 INT8U err; for (;;) { 87 OSSemPend(RandomSem, 0, &err); 88 x = random(80); 89 y = random(16); 90 OSSemPost(RandomSem); PC_DispChar(x, y + 5, *(char *)pdata, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 93 OSTimeDly(1); 94 } 95 }

35 5.1s01 µC/OS-View与实例一(1)

36 5.1s02 µC/OS-View与实例一(2)

37 5.1s03 µC/OS-View与实例一(3)

38 5.1s04 µC/OS-View与实例一(4)

39 5.1t01 工程ex5_1v修改与运行(1) “D:\xtucosii\ex5_1v\user”目录下的文件includes.h中添加以下包括文件,即 #include "os_viewc.h" #include "os_view.h"

40 5.1t02 工程ex5_1v修改与运行(2) D:\xtucosii\ex5_1v\ports”目录下的文件os_cpu_c.c中的三个函数作如下修改,即: 1 void OSTaskCreateHook (OS_TCB *ptcb) 2 { OSView_TaskCreateHook(ptcb); 4 } 5 6 void OSTaskSwHook (void) 7 { OSView_TaskSwHook(); 9 } 10 11 void OSTimeTickHook (void) 12 { OSView_TickHook(); 14 }

41 5.1t03 工程ex5_1v修改与运行(3) 修改目录“D:\xtucosii\ex5_1v\user”下的文件ex5_1v.c中的main函数和TaskStartCreateTasks函数,即使用OSTaskCreateExt函数创建任务,并为每个任务命名,修改后的函数如下: 1 void main (void) 2 { INT8U err; 4 PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

42 5.1t04 工程ex5_1v修改与运行(3) 7 OSInit(); 8 9 PC_DOSSaveReturn(); 10 PC_VectSet(uCOS, OSCtxSw); RandomSem = OSSemCreate(1); OSTaskCreateExt(TaskStart, 15 (void *)0, 16 &TaskStartStk[TASK_STK_SIZE - 1], 17 0, 18 0, 19 &TaskStartStk[0], 20 TASK_STK_SIZE, 21 (void *)0, 22 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 23 OSTaskNameSet(0,"Task0",&err); 24 OSStart(); 25 }

43 5.1t05 工程ex5_1v修改与运行(3) 27 static void TaskStartCreateTasks (void) 28 { 29 INT8U i; 30 INT8U err; 31 INT8U strName[16];

44 5.1t06 工程ex5_1v修改与运行(3) 34 for (i = 0; i < N_TASKS; i++) { 35 TaskData[i] = '0' + i; 36 OSTaskCreateExt(Task, 37 (void *)&TaskData[i], 38 &TaskStk[i][TASK_STK_SIZE - 1], 39 i + 1, 40 i + 1, 41 &TaskStk[i][0], 42 TASK_STK_SIZE, 43 (void *)0, 44 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 45 sprintf(strName,"Task%d",i+1); 46 OSTaskNameSet(i + 1,strName,&err); 47 } 48 }

45 5.1t07 工程ex5_1v修改与运行(4) 文件ex5_1v.c的函数TaskStart中代码“OSStatInit();”后添加代码“OSView_Init();”,即加入初始化µC/OS-View的代码,这个函数将调用OSView_InitOS函数创建一个为µC/OS-View服务的任务OSView_Task,优先级号为OS_VIEW_TASK_PRIO。

46 5.1t08 工程ex5_1v修改与运行(5) 去掉目录“D:\xtucosii\ex5_1v”下所有文件的只读属性。

47 5.1t09 工程ex5_1v修改与运行(6) 设置工程选项“Project Options|Directories”为: Include为:c:\bc5\include; d:\xtucosii\ex5_1v\user; d:\xtucosii\ex5_1v\ucosii; d:\xtucosii\ ex5_1v\ports; d:\xtucosii\ex5_1v\bsp; d:\xtucosii\ex5_1v\ucview; d:\xtucosii\ex5_1v\config; Source为:d:\xtucosii\ex5_1v\user; d:\xtucosii\ex5_1v\ucosii; d:\xtucosii\ex5_1v\ports; d:\ xtucosii\ex5_1v\bsp; d:\xtucosii\ex5_1v\ucview; Intermediate和Final均为D:\xtucosii\ex5_1v\object。

48 5.1t10 工程ex5_1v修改与运行(7) 目录“D:\xtucosii\ex5_1v\ucview\”下的文件os_view.h中添加如下宏定义: #define OS_VIEW_MODULE 1 #define OS_VIEW_PARSE_TASK 1 #define OS_VIEW_TASK_STK_SIZE 128 #define OS_VIEW_TASK_PRIO 38 #define OS_VIEW_TASK_ID 38

49 5.1t11 工程ex5_1v修改与运行(8) 修改os_view.c文件中的函数OSView_TxStoINT32U和OSView_TxStoPtr,如下: 1 static void OSView_TxStoINT32U (INT32U tx_data) 2 { OSView_TxStoINT16U((INT16U)(tx_data >> 16)); OSView_TxStoINT16U((INT16U)(tx_data & 0x0000FFFFL)); 5 }

50 5.1t12 工程ex5_1v修改与运行(8) 8 static void OSView_TxStoPtr (void *ptr) 9 { 10 INT32U tx_data; tx_data = (INT32U)ptr; 14 OSView_TxStoINT16U((INT16U)(tx_data >> 16)); 15 OSView_TxStoINT16U((INT16U)(tx_data & 0x0000FFFFL)); 16 }

51 5.1t13 工程ex5_1v修改与运行(8) 修改os_view.c文件中的函数OSView_Init(位于第127行),将其参数“INT32U baud_rate”改为void,即“void OSView_Init (void)”;然后,该函数的最后一行(文件中第150行)的语句改为:“OSView_InitTarget();”,即去掉其参数。

52 5.1t14 工程ex5_1v修改与运行(9) 修改os_view.h中函数OSView_Init和OSView_InitTarget的声明(位于文件中第72行和第85行)如下 void OSView_Init(void); void OSView_InitTarget(void);

53 5.1t15 工程ex5_1v修改与运行(10) 修改os_viewc.c中的函数OSView_CfgPort的第一个参数,由“INT16U baud”改为“INT32U baud”,位于文件中第83行和第470行。

54 5.1t16 工程ex5_1v修改与运行(11) 将os_view.c文件中的函数OSView_TickHook和OSView_TimeGetCycles删掉或注释掉,位于该文件中的第312~360行。

55 5.1t17 VSPD6软件

56 5.1t18 工程ex5_1v执行结果

57 5.1t19 上位机软件µC/OS-View 3.10g实时跟踪工程ex5_1v运行情况

58 5.2 实例二 实例二将进一步介绍如何动态检查µC/OS-II程序中每个任务的堆栈使用情况

59 5.2p01 工程ex5_2

60 5.2p02 工程ex5_2执行情况

61 5.2q01 任务函数体Task1(1) 1 void Task1 (void *pdata) 2 { 3 INT8U err; 4 OS_STK_DATA data; 5 INT16U time; 6 INT8U i; 7 char s[80]; 8 9 pdata = pdata;

62 5.2q02 任务函数体Task1(2) 10 for (;;) { 11 for (i = 0; i < 7; i++) { 12 PC_ElapsedStart(); 13 err = OSTaskStkChk(TASK_START_PRIO + i, &data); 14 time = PC_ElapsedStop(); 15 if (err == OS_ERR_NONE) { 16 sprintf(s, "%4ld %4ld %4ld %6d", 17 data.OSFree + data.OSUsed, 18 data.OSFree, 19 data.OSUsed, 20 time); 21 PC_DispStr(19, 12 + i, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 22 } 23 } 24 OSTimeDlyHMSM(0, 0, 0, 100); 25 } 26 }

63 5.2q03 任务函数体TaskClk 1 void TaskClk (void *data) 2 { 3 char s[40]; 4 5 data = data; 6 for (;;) { 7 PC_GetDateTime(s); 8 PC_DispStr(60, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE); 9 OSTimeDly(OS_TICKS_PER_SEC); 10 } 11 }

64 5.2q04 任务函数体Task4 1 void Task4 (void *data) 2 { 3 char txmsg; 4 INT8U err; 5 6 data = data; 7 txmsg = 'A'; 8 for (;;) { 9 OSMboxPost(TxMbox, (void *)&txmsg); 10 OSMboxPend(AckMbox, 0, &err); 11 txmsg++; 12 if (txmsg == 'Z') { 13 txmsg = 'A'; 14 } 15 } 16 }

65 5.2q05 任务函数体Task5 19 void Task5 (void *data) 20 { 21 char *rxmsg; 22 INT8U err; data = data; 25 for (;;) { 26 rxmsg = (char *)OSMboxPend(TxMbox, 0, &err); 27 PC_DispChar(70, 18, *rxmsg, DISP_FGND_YELLOW + DISP_BGND_BLUE); 28 OSTimeDlyHMSM(0, 0, 1, 0); 29 OSMboxPost(AckMbox, (void *)1); 30 } 31 }

66 5.2q06 任务Task4和Task5执行流程

67 5.3 实例三 实例三主要介绍任务控制块扩展数据结构的使用方法以及各种钩子函数的使用方法

68 5.3p01 工程ex5_3执行情况

69 5.3q01 钩子函数OSTaskSwHook 1 void OSTaskSwHook (void) 2 { 3 INT16U time; 4 TASK_USER_DATA *puser; 5 6 time = PC_ElapsedStop(); 7 PC_ElapsedStart(); 8 puser = OSTCBCur->OSTCBExtPtr; 9 if (puser != (TASK_USER_DATA *)0) { 10 puser->TaskCtr++; 11 puser->TaskExecTime = time; 12 puser->TaskTotExecTime += time; 13 } 14 }

70 5.3q02 修正时间后的钩子函数OSTaskSwHook(1)
1 void OSTaskSwHook (void) 2 { 3 static BOOLEAN isNotFirstRun=OS_FALSE; 4 INT16U time; 5 TASK_USER_DATA *puser; 6 7 if(isNotFirstRun) 8 time = PC_ElapsedStop(); 9 PC_ElapsedStart();

71 5.3q03 修正时间后的钩子函数OSTaskSwHook(2)
10 if(isNotFirstRun) 11 { 12 puser = OSTCBCur->OSTCBExtPtr; 13 if (puser != (TASK_USER_DATA *)0) { 14 puser->TaskCtr++; 15 puser->TaskExecTime = time; 16 puser->TaskTotExecTime += time; 17 } 18 } 19 else 20 { 21 isNotFirstRun=OS_TRUE; 22 } 23 }

72 5.3q04 钩子函数OSTaskStatHook(1)
1 void OSTaskStatHook (void) 2 { 3 char s[80]; 4 INT8U i; 5 INT32U total; 6 INT8U pct; 7 8 total = 0L; 9 for (i = 0; i < 7; i++) { 10 total += TaskUserData[i].TaskTotExecTime; 11 DispTaskStat(i); 12 }

73 5.3q05 钩子函数OSTaskStatHook(2)
13 if (total > 0) { 14 for (i = 0; i < 7; i++) { 15 pct = (INT8U)(100 * TaskUserData[i].TaskTotExecTime / total); 16 sprintf(s, "%3d %%", pct); 17 PC_DispStr(62, i + 11, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 18 } 19 } 20 if (total > L) { 21 for (i = 0; i < 7; i++) { 22 TaskUserData[i].TaskTotExecTime = 0L; 23 } 24 } 25 }

74 5.4 实例四 实例四直接使用硬件浮点数协处理器,而不像其他三个实例使用仿真协处理器,因此,在调用OSTaskCreateExt函数时,最后一个参数应使用OS_TASK_OPT_SAVE_FP,表示将对硬件浮点数协处理器相关的寄存器进行保护,即伴随着任务环境进行相关的入栈和出栈操作。

75 5.4p01 工程ex5_4

76 5.4p02 工程ex5_4创建向导

77 5.4p03 工程ex5_4执行情况

78 5.4q01 Task函数(1) 1 void Task (void *pdata) 2 { 3 FP32 x; 4 FP32 y; 5 FP32 angle; 6 FP32 radians; 7 char s[81]; 8 INT8U ypos; 9 10 ypos = *(INT8U *)pdata + 7; 11 angle = (FP32)(*(INT8U *)pdata) * (FP32)36.0; 12 for (;;) { 13 radians = (FP32)2.0 * (FP32) * angle / (FP32)360.0; 14 x = cos(radians); 15 y = sin(radians);

79 5.4q02 Task函数(2) 16 sprintf(s, " %2d %8.3f %8.3f %8.3f", *(INT8U *)pdata, angle, x, y); 17 PC_DispStr(0, ypos, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); 18 if (angle >= (FP32)360.0) { 19 angle = (FP32)0.0; 20 } else { 21 angle += (FP32)0.01; 22 } 23 OSTimeDly(1); 24 } 25 }

80 需要掌握的知识点 四个实例的创建与运行 掌握任务的创建与工作原理
设计一个应用程序,每2秒自动产生一个16位的随机整数,将其转化为格雷码显示。 注:假设二进制码为c[i],0≤i<16,产生的格雷码记为d[k],0≤k<16,则d[i]=c[i]⊕c[i+1],0≤i<16,c[16]=0。


Download ppt "5. µC/OS-II应用实例."

Similar presentations


Ads by Google