📄 ucos.s
字号:
* Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every * call to OSSchedLock() you MUST have a call to OSSchedUnlock().**********************************************************************************************************/void OSSchedUnlock (void){ if (OSRunning == TRUE) { /* Make sure multitasking is running */ 10009f4: e59f3058 ldr r3, [pc, #58] ; 1000a54 <OSSchedUnlock+0x68> 10009f8: e5d32000 ldrb r2, [r3] 10009fc: e24cb004 sub r11, r12, #4 ; 0x4 1000a00: e3520001 cmp r2, #1 ; 0x1 1000a04: 191ba800 ldmnedb r11, {r11, sp, pc} OS_ENTER_CRITICAL(); 1000a08: ebfffe63 bl 100039c <ARMDisableInt> if (OSLockNesting > 0) { /* Do not decrement if already 0 */ 1000a0c: e59f0044 ldr r0, [pc, #44] ; 1000a58 <OSSchedUnlock+0x6c> 1000a10: e5d02000 ldrb r2, [r0] 1000a14: e3520000 cmp r2, #0 ; 0x0 1000a18: 0a00000b beq 1000a4c <OSSchedUnlock+0x60> OSLockNesting--; /* Decrement lock nesting level */ if ((OSLockNesting | OSIntNesting) == 0) { /* See if scheduling re-enabled and not an ISR */ 1000a1c: e59f3038 ldr r3, [pc, #38] ; 1000a5c <OSSchedUnlock+0x70> 1000a20: e5d31000 ldrb r1, [r3] 1000a24: e2422001 sub r2, r2, #1 ; 0x1 1000a28: e5c02000 strb r2, [r0] 1000a2c: e1822001 orr r2, r2, r1 1000a30: e31200ff tst r2, #255 ; 0xff 1000a34: 1a000002 bne 1000a44 <OSSchedUnlock+0x58> OS_EXIT_CRITICAL(); 1000a38: ebfffe5c bl 10003b0 <ARMEnableInt> OSSched(); /* See if a higher priority task is ready */ 1000a3c: ebffffab bl 10008f0 <OSSched> } else { 1000a40: e91ba800 ldmdb r11, {r11, sp, pc} OS_EXIT_CRITICAL(); 1000a44: ebfffe59 bl 10003b0 <ARMEnableInt> } } else { 1000a48: e91ba800 ldmdb r11, {r11, sp, pc} OS_EXIT_CRITICAL(); 1000a4c: ebfffe57 bl 10003b0 <ARMEnableInt> } } 1000a50: e91ba800 ldmdb r11, {r11, sp, pc} 1000a54: 010070b0 streqh r7, [r0, -r0] 1000a58: 0100709c swpeq r7, r12, [r0] 1000a5c: 01007098 swpeq r7, r8, [r0]01000a60 <OSStart>: 1000a60: e1a0c00d mov r12, sp 1000a64: e92dd800 stmdb sp!, {r11, r12, lr, pc}}/*$PAGE*//*********************************************************************************************************** START MULTITASKING** Description: This function is used to start the multitasking process which lets uC/OS-II manages the* task that you have created. Before you can call OSStart(), you MUST have called OSInit()* and you MUST have created at least one task.** Arguments : none** Returns : none** Note : OSStartHighRdy() MUST:* a) Call OSTaskSwHook() then,* b) Set OSRunning to TRUE.**********************************************************************************************************/void OSStart (void){ INT8U y; INT8U x; if (OSRunning == FALSE) { 1000a68: e59f3060 ldr r3, [pc, #60] ; 1000ad0 <OSStart+0x70> 1000a6c: e5d32000 ldrb r2, [r3] 1000a70: e24cb004 sub r11, r12, #4 ; 0x4 1000a74: e3520000 cmp r2, #0 ; 0x0 1000a78: 191ba800 ldmnedb r11, {r11, sp, pc} y = OSUnMapTbl[OSRdyGrp]; /* Find highest priority's task priority number */ 1000a7c: e59f2050 ldr r2, [pc, #50] ; 1000ad4 <OSStart+0x74> 1000a80: e59f0050 ldr r0, [pc, #50] ; 1000ad8 <OSStart+0x78> x = OSUnMapTbl[OSRdyTbl[y]]; OSPrioHighRdy = (INT8U)((y << 3) + x); 1000a84: e59fe050 ldr lr, [pc, #50] ; 1000adc <OSStart+0x7c> 1000a88: e5d23000 ldrb r3, [r2] 1000a8c: e59f204c ldr r2, [pc, #4c] ; 1000ae0 <OSStart+0x80> 1000a90: e7d0c003 ldrb r12, [r0, r3] 1000a94: e7d2300c ldrb r3, [r2, r12] OSPrioCur = OSPrioHighRdy; OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */ 1000a98: e59f2044 ldr r2, [pc, #44] ; 1000ae4 <OSStart+0x84> 1000a9c: e7d01003 ldrb r1, [r0, r3] 1000aa0: e59f3040 ldr r3, [pc, #40] ; 1000ae8 <OSStart+0x88> 1000aa4: e59f0040 ldr r0, [pc, #40] ; 1000aec <OSStart+0x8c> 1000aa8: e081118c add r1, r1, r12, lsl #3 1000aac: e5ce1000 strb r1, [lr] 1000ab0: e5c31000 strb r1, [r3] 1000ab4: e5de3000 ldrb r3, [lr] 1000ab8: e7901103 ldr r1, [r0, r3, lsl #2] OSTCBCur = OSTCBHighRdy; 1000abc: e59f302c ldr r3, [pc, #2c] ; 1000af0 <OSStart+0x90> 1000ac0: e5821000 str r1, [r2] 1000ac4: e5831000 str r1, [r3] OSStartHighRdy(); /* Execute target specific code to start task */ 1000ac8: ebfffdfc bl 10002c0 <OSStartHighRdy> }} 1000acc: e91ba800 ldmdb r11, {r11, sp, pc} 1000ad0: 010070b0 streqh r7, [r0, -r0] 1000ad4: 010070a8 tsteq r0, r8, lsr #1 1000ad8: 0100145c tsteq r0, r12, asr r4 1000adc: 010070a4 tsteq r0, r4, lsr #1 1000ae0: 010070ac tsteq r0, r12, lsr #1 1000ae4: 010070c0 tsteq r0, r0, asr #1 1000ae8: 010070a0 tsteq r0, r0, lsr #1 1000aec: 010070c8 tsteq r0, r8, asr #1 1000af0: 010070b8 streqh r7, [r0, -r8]01000af4 <OSTaskIdle>: 1000af4: e1a0c00d mov r12, sp 1000af8: e92dd810 stmdb sp!, {r4, r11, r12, lr, pc} 1000afc: e24cb004 sub r11, r12, #4 ; 0x4/*$PAGE*//*********************************************************************************************************** STATISTICS INITIALIZATION** Description: This function is called by your application to establish CPU usage by first determining* how high a 32-bit counter would count to in 1 second if no other tasks were to execute* during that time. CPU usage is then determined by a low priority task which keeps track* of this 32-bit counter every second but this time, with other tasks running. CPU usage is* determined by:** OSIdleCtr* CPU Usage (%) = 100 * (1 - ------------)* OSIdleCtrMax** Arguments : none** Returns : none**********************************************************************************************************/#if OS_TASK_STAT_ENvoid OSStatInit (void){ OSTimeDly(2); /* Synchronize with clock tick */ OS_ENTER_CRITICAL(); OSIdleCtr = 0L; /* Clear idle counter */ OS_EXIT_CRITICAL(); OSTimeDly(OS_TICKS_PER_SEC); /* Determine MAX. idle counter value for 1 second */ OS_ENTER_CRITICAL(); OSIdleCtrMax = OSIdleCtr; /* Store maximum idle counter count in 1 second */ OSStatRdy = TRUE; OS_EXIT_CRITICAL();}#endif/*$PAGE*//*********************************************************************************************************** IDLE TASK** Description: This task is internal to uC/OS-II and executes whenever no other higher priority tasks* executes because they are waiting for event(s) to occur.** Arguments : none** Returns : none**********************************************************************************************************/void OSTaskIdle (void *pdata){ pdata = pdata; /* Prevent compiler warning for not using 'pdata' */ for (;;) { 1000b00: e59f4014 ldr r4, [pc, #14] ; 1000b1c <OSTaskIdle+0x28> OS_ENTER_CRITICAL(); 1000b04: ebfffe24 bl 100039c <ARMDisableInt> OSIdleCtr++; 1000b08: e5943000 ldr r3, [r4] 1000b0c: e2833001 add r3, r3, #1 ; 0x1 1000b10: e5843000 str r3, [r4] OS_EXIT_CRITICAL(); 1000b14: ebfffe25 bl 10003b0 <ARMEnableInt> 1000b18: eafffff9 b 1000b04 <OSTaskIdle+0x10> 1000b1c: 01007094 swpeq r7, r4, [r0] 1000b20: e91ba810 ldmdb r11, {r4, r11, sp, pc}01000b24 <OSTCBInit>: 1000b24: e1a0c00d mov r12, sp 1000b28: e92dd8f0 stmdb sp!, {r4, r5, r6, r7, r11, r12, lr, pc} 1000b2c: e24cb004 sub r11, r12, #4 ; 0x4 }}/*$PAGE*//*********************************************************************************************************** STATISTICS TASK** Description: This task is internal to uC/OS-II and is used to compute some statistics about the* multitasking environment. Specifically, OSTaskStat() computes the CPU usage.* CPU usage is determined by:** OSIdleCtr* OSCPUUsage = 100 * (1 - ------------) (units are in %)* OSIdleCtrMax** Arguments : pdata this pointer is not used at this time.** Returns : none** Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the* next higher priority, OS_IDLE_PRIO-1.* 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0.* 3) We delay for 5 seconds in the beginning to allow the system to reach steady state and* have all other tasks created before we do statistics. You MUST have at least a delay* of 2 seconds to allow for the system to establish the maximum value for the idle * counter.**********************************************************************************************************/#if OS_TASK_STAT_ENvoid OSTaskStat (void *pdata){ INT32U run; INT8S usage; pdata = pdata; /* Prevent compiler warning for not using 'pdata' */ while (OSStatRdy == FALSE) { OSTimeDly(2 * OS_TICKS_PER_SEC); /* Wait until statistic task is ready */ } for (;;) { OS_ENTER_CRITICAL(); OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */ run = OSIdleCtr; OSIdleCtr = 0L; /* Reset the idle counter for the next second */ OS_EXIT_CRITICAL(); if (OSIdleCtrMax > 0L) { usage = (INT8S)(100L - 100L * run / OSIdleCtrMax); if (usage > 100) { OSCPUUsage = 100; } else if (usage < 0) { OSCPUUsage = 0; } else { OSCPUUsage = usage; } } else { OSCPUUsage = 0; } OSTaskStatHook(); /* Invoke user definable hook */ OSTimeDly(OS_TICKS_PER_SEC); /* Accumulate OSIdleCtr for the next second */ }}#endif/*$PAGE*//*********************************************************************************************************** INITIALIZE TCB** Description: This function is internal to uC/OS-II and is used to initialize a Task Control Block when* a task is created (see OSTaskCreate() and OSTaskCreateExt()).** Arguments : prio is the priority of the task being created** ptos is a pointer to the task's top-of-stack assuming that the CPU registers* have been placed on the stack. Note that the top-of-stack corresponds to a * 'high' memory location is OS_STK_GROWTH is set to 1 and a 'low' memory* location if OS_STK_GROWTH is set to 0. Note that stack growth is CPU* specific.** pbos is a pointer to the bottom of stack. A NULL pointer is passed if called by* 'OSTaskCreate()'.** id is the task's ID (0..65535)** stk_size is the size of the stack (in 'stack units'). If the stack units are INT8Us* then, 'stk_size' contains the number of bytes for the stack. If the stack* units are INT32Us then, the stack contains '4 * stk_size' bytes. The stack* units are established by the #define constant OS_STK which is CPU* specific. 'stk_size' is 0 if called by 'OSTaskCreate()'.** pext is a pointer to a user supplied memory area that is used to extend the task* control block. This allows you to store the contents of floating-point* registers, MMU registers or anything else you could find useful during a * context switch. You can even assign a name to each task and store this name* in this TCB extension. A NULL pointer is passed if called by OSTaskCreate().** opt options as passed to 'OSTaskCreateExt()' or, * 0 if called from 'OSTaskCreate()'.** Returns : OS_NO_ERR if the call was successful* OS_NO_MORE_TCB if there are no more free TCBs to be allocated and thus, the task cannot* be created.** Note : This function is INTERNAL to uC/OS-II and your application should not call it.**********************************************************************************************************/INT8U OSTCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT16U stk_size, void *pext, INT16U opt){ 1000b30: e1a07000 mov r7, r0 1000b34: e1a06001 mov r6, r1 OS_TCB *ptcb; OS_ENTER_CRITICAL(); 1000b38: ebfffe17 bl 100039c <ARMDisableInt> ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */ 1000b3c: e59f20c8 ldr r2, [pc, #c8] ; 1000c0c <OSTCBInit+0xe8> 1000b40: e5924000 ldr r4, [r2] 1000b44: e20750ff and r5, r7, #2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -