Presentation is loading. Please wait.

Presentation is loading. Please wait.

3. µC/OS-II内核 2019/4/11.

Similar presentations


Presentation on theme: "3. µC/OS-II内核 2019/4/11."— Presentation transcript:

1 3. µC/OS-II内核 2019/4/11

2 3. µC/OS-II内核 µC/OS-II初始化 空闲任务控制块链表 空闲事件控制块链表 空闲内存控制块链表 任务就绪组和任务就绪表
统计任务 定时器任务 空闲事件标志组链表 空闲消息队列链表 时钟节拍 任务状态 任务调度与内核函数 多任务启动 2019/4/11

3 µC/OS-II应用程序的典型结构 ? 调用OSInit()初始化µC/OS-II操作系统 调用OSTaskCreate或OSTaskCreateExt创建用户任务 调用OSStart()开启多任务 2019/4/11

4 µC/OS-II应用程序主函数 ? 1 void main(void) 2 { 3 OSInit(); 4 OSTaskCreateExt(AppTaskStart, 5 (void *)0, 6 &AppTaskStartStk[TASK_START_STK_SIZE-1], 7 AppTaskStartPrio, 8 AppTaskStartID, 9 &AppTaskStartStk[0], 10 TASK_START_STK_SIZE, 11 (void *)0, 12 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 13 OSStart(); 14 } 2019/4/11

5 3.1 µC/OS-II初始化完成哪些工作? µC/OS-II应用程序设计的第一步是调用OSInit()函数对µC/OS-II操作系统初始化 初始化µC/OS-II操作系统的全局变量或数据结构 建立空闲任务、统计任务和定时器管理等系统服务。 2019/4/11

6 3.1p01 OSInit函数代码(1) 1 void OSInit (void) 2 { 3 OSInitHookBegin(); /* Call port specific initialization code */ 4 5 OS_InitMisc(); /* Initialize miscellaneous variables */ 6 7 OS_InitRdyList(); /* Initialize the Ready List */ 8 9 OS_InitTCBList(); /* Initialize the free list of OS_TCBs */ OS_InitEventList(); /* Initialize the free list of OS_EVENTs */ 2019/4/11

7 3.1p02 OSInit函数代码(2) 13 #if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) 14 OS_FlagInit(); /* Initialize the event flag structures */ 15 #endif #if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) 18 OS_MemInit(); /* Initialize the memory manager */ 19 #endif #if (OS_Q_EN > 0) && (OS_MAX_QS > 0) 22 OS_QInit(); /* Initialize the message queue structures */ 23 #endif 2019/4/11

8 3.1p03 OSInit函数代码(3) 25 OS_InitTaskIdle(); /* Create the Idle Task */ 26 #if OS_TASK_STAT_EN > 0 27 OS_InitTaskStat(); /* Create the Statistic Task */ 28 #endif #if OS_TMR_EN > 0 31 OSTmr_Init(); /* Initialize the Timer Manager */ 32 #endif 2019/4/11

9 3.1p03 OSInit函数代码(4) 34 OSInitHookEnd(); /* Call port specific init. code */ #if OS_DEBUG_EN > 0 37 OSDebugInit(); 38 #endif 39 } 2019/4/11

10 3.1p04 什么是钩子函数? 所谓的钩子函数是指那些插入到某些函数中为扩展这些函数功能的函数,一般地,钩子函数为第三方软件开发人员提供扩充软件功能的入口点,同样道理,µC/OS-II中有大量的钩子函数,用户不需要修改µC/OS-II内核程序代码,而只需要向钩子函数添加代码就可以扩充µC/OS-II的功能。 2019/4/11

11 3.1q01 OSInitHookBegin()函数代码(1)
1 #if OS_CPU_HOOKS_EN > 0 && OS_VERSION > void OSInitHookBegin (void) 3 { 4 INT32U size; 5 OS_STK *pstk; 6 7 /* Clear exception stack for stack checking.*/ 8 pstk = &OS_CPU_ExceptStk[0]; 9 size = OS_CPU_EXCEPT_STK_SIZE; 2019/4/11

12 3.1q02 OSInitHookBegin()函数代码(2)
10 while (size > 0) { 11 size--; 12 *pstk++ = (OS_STK)0; 13 } #if OS_STK_GROWTH == 1 16 OS_CPU_ExceptStkBase = &OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE - 1]; 17 #else 18 OS_CPU_ExceptStkBase = &OS_CPU_ExceptStk[0]; 19 #endif 2019/4/11

13 3.1q03 OSInitHookBegin()函数代码(3)
21 #if OS_TMR_EN > 0 22 OSTmrCtr = 0; 23 #endif 24 myInitHookBegin(); 25 } 26 #endif 2019/4/11

14 3.1r01 µC/OS-II自定义变量类型有哪些?
1 typedef unsigned char BOOLEAN; 2 typedef unsigned char INT8U; 3 typedef signed char INT8S; 4 typedef unsigned short INT16U; 5 typedef signed short INT16S; 6 typedef unsigned int INT32U; 7 typedef signed int INT32S; 8 typedef float FP32; 9 typedef double FP64; typedef unsigned int OS_STK; 12 typedef unsigned int OS_CPU_SR; 2019/4/11

15 3.1s01 OS_InitMisc函数代码(1) 1 static void OS_InitMisc (void) 2 { 3 #if OS_TIME_GET_SET_EN > 0 4 OSTime = 0L; 5 #endif 6 7 OSIntNesting = 0; 8 OSLockNesting = 0; 9 2019/4/11

16 3.1s02 OS_InitMisc函数代码(2) 10 OSTaskCtr = 0; OSRunning = OS_FALSE; OSCtxSwCtr = 0; 15 OSIdleCtr = 0L; #if OS_TASK_STAT_EN > 0 18 OSIdleCtrRun = 0L; 19 OSIdleCtrMax = 0L; 20 OSStatRdy = OS_FALSE; 21 #endif 22 } 2019/4/11

17 3.2 空闲任务控制块链表 2019/4/11

18 3.2p01 OS_TCB结构体定义(1) 1 typedef struct os_tcb { 2 OS_STK *OSTCBStkPtr; 3 4 #if OS_TASK_CREATE_EXT_EN > 0 5 void *OSTCBExtPtr; 6 OS_STK *OSTCBStkBottom; 7 INT32U OSTCBStkSize; 8 INT16U OSTCBOpt; 9 INT16U OSTCBId; 10 #endif 2019/4/11

19 3.2p02 OS_TCB结构体定义(2) 12 struct os_tcb *OSTCBNext; 13 struct os_tcb *OSTCBPrev; #if (OS_EVENT_EN) || (OS_FLAG_EN > 0) 16 OS_EVENT *OSTCBEventPtr; 17 #endif #if (OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0) 20 OS_EVENT **OSTCBEventMultiPtr; 21 #endif 2019/4/11

20 3.2p03 OS_TCB结构体定义(3) 23 #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) 24 void *OSTCBMsg; 25 #endif #if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) 28 #if OS_TASK_DEL_EN > 0 29 OS_FLAG_NODE *OSTCBFlagNode; 30 #endif 31 OS_FLAGS OSTCBFlagsRdy; 32 #endif 2019/4/11

21 3.2p04 OS_TCB结构体定义(4) 34 INT16U OSTCBDly; 35 INT8U OSTCBStat; 36 INT8U OSTCBStatPend; 37 INT8U OSTCBPrio; INT8U OSTCBX; 40 INT8U OSTCBY; 2019/4/11

22 3.2p05 OS_TCB结构体定义(5) 41 #if OS_LOWEST_PRIO <= INT8U OSTCBBitX; 43 INT8U OSTCBBitY; 44 #else 45 INT16U OSTCBBitX; 46 INT16U OSTCBBitY; 47 #endif 2019/4/11

23 3.2p06 OS_TCB结构体定义(6) 49 #if OS_TASK_DEL_EN > 0 50 INT8U OSTCBDelReq; 51 #endif #if OS_TASK_PROFILE_EN > 0 54 INT32U OSTCBCtxSwCtr; 55 INT32U OSTCBCyclesTot; 56 INT32U OSTCBCyclesStart; 57 OS_STK *OSTCBStkBase; 58 INT32U OSTCBStkUsed; 59 #endif 2019/4/11

24 3.2p07 OS_TCB结构体定义(7) 61 #if OS_TASK_NAME_SIZE > 1 62 INT8U OSTCBTaskName[OS_TASK_NAME_SIZE]; 63 #endif 64 } OS_TCB; 2019/4/11

25 3.2q01 初始化空闲TCB链表(1) 1 static void OS_InitTCBList (void) 2 { 3 INT8U i; 4 OS_TCB *ptcb1; 5 OS_TCB *ptcb2; OS_MemClr((INT8U *)&OSTCBTbl[0], sizeof(OSTCBTbl)); 9 OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl)); 2019/4/11

26 3.2q02 初始化空闲TCB链表(2) 10 ptcb1 = &OSTCBTbl[0]; 11 ptcb2 = &OSTCBTbl[1]; 12 for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) { 13 ptcb1->OSTCBNext = ptcb2; 14 #if OS_TASK_NAME_SIZE > 1 15 ptcb1->OSTCBTaskName[0] = '?'; 16 ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL; 17 #endif 18 ptcb1++; 19 ptcb2++; 20 } 2019/4/11

27 3.2q03 初始化空闲TCB链表(3) 21 ptcb1->OSTCBNext = (OS_TCB *)0; 22 #if OS_TASK_NAME_SIZE > 1 23 ptcb1->OSTCBTaskName[0] = '?'; 24 ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL; 25 #endif 26 OSTCBList = (OS_TCB *)0; 27 OSTCBFreeList = &OSTCBTbl[0]; 28 } 2019/4/11

28 3.2q04 OS_MemClr函数 1 void OS_MemClr (INT8U *pdest, INT16U size) 2 { 3 while (size > 0) { 4 *pdest++ = (INT8U)0; 5 size--; 6 } 7 } 2019/4/11

29 3.2q05 任务优先级表 2019/4/11

30 3.3 空闲事件控制块链表 2019/4/11

31 3.3p01 事件控制块结构体 (1) 1 #if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0) 2 typedef struct os_event { 3 INT8U OSEventType; 4 void *OSEventPtr; 5 INT16U OSEventCnt; 6 #if OS_LOWEST_PRIO <= 63 7 INT8U OSEventGrp; 8 INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; 9 #else 10 INT16U OSEventGrp; 11 INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; 12 #endif 2019/4/11

32 3.3p02 事件控制块结构体 (2) 14 #if OS_EVENT_NAME_SIZE > 1 15 INT8U OSEventName[OS_EVENT_NAME_SIZE]; 16 #endif 17 } OS_EVENT; 18 #endif 2019/4/11

33 3.3q01 初始化空闲事件控制块链表(1) 1 static void OS_InitEventList (void) 2 { 3 #if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0) 4 #if (OS_MAX_EVENTS > 1) 5 INT16U i; 6 OS_EVENT *pevent1; 7 OS_EVENT *pevent2; 8 2019/4/11

34 3.3q02 初始化空闲事件控制块链表(2) 10 OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); 11 pevent1 = &OSEventTbl[0]; 12 pevent2 = &OSEventTbl[1]; 13 for (i = 0; i < (OS_MAX_EVENTS - 1); i++) { 14 pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; 15 pevent1->OSEventPtr = pevent2; 16 #if OS_EVENT_NAME_SIZE > 1 17 pevent1->OSEventName[0] = '?'; 18 pevent1->OSEventName[1] = OS_ASCII_NUL; 19 #endif 20 pevent1++; 21 pevent2++; 22 } 2019/4/11

35 3.3q03 初始化空闲事件控制块链表(3) 23 pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; 24 pevent1->OSEventPtr = (OS_EVENT *)0; 25 #if OS_EVENT_NAME_SIZE > 1 26 pevent1->OSEventName[0] = '?'; 27 pevent1->OSEventName[1] = OS_ASCII_NUL; 28 #endif 29 OSEventFreeList = &OSEventTbl[0]; 2019/4/11

36 3.3q04 初始化空闲事件控制块链表(4) 30 #else 31 OSEventFreeList = &OSEventTbl[0]; 32 OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED; 33 OSEventFreeList->OSEventPtr = (OS_EVENT *)0; 34 #if OS_EVENT_NAME_SIZE > 1 35 OSEventFreeList->OSEventName[0] = '?'; 36 OSEventFreeList->OSEventName[1] = OS_ASCII_NUL; 37 #endif 38 #endif 39 #endif 40 } 2019/4/11

37 3.3q05 空闲事件控制块指针OSEventFreeList和事件列表OSEventTbl定义
1 #if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0) 2 OS_EXT OS_EVENT *OSEventFreeList; 3 OS_EXT OS_EVENT OSEventTbl[OS_MAX_EVENTS]; 4 #endif 2019/4/11

38 3.4 空闲内存控制块链表 2019/4/11

39 3.4p01 内存控制块(MCB)结构体类型定义(1)
1 #if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) 2 typedef struct os_mem { 3 void *OSMemAddr; 4 void *OSMemFreeList; 5 INT32U OSMemBlkSize; 6 INT32U OSMemNBlks; 7 INT32U OSMemNFree; 8 #if OS_MEM_NAME_SIZE > 1 9 INT8U OSMemName[OS_MEM_NAME_SIZE]; 10 #endif 11 } OS_MEM; 2019/4/11

40 3.4p02 内存控制块(MCB)结构体类型定义(2)
14 typedef struct os_mem_data { 15 void *OSAddr; 16 void *OSFreeList; 17 INT32U OSBlkSize; 18 INT32U OSNBlks; 19 INT32U OSNFree; 20 INT32U OSNUsed; 21 } OS_MEM_DATA; 22 #endif 2019/4/11

41 3.4q01 OSMemFreeList和OSMemTbl定义
1 #if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) 2 OS_EXT OS_MEM *OSMemFreeList; 3 OS_EXT OS_MEM OSMemTbl[OS_MAX_MEM_PART 4 #endif 2019/4/11

42 3.4q02 初始化内存管理器(1) 1 void OS_MemInit (void) 2 { 3 #if OS_MAX_MEM_PART == 1 4 OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); 5 OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; 6 #if OS_MEM_NAME_SIZE > 1 7 OSMemFreeList->OSMemName[0] = '?'; 8 OSMemFreeList->OSMemName[1] = OS_ASCII_NUL; 9 #endif 10 #endif #if OS_MAX_MEM_PART >= 2 13 OS_MEM *pmem; 14 INT16U i; 2019/4/11

43 3.4q03 初始化内存管理器(2) 17 OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); 18 pmem = &OSMemTbl[0]; 19 for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) { 20 pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; 21 #if OS_MEM_NAME_SIZE > 1 22 pmem->OSMemName[0] = '?'; 23 pmem->OSMemName[1] = OS_ASCII_NUL; 24 #endif 25 pmem++; 26 } 2019/4/11

44 3.4q04 初始化内存管理器(3) 27 pmem->OSMemFreeList = (void *)0; 28 #if OS_MEM_NAME_SIZE > 1 29 pmem->OSMemName[0] = '?'; 30 pmem->OSMemName[1] = OS_ASCII_NUL; 31 #endif OSMemFreeList = &OSMemTbl[0]; 34 #endif 35 } 2019/4/11

45 3.5 任务就绪组和任务就绪表 2019/4/11

46 2019/4/11

47 3.5p01任务就绪组和就绪表初始化函数OS_InitRdyList (1)
1 static void OS_InitRdyList (void) 2 { 3 INT8U i; 4 #if OS_LOWEST_PRIO <= 63 5 INT8U *prdytbl; 6 #else 7 INT16U *prdytbl; 8 #endif OSRdyGrp = 0; 12 prdytbl = &OSRdyTbl[0]; 13 for (i = 0; i < OS_RDY_TBL_SIZE; i++) { 14 *prdytbl++ = 0; 15 } 2019/4/11

48 3.5p02任务就绪组和就绪表初始化函数OS_InitRdyList (2)
17 OSPrioCur = 0; 18 OSPrioHighRdy = 0; OSTCBHighRdy = (OS_TCB *)0; 21 OSTCBCur = (OS_TCB *)0; 22 } 2019/4/11

49 3.5p03 任务就绪表和就绪组相关的全局变量(1) 1 OS_EXT INT8U OSPrioCur; 2 OS_EXT INT8U OSPrioHighRdy; 3 4 #if OS_LOWEST_PRIO <= 63 5 OS_EXT INT8U OSRdyGrp; 6 OS_EXT INT8U OSRdyTbl[OS_RDY_TBL_SIZE]; 7 #else 8 OS_EXT INT16U OSRdyGrp; 9 OS_EXT INT16U OSRdyTbl[OS_RDY_TBL_SIZE]; 10 #endif OS_EXT OS_TCB *OSTCBCur; 13 OS_EXT OS_TCB *OSTCBHighRdy; 2019/4/11

50 3.5p04 任务就绪表和就绪组相关的全局变量(2) 1 #if OS_LOWEST_PRIO <= 63 2 #define OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 8 + 1) 3 #define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / 8 + 1) 4 #else 5 #define OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / ) 6 #define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / ) 7 #endif 2019/4/11

51 3.5p05 根据就绪任务的优先级prio计算其在任务就绪组和就绪表中的位置
1 #if OS_LOWEST_PRIO <= 63 2 ptcb->OSTCBY = (INT8U)(prio >> 3); 3 ptcb->OSTCBX = (INT8U)(prio & 0x07); 4 ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY); 5 ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); 6 #else 7 ptcb->OSTCBY = (INT8U)((prio >> 4) & 0xFF); 8 ptcb->OSTCBX = (INT8U) (prio & 0x0F); 9 ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY); 10 ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX); 11 #endif OSRdyGrp |= ptcb->OSTCBBitY; 14 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; 2019/4/11

52 3.5p06 根据任务的优先级prio清除其在任务就绪组和就绪表中的1
1 #if OS_LOWEST_PRIO <= 63 2 ptcb->OSTCBY = (INT8U)(prio >> 3); 3 ptcb->OSTCBX = (INT8U)(prio & 0x07); 4 ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY); 5 ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); 6 #else 7 ptcb->OSTCBY = (INT8U)((prio >> 4) & 0xFF); 8 ptcb->OSTCBX = (INT8U) (prio & 0x0F); 9 ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY); 10 ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX); 11 #endif if((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX)==0) { 14 OSRdyGrp &= ~ptcb->OSTCBBitY; 15 } 2019/4/11

53 3.5p07优先级解映射查找表OSUnMapTbl
1 INT8U const OSUnMapTbl[256] = { 2 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 3 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 8 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 9 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 10 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 11 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 12 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 13 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 14 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 15 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 16 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 17 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 18 }; 2019/4/11

54 3.5p08 由任务就绪组和就绪表查最高优先级任务优先级号prio(1)
1 #if OS_LOWEST_PRIO <= 63 2 INT8U y; y = OSUnMapTbl[OSRdyGrp]; 6 OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); 7 #else 8 INT8U y; 9 INT16U *ptbl; 10 2019/4/11

55 3.5p09 由任务就绪组和就绪表查最高优先级任务优先级号prio(2)
12 if ((OSRdyGrp & 0xFF) != 0) { 13 y = OSUnMapTbl[OSRdyGrp & 0xFF]; 14 } else { 15 y = OSUnMapTbl[(OSRdyGrp >> 8) & 0xFF] + 8; 16 } 17 ptbl = &OSRdyTbl[y]; 18 if ((*ptbl & 0xFF) != 0) { 19 OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl & 0xFF)]); 20 } else { 21 OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8); 22 } 23 #endif 2019/4/11

56 3.6 什么是空闲任务 空闲任务是µC/OS-II的系统任务,当没有用户任务执行时,µC/OS-II将切换到空闲任务执行,空闲任务具有最低的优先级,空闲任务的优先级总是OS_LOWEST_PRIO,并且空闲任务总是就绪的。 2019/4/11

57 3.6p01 空闲任务 1 void OS_TaskIdle (void *p_arg) 2 { 3 #if OS_CRITICAL_METHOD == 3 4 OS_CPU_SR cpu_sr = 0; 5 #endif (void)p_arg; 10 for (;;) { 11 OS_ENTER_CRITICAL(); 12 OSIdleCtr++; 13 OS_EXIT_CRITICAL(); 14 OSTaskIdleHook(); 15 } 16 } 2019/4/11

58 3.6p02 创建空闲任务函数OS_InitTaskIdle(1)
1 static void OS_InitTaskIdle (void) 2 { 3 #if OS_TASK_NAME_SIZE > 7 4 INT8U err; 5 #endif 6 7 2019/4/11

59 3.6p03 创建空闲任务函数OS_InitTaskIdle(2)
8 #if OS_TASK_CREATE_EXT_EN > 0 9 #if OS_STK_GROWTH == 1 10 (void)OSTaskCreateExt(OS_TaskIdle, 11 (void *)0, 12 &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], 13 OS_TASK_IDLE_PRIO, 14 OS_TASK_IDLE_ID, 15 &OSTaskIdleStk[0], 16 OS_TASK_IDLE_STK_SIZE, 17 (void *)0, 18 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR 2019/4/11

60 3.6p04 创建空闲任务函数OS_InitTaskIdle(3)
19 #else 20 (void)OSTaskCreateExt(OS_TaskIdle, 21 (void *)0, 22 &OSTaskIdleStk[0], 23 OS_TASK_IDLE_PRIO, 24 OS_TASK_IDLE_ID, 25 &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], 26 OS_TASK_IDLE_STK_SIZE, 27 (void *)0, 28 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 29 #endif 2019/4/11

61 3.6p05 创建空闲任务函数OS_InitTaskIdle(4)
30 #else 31 #if OS_STK_GROWTH == 1 32 (void)OSTaskCreate(OS_TaskIdle, 33 (void *)0, 34 &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], 35 OS_TASK_IDLE_PRIO); 36 #else 37 (void)OSTaskCreate(OS_TaskIdle, 38 (void *)0, 39 &OSTaskIdleStk[0], 40 OS_TASK_IDLE_PRIO); 41 #endif 42 #endif 2019/4/11

62 3.6p06 创建空闲任务函数OS_InitTaskIdle(5)
44 #if OS_TASK_NAME_SIZE > OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"uC/OS-II Idle", &err); 46 #else 47 #if OS_TASK_NAME_SIZE > 7 48 OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"OS-Idle", &err); 49 #endif 50 #endif 51 } 2019/4/11

63 2019/4/11

64 3.7 统计任务 统计任务为µC/OS-II系统任务,统计任务每0.1秒执行一次,用于计算CPU的利用率。 2019/4/11

65 3.7p01 统计任务(1) 1 #if OS_TASK_STAT_EN > 0 2 void OS_TaskStat (void *p_arg) 3 { 4 #if OS_CRITICAL_METHOD == 3 5 OS_CPU_SR cpu_sr = 0; 6 #endif 7 2019/4/11

66 3.7p02 统计任务(2) 10 (void)p_arg; 11 while (OSStatRdy == OS_FALSE) { 12 OSTimeDly(2 * OS_TICKS_PER_SEC / 10); 13 } 14 OSIdleCtrMax /= 100L; 15 if (OSIdleCtrMax == 0L) { 16 OSCPUUsage = 0; 17 (void)OSTaskSuspend(OS_PRIO_SELF); 18 } 2019/4/11

67 3.7p03 统计任务(3) 19 for (;;) { 20 OS_ENTER_CRITICAL(); 21 OSIdleCtrRun = OSIdleCtr; 22 OSIdleCtr = 0L; 23 OS_EXIT_CRITICAL(); 24 OSCPUUsage = (INT8U)(100L - OSIdleCtrRun / OSIdleCtrMax); 25 OSTaskStatHook(); 26 #if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0) 27 OS_TaskStatStkChk(); 28 #endif 29 OSTimeDly(OS_TICKS_PER_SEC / 10); 30 } 31 } 32 #endif 2019/4/11

68 3.7p04 OSStatInit函数 (1) 1 #if OS_TASK_STAT_EN > 0 2 void OSStatInit (void) 3 { 4 #if OS_CRITICAL_METHOD == 3 5 OS_CPU_SR cpu_sr = 0; 6 #endif 2019/4/11

69 3.7p05 OSStatInit函数 (2) 10 OSTimeDly(2); 11 OS_ENTER_CRITICAL(); 12 OSIdleCtr = 0L; 13 OS_EXIT_CRITICAL(); 14 OSTimeDly(OS_TICKS_PER_SEC / 10); 15 OS_ENTER_CRITICAL(); 16 OSIdleCtrMax = OSIdleCtr; 17 OSStatRdy = OS_TRUE; 18 OS_EXIT_CRITICAL(); 19 } 20 #endif 2019/4/11

70 3.7q01统计任务创建函数OS_InitTaskStat(1)
1 #if OS_TASK_STAT_EN > 0 2 static void OS_InitTaskStat (void) 3 { 4 #if OS_TASK_NAME_SIZE > 7 5 INT8U err; 6 #endif #if OS_TASK_CREATE_EXT_EN > 0 10 #if OS_STK_GROWTH == 1 11 (void)OSTaskCreateExt(OS_TaskStat, 12 (void *)0, 13 &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], 14 OS_TASK_STAT_PRIO, 15 OS_TASK_STAT_ID, 16 &OSTaskStatStk[0], 17 OS_TASK_STAT_STK_SIZE, 18 (void *)0, 19 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 2019/4/11

71 3.7q02统计任务创建函数OS_InitTaskStat(2)
20 #else 21 (void)OSTaskCreateExt(OS_TaskStat, 22 (void *)0, 23 &OSTaskStatStk[0], 24 OS_TASK_STAT_PRIO, 25 OS_TASK_STAT_ID, 26 &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], 27 OS_TASK_STAT_STK_SIZE, 28 (void *)0, 29 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 30 #endif 2019/4/11

72 3.7q03统计任务创建函数OS_InitTaskStat(3)
31 #else 32 #if OS_STK_GROWTH == 1 33 (void)OSTaskCreate(OS_TaskStat, 34 (void *)0, 35 &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], 36 OS_TASK_STAT_PRIO); 37 #else 38 (void)OSTaskCreate(OS_TaskStat, 39 (void *)0, 40 &OSTaskStatStk[0], 41 OS_TASK_STAT_PRIO); 42 #endif 43 #endif 2019/4/11

73 3.7q04统计任务创建函数OS_InitTaskStat(4)
45 #if OS_TASK_NAME_SIZE > OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"uC/OS-II Stat", &err); 47 #else 48 #if OS_TASK_NAME_SIZE > 7 49 OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"OS-Stat", &err); 50 #endif 51 #endif 52 } 53 #endif 2019/4/11

74 3.7q05统计任务计算CPU使用率过程 2019/4/11

75 2019/4/11

76 3.8 什么是定时器任务? 这里的定时器不是系统硬件平台的定时器计数器,而是µC/OS-II操作系统的软件定时器,最小分辨率为一个时钟节拍。在µC/OS-II内部使用定时器任务来管理定时器,定时器任务的优先级由用户指定,µC/OS-II只能定义一个定时器任务,但这个定时器任务可以管理多个定时器,管理的定时器数量仅受INT16U变量数值范围的限定,可以认为最多能创建65535个定时器。 2019/4/11

77 3.8p01 定时器任务的工作原理? 定时器任务可视为µC/OS-II的系统服务,严格意义上讲,定时器任务对用户不可见,µC/OS-II提供了面向定时器的接口函数,用户应用程序中只需要调用这些函数就可以使用定时器,而完全不用去关心定时器任务。每个定时器的定时时间到达后,定时器将启动一个回调函数,回调函数代码一般十分短小(相当于硬件定时器的中断服务程序),往往在回调函数中完成释放信号量等操作,以启动一个请求该信号量的用户任务工作。 2019/4/11

78 3.8p02 空闲定时器链表 2019/4/11

79 3.8p02 实始化定时器管理器OSTmr_Init函数(1)
1 #if OS_TMR_EN > 0 2 void OSTmr_Init (void) 3 { 4 #if OS_EVENT_NAME_SIZE > 10 5 INT8U err; 6 #endif 7 INT16U i; 8 OS_TMR *ptmr1; 9 OS_TMR *ptmr2; OS_MemClr((INT8U *)&OSTmrTbl[0], sizeof(OSTmrTbl)); 13 OS_MemClr((INT8U *)&OSTmrWheelTbl[0], sizeof(OSTmrWheelTbl)); 2019/4/11

80 3.8p03 实始化定时器管理器OSTmr_Init函数(2)
15 ptmr1 = &OSTmrTbl[0]; 16 ptmr2 = &OSTmrTbl[1]; 17 for (i = 0; i < (OS_TMR_CFG_MAX - 1); i++) { 18 ptmr1->OSTmrType = OS_TMR_TYPE; 19 ptmr1->OSTmrState = OS_TMR_STATE_UNUSED; 20 ptmr1->OSTmrNext = (void *)ptmr2; 21 #if OS_TMR_CFG_NAME_SIZE > 1 22 ptmr1->OSTmrName[0] = '?'; 23 ptmr1->OSTmrName[1] = OS_ASCII_NUL; 24 #endif 25 ptmr1++; 26 ptmr2++; 27 } 2019/4/11

81 3.8p04 实始化定时器管理器OSTmr_Init函数(3)
28 ptmr1->OSTmrType = OS_TMR_TYPE; 29 ptmr1->OSTmrState = OS_TMR_STATE_UNUSED; 30 ptmr1->OSTmrNext = (void *)0; 31 #if OS_TMR_CFG_NAME_SIZE > 1 32 ptmr1->OSTmrName[0] = '?'; 33 ptmr1->OSTmrName[1] = OS_ASCII_NUL; 34 #endif 35 OSTmrTime = 0; 36 OSTmrUsed = 0; 37 OSTmrFree = OS_TMR_CFG_MAX; 38 OSTmrFreeList = &OSTmrTbl[0]; 39 OSTmrSem = OSSemCreate(1); 40 OSTmrSemSignal = OSSemCreate(0); 2019/4/11

82 3.8p05 实始化定时器管理器OSTmr_Init函数(4)
42 #if OS_EVENT_NAME_SIZE > OSEventNameSet(OSTmrSem, (INT8U *)"uC/OS-II TmrLock", &err 44 #else 45 #if OS_EVENT_NAME_SIZE > OSEventNameSet(OSTmrSem, (INT8U *)"OS-TmrLock", &err); 47 #endif 48 #endif 2019/4/11

83 3.8p06 实始化定时器管理器OSTmr_Init函数(5)
50 #if OS_EVENT_NAME_SIZE > OSEventNameSet(OSTmrSemSignal, (INT8U *)"uC/OS-II TmrSignal", &err); 52 #else 53 #if OS_EVENT_NAME_SIZE > OSEventNameSet(OSTmrSemSignal, (INT8U *)"OS-TmrSig", &err); 55 #endif 56 #endif OSTmr_InitTask(); 59 } 60 #endif 2019/4/11

84 3.8p07 OS_TMR和OS_TMR_WHEEL结构体类型定义 (1)
1 #if OS_TMR_EN > 0 2 typedef void (*OS_TMR_CALLBACK)(void *ptmr, void *parg); 3 4 typedef struct os_tmr { 5 INT8U OSTmrType; 6 OS_TMR_CALLBACK OSTmrCallback; 7 void *OSTmrCallbackArg; 8 void *OSTmrNext; 9 void *OSTmrPrev; 10 INT32U OSTmrMatch; 11 INT32U OSTmrDly; 12 INT32U OSTmrPeriod; 13 #if OS_TMR_CFG_NAME_SIZE > 0 14 INT8U OSTmrName[OS_TMR_CFG_NAME_SIZE]; 15 #endif 16 INT8U OSTmrOpt; 17 INT8U OSTmrState; 18 } OS_TMR; 2019/4/11

85 3.8p08 OS_TMR和OS_TMR_WHEEL结构体类型定义 (2)
23 typedef struct os_tmr_wheel { 24 OS_TMR *OSTmrFirst; 25 INT16U OSTmrEntries; 26 } OS_TMR_WHEEL; 27 #endif 2019/4/11

86 3.8p09 定时器相关的全局变量 1 #if OS_TMR_EN > 0 2 OS_EXT INT16U OSTmrFree; 3 OS_EXT INT16U OSTmrUsed; 4 OS_EXT INT32U OSTmrTime; 5 6 OS_EXT OS_EVENT *OSTmrSem; 7 OS_EXT OS_EVENT *OSTmrSemSignal; 8 9 OS_EXT OS_TMR OSTmrTbl[OS_TMR_CFG_MAX]; 10 OS_EXT OS_TMR *OSTmrFreeList; 11 OS_EXT OS_STK OSTmrTaskStk[OS_TASK_TMR_STK_SIZE]; OS_EXT OS_TMR_WHEEL OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE]; 14 #endif 2019/4/11

87 3.8q01 定时器任务创建 (1) 1 #if OS_TMR_EN > 0 2 static void OSTmr_InitTask (void) 3 { 4 #if OS_TASK_NAME_SIZE > 6 5 INT8U err; 6 #endif 2019/4/11

88 3.8q02 定时器任务创建 (2) 9 #if OS_TASK_CREATE_EXT_EN > 0 10 #if OS_STK_GROWTH == 1 11 (void)OSTaskCreateExt(OSTmr_Task, 12 (void *)0, 13 &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], 14 OS_TASK_TMR_PRIO, 15 OS_TASK_TMR_ID, 16 &OSTmrTaskStk[0], 17 OS_TASK_TMR_STK_SIZE, 18 (void *)0, 19 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR 20 #else 2019/4/11

89 3.8q03 定时器任务创建 (3) 21 (void)OSTaskCreateExt(OSTmr_Task, 22 (void *)0, 23 &OSTmrTaskStk[0], 24 OS_TASK_TMR_PRIO, 25 OS_TASK_TMR_ID, 26 &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], 27 OS_TASK_TMR_STK_SIZE, 28 (void *)0, 29 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 30 #endif 31 #else 2019/4/11

90 3.8q04 定时器任务创建 (4) 32 #if OS_STK_GROWTH == 1 33 (void)OSTaskCreate(OSTmr_Task, 34 (void *)0, 35 &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], 36 OS_TASK_TMR_PRIO); 37 #else 38 (void)OSTaskCreate(OSTmr_Task, 39 (void *)0, 40 &OSTmrTaskStk[0], 41 OS_TASK_TMR_PRIO); 42 #endif 43 #endif 2019/4/11

91 3.8q05 定时器任务创建 (5) 45 #if OS_TASK_NAME_SIZE > OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)"uC/OS-II Tmr", &err); 47 #else 48 #if OS_TASK_NAME_SIZE > 6 49 OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)"OS-Tmr", &err); 50 #endif 51 #endif 52 } 53 #endif 2019/4/11

92 3.9 空闲事件标志组链表 2019/4/11

93 3.9p01 事件标志组相关变量类型 (1) 1 #if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) 2 3 #if OS_FLAGS_NBITS == 8 4 typedef INT8U OS_FLAGS; 5 #endif 6 7 #if OS_FLAGS_NBITS == 16 8 typedef INT16U OS_FLAGS; 9 #endif #if OS_FLAGS_NBITS == typedef INT32U OS_FLAGS; 13 #endif 2019/4/11

94 3.9p02 事件标志组相关变量类型 (2) 15 typedef struct os_flag_grp { 16 INT8U OSFlagType; 17 void *OSFlagWaitList; 18 OS_FLAGS OSFlagFlags; 19 #if OS_FLAG_NAME_SIZE > 1 20 INT8U OSFlagName[OS_FLAG_NAME_SIZE]; 21 #endif 22 } OS_FLAG_GRP; typedef struct os_flag_node { 25 void *OSFlagNodeNext; 26 void *OSFlagNodePrev; 27 void *OSFlagNodeTCB; 28 void *OSFlagNodeFlagGrp; 29 OS_FLAGS OSFlagNodeFlags; 30 INT8U OSFlagNodeWaitType; 31 } OS_FLAG_NODE; 32 #endif 2019/4/11

95 3.9p03初始化事件标志组(1) 1 void OS_FlagInit (void) 2 { 3 #if OS_MAX_FLAGS == 1 4 OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0]; 5 OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED; 6 OSFlagFreeList->OSFlagWaitList = (void *)0; 7 OSFlagFreeList->OSFlagFlags = (OS_FLAGS)0; 8 #if OS_FLAG_NAME_SIZE > 1 9 OSFlagFreeList->OSFlagName[0] = '?'; 10 OSFlagFreeList->OSFlagName[1] = OS_ASCII_NUL; 11 #endif 12 #endif 2019/4/11

96 3.9p04 初始化事件标志组(2) 14 #if OS_MAX_FLAGS >= 2 15 INT16U i; 16 OS_FLAG_GRP *pgrp1; 17 OS_FLAG_GRP *pgrp2; OS_MemClr((INT8U *)&OSFlagTbl[0], sizeof(OSFlagTbl)); 21 pgrp1 = &OSFlagTbl[0]; 22 pgrp2 = &OSFlagTbl[1]; 23 for (i = 0; i < (OS_MAX_FLAGS - 1); i++) { 24 pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; 25 pgrp1->OSFlagWaitList = (void *)pgrp2; 26 #if OS_FLAG_NAME_SIZE > 1 27 pgrp1->OSFlagName[0] = '?'; 28 pgrp1->OSFlagName[1] = OS_ASCII_NUL; 29 #endif 30 pgrp1++; 31 pgrp2++; 32 } 2019/4/11

97 3.9p05 初始化事件标志组(3) 33 pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; 34 pgrp1->OSFlagWaitList = (void *)0; 35 #if OS_FLAG_NAME_SIZE > 1 36 pgrp1->OSFlagName[0] = '?'; 37 pgrp1->OSFlagName[1] = OS_ASCII_NUL; 38 #endif 39 OSFlagFreeList = &OSFlagTbl[0]; 40 #endif 41 } 2019/4/11

98 3.9p06 OSFlagTbl和OSFlagFreeList定义
1 #if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) 2 OS_EXT OS_FLAG_GRP OSFlagTbl[OS_MAX_FLAGS]; 3 OS_EXT OS_FLAG_GRP *OSFlagFreeList; 4 #endif 2019/4/11

99 3.10 空闲消息队列链表 2019/4/11

100 3.10p01 消息队列相关的数据结构 (1) 1 #if OS_Q_EN > 0 2 typedef struct os_q { 3 struct os_q *OSQPtr; 4 void **OSQStart; 5 void **OSQEnd; 6 void **OSQIn; 7 void **OSQOut; 8 INT16U OSQSize; 9 INT16U OSQEntries; 10 } OS_Q; 2019/4/11

101 3.10p02 消息队列相关的数据结构 (2) 13 typedef struct os_q_data { 14 void *OSMsg; 15 INT16U OSNMsgs; 16 INT16U OSQSize; 17 #if OS_LOWEST_PRIO <= INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; 19 INT8U OSEventGrp; 20 #else 21 INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; 22 INT16U OSEventGrp; 23 #endif 24 } OS_Q_DATA; 25 #endif 2019/4/11

102 3.10q01 空闲消息队列链表初始化(1) 1 void OS_QInit (void) 2 { 3 #if OS_MAX_QS == 1 4 OSQFreeList = &OSQTbl[0]; 5 OSQFreeList->OSQPtr = (OS_Q *)0; 6 #endif 7 8 #if OS_MAX_QS >= 2 9 INT16U i; 10 OS_Q *pq1; 11 OS_Q *pq2; 2019/4/11

103 3.10q02 空闲消息队列链表初始化(2) 15 OS_MemClr((INT8U *)&OSQTbl[0], sizeof(OSQTbl)); 16 pq1 = &OSQTbl[0]; 17 pq2 = &OSQTbl[1]; 18 for (i = 0; i < (OS_MAX_QS - 1); i++) { 19 pq1->OSQPtr = pq2; 20 pq1++; 21 pq2++; 22 } 23 pq1->OSQPtr = (OS_Q *)0; 24 OSQFreeList = &OSQTbl[0]; 25 #endif 26 } 2019/4/11

104 3.10q03 OSQTbl和OSQFreeList的定义
1 #if (OS_Q_EN > 0) && (OS_MAX_QS > 0) 2 OS_EXT OS_Q *OSQFreeList; 3 OS_EXT OS_Q OSQTbl[OS_MAX_QS]; 4 #endif 2019/4/11

105 3.11 时钟节拍 µC/OS-II系统内部提供了时钟服务,用于识别任务的延时等待时间(或超时等待时间),这个时钟服务的频率一般取为10Hz~200Hz,即将硬件定时器的频率设为10Hz~200Hz,每次硬件定时中断调用一次时钟服务程序,在这个时钟服务程序中更新任务的延时时间。由于时钟服务按设定的频率周期性地执行,被称为时钟节拍。 2019/4/11

106 3.11p01 时钟节拍程序 (1) 1 void OSTimeTick (void) 2 { 3 OS_TCB *ptcb; 4 #if OS_TICK_STEP_EN > 0 5 BOOLEAN step; 6 #endif 7 #if OS_CRITICAL_METHOD == 3 8 OS_CPU_SR cpu_sr = 0; 9 #endif 2019/4/11

107 3.11p02 时钟节拍程序 (2) 11 #if OS_TIME_TICK_HOOK_EN > 0 12 OSTimeTickHook(); 13 #endif 14 #if OS_TIME_GET_SET_EN > 0 15 OS_ENTER_CRITICAL(); 16 OSTime++; 17 OS_EXIT_CRITICAL(); 18 #endif 2019/4/11

108 3.11p03 时钟节拍程序 (3) 19 if (OSRunning == OS_TRUE) { 20 #if OS_TICK_STEP_EN > 0 21 switch (OSTickStepState) { 22 case OS_TICK_STEP_DIS: 23 step = OS_TRUE; 24 break; case OS_TICK_STEP_WAIT: 27 step = OS_FALSE; 28 break; case OS_TICK_STEP_ONCE: 31 step = OS_TRUE; 32 OSTickStepState = OS_TICK_STEP_WAIT; 33 break; 2019/4/11

109 3.11p04 时钟节拍程序 (4) 35 default: 36 step = OS_TRUE; 37 OSTickStepState = OS_TICK_STEP_DIS; 38 break; 39 } 40 if (step == OS_FALSE) { 41 return; 42 } 43 #endif 2019/4/11

110 3.11p05 时钟节拍程序 (5) 44 ptcb = OSTCBList; 45 while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) 46 OS_ENTER_CRITICAL(); 47 if (ptcb->OSTCBDly != 0) { 48 if (--ptcb->OSTCBDly == 0) if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) { 51 ptcb->OSTCBStat &= ~(INT8U)OS_STAT_PEND_ANY; 52 ptcb->OSTCBStatPend = OS_STAT_PEND_TO; 53 } else { 54 ptcb->OSTCBStatPend = OS_STAT_PEND_OK; 55 } 2019/4/11

111 3.11p06 时钟节拍程序 (6) 57 if((ptcb->OSTCBStat & OS_STAT_SUSPEND)==OS_STAT_RDY) { 58 OSRdyGrp |= ptcb->OSTCBBitY; 59 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; 60 } 61 } 62 } 63 ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list*/ 64 OS_EXIT_CRITICAL(); 65 } 66 } 67 } 2019/4/11

112 3.11p07任务状态宏常量 1 #define OS_STAT_RDY 0x00u 2 #define OS_STAT_SEM 0x01u 3 #define OS_STAT_MBOX 0x02u 4 #define OS_STAT_Q 0x04u 5 #define OS_STAT_SUSPEND 0x08u 6 #define OS_STAT_MUTEX 0x10u 7 #define OS_STAT_FLAG 0x20u 8 #define OS_STAT_MULTI 0x80u 9 10 #define OS_STAT_PEND_ANY (OS_STAT_SEM | OS_STAT_MBOX | OS_STAT_Q | OS_STAT_MUTEX | OS_STAT_FLAG) #define OS_STAT_PEND_OK 0u 13 #define OS_STAT_PEND_TO 1u 14 #define OS_STAT_PEND_ABORT 2u 2019/4/11

113 3.12 任务状态有哪些? 2019/4/11

114 3.12p01任务实现任何程序的可能性 2019/4/11

115 3.13 什么是任务调度? µC/OS-II操作系统为实时系统,总是保证处于就绪态的最高优先级任务得到执行权,即一旦最高优先级任务就绪,CPU将立即调用OS_Sched函数,如果当前正在执行的任务就是最高优先级任务,则不调度;否则,将当前任务切换为最高优先级的就绪任务执行。如果是从中断返回,任务调度由函数OSIntExit执行,而不是OS_Sched函数。OS_Sched和OSIntExit函数都位于os_core.c中,二个函数都调用了OS_SchedNew函数,该函数从就绪表中找出优先级最高任务的优先级 2019/4/11

116 3.13p01 OS_Sched、OSIntExit和OS_SchedNew函数 (1)
1 void OS_Sched (void) 2 { 3 #if OS_CRITICAL_METHOD == 3 4 OS_CPU_SR cpu_sr = 0; 5 #endif 6 2019/4/11

117 3.13p02 OS_Sched、OSIntExit和OS_SchedNew函数 (2)
9 OS_ENTER_CRITICAL(); 10 if (OSIntNesting == 0) { 11 if (OSLockNesting == 0) { 12 OS_SchedNew(); 13 if (OSPrioHighRdy != OSPrioCur) { 14 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; 15 #if OS_TASK_PROFILE_EN > 0 16 OSTCBHighRdy->OSTCBCtxSwCtr++; 17 #endif 18 OSCtxSwCtr++; 19 OS_TASK_SW(); 20 } 21 } 22 } 23 OS_EXIT_CRITICAL(); 24 } 2019/4/11

118 3.13p03 OS_Sched、OSIntExit和OS_SchedNew函数 (3)
26 void OSIntExit (void) 27 { 28 #if OS_CRITICAL_METHOD == 3 29 OS_CPU_SR cpu_sr = 0; 30 #endif 2019/4/11

119 3.13p04 OS_Sched、OSIntExit和OS_SchedNew函数 (4)
34 if (OSRunning == OS_TRUE) { 35 OS_ENTER_CRITICAL(); 36 if (OSIntNesting > 0) { 37 OSIntNesting--; 38 } 39 if (OSIntNesting == 0) { 40 if (OSLockNesting == 0) { 41 OS_SchedNew(); 42 if (OSPrioHighRdy != OSPrioCur) { 43 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; 44 #if OS_TASK_PROFILE_EN > 0 45 OSTCBHighRdy->OSTCBCtxSwCtr++; 46 #endif 47 OSCtxSwCtr++; 48 OSIntCtxSw(); 49 } 50 } 51 } 52 OS_EXIT_CRITICAL(); 53 } 54 } 2019/4/11

120 3.13p05 OS_Sched、OSIntExit和OS_SchedNew函数 (5)
56 static void OS_SchedNew (void) 57 { 58 #if OS_LOWEST_PRIO <= INT8U y; y = OSUnMapTbl[OSRdyGrp]; 63 OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); 64 #else 65 INT8U y; 66 INT16U *ptbl; 2019/4/11

121 3.13p06 OS_Sched、OSIntExit和OS_SchedNew函数 (6)
69 if ((OSRdyGrp & 0xFF) != 0) { 70 y = OSUnMapTbl[OSRdyGrp & 0xFF]; 71 } else { 72 y = OSUnMapTbl[(OSRdyGrp >> 8) & 0xFF] + 8; 73 } 74 ptbl = &OSRdyTbl[y]; 75 if ((*ptbl & 0xFF) != 0) { 76 OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl & 0xFF)]); 77 } else { 78 OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8); 79 } 80 #endif 81 } 2019/4/11

122 3.13q01 µC/OS-II内核文件名? 1 #define OS_GLOBALS 2 #include "ucos_ii.h" #define OS_MASTER_FILE 6 #include "os_core.c" 7 #include "os_flag.c" 8 #include "os_mbox.c" 9 #include "os_mem.c" 10 #include "os_mutex.c" 11 #include "os_q.c" 12 #include "os_sem.c" 13 #include "os_task.c" 14 #include "os_time.c" 15 #include "os_tmr.c" 2019/4/11

123 3.13r01 内核管理函数(1) void OSInit(void); void OSStart(void); void OSIntEnter(void); void OSIntExit(void); void OSStatInit(void); INT16U OSVersion(void); 2019/4/11

124 3.13r01 内核管理函数(2) void OSSchedLock(void); void OSSchedUnlock(void); INT8U OSEventNameGet(OS_EVENT *pevent, INT8U *pname, INT8U *perr); void OSEventNameSet(OS_EVENT *pevent, void OSEventPendMulti(OS_EVENT **pevents_pend, OS_EVENT **pevents_rdy, void **pmsgs_rdy, INT16U timeout, 2019/4/11

125 3.13s01延时管理函数 void OSTimeDly(INT16U ticks); INT8U OSTimeDlyHMSM(INT8U hours, INT8U minutes, INT8U seconds, INT16U milli); INT8U OSTimeDlyResume(INT8U prio); INT32U OSTimeGet(void); void OSTimeSet(INT32U ticks); void OSTimeTick(void); 2019/4/11

126 3.13s02 OSTimeDly函数 (1) 1 void OSTimeDly (INT16U ticks) 2 { 3 INT8U y; 4 #if OS_CRITICAL_METHOD == 3 5 OS_CPU_SR cpu_sr = 0; 6 #endif 2019/4/11

127 3.13s03 OSTimeDly函数 (2) 10 if (OSIntNesting > 0) { 11 return; 12 } 13 if (ticks > 0) { 14 OS_ENTER_CRITICAL(); 15 y = OSTCBCur->OSTCBY; 16 OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; 17 if (OSRdyTbl[y] == 0) { 18 OSRdyGrp &= ~OSTCBCur->OSTCBBitY; 19 } 20 OSTCBCur->OSTCBDly = ticks; 21 OS_EXIT_CRITICAL(); 22 OS_Sched(); 23 } 24 } 2019/4/11

128 3.13s04 OSTimeDlyHMSM函数(1) 1 #if OS_TIME_DLY_HMSM_EN > 0 2 INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U ms) 3 { 4 INT32U ticks; 5 INT16U loops; if (OSIntNesting > 0) { 9 return (OS_ERR_TIME_DLY_ISR); 10 } 2019/4/11

129 3.13s05 OSTimeDlyHMSM函数(2) 2019/4/11
11 #if OS_ARG_CHK_EN > 0 12 if (hours == 0) { 13 if (minutes == 0) { 14 if (seconds == 0) { 15 if (ms == 0) { 16 return (OS_ERR_TIME_ZERO_DLY); 17 } 18 } 19 } 20 } 21 if (minutes > 59) { 22 return (OS_ERR_TIME_INVALID_MINUTES); 23 } 24 if (seconds > 59) { 25 return (OS_ERR_TIME_INVALID_SECONDS); 26 } 27 if (ms > 999) { 28 return (OS_ERR_TIME_INVALID_MS); 29 } 30 #endif 2019/4/11

130 3.13s06 OSTimeDlyHMSM函数(3) 33 ticks = ((INT32U)hours * 3600L + (INT32U)minutes * 60L + (INT32U)seconds) * OS_TICKS_PER_SEC 34 + OS_TICKS_PER_SEC * ((INT32U)ms + 500L / OS_TICKS_PER_SEC) / 1000L; 35 loops = (INT16U)(ticks >> 16); 36 ticks = ticks & 0xFFFFL; 37 OSTimeDly((INT16U)ticks); 38 while (loops > 0) { 39 OSTimeDly((INT16U)32768u); 40 OSTimeDly((INT16U)32768u); 41 loops--; 42 } 43 return (OS_ERR_NONE); 44 } 45 #endif 2019/4/11

131 3.13t01 移植管理函数 void OSCtxSw(void); void OSIntCtxSw(void); void OSStartHighRdy(void); void OSInitHookBegin(void); void OSInitHookEnd(void); void OSTaskCreateHook(OS_TCB *ptcb); void OSTaskDelHook(OS_TCB *ptcb); void OSTaskIdleHook(void); void OSTaskStatHook(void); OS_STK *OSTaskStkInit(void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt); void OSTaskSwHook(void); void OSTCBInitHook(OS_TCB *ptcb); void OSTimeTickHook(void); 2019/4/11

132 3.14 多任务启动 1 void OSStart (void) 2 { 3 if (OSRunning == OS_FALSE) { 4 OS_SchedNew(); 5 OSPrioCur = OSPrioHighRdy; 6 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; 7 OSTCBCur = OSTCBHighRdy; 8 OSStartHighRdy(); 9 } 10 } 2019/4/11

133 需要掌握的知识点 初始化函数OSInit实现的功能 借助于算法将优先级为12、34和78的任务放入任务就绪组和就绪表中,然后找出优先级最高的任务的优先级号 分析空闲任务的工作原理 统计任务如何计算OSIdleCtrMax的值 分析时钟节拍的工作原理 分析函数OS_Sched的工作过程 2019/4/11


Download ppt "3. µC/OS-II内核 2019/4/11."

Similar presentations


Ads by Google