📄 os_cpu_a.asm
字号:
// cp2 = OSTaskStackBottom[OSTaskID+1]; // cp2保存当前任务后一个任务的栈底
MOV.W &OSTaskID, R15
RLA.W R15
MOV.W OSTaskStackBottom + 2(R15), R13
// if( OSNextTaskID > OSTaskID)
// {
CMP.W &OSNextTaskID, &OSTaskID
JC ??C_OSCtxSw_4
JMP ??C_OSCtxSw_5
// {
// while( cp2 != (uint16 *)temp ) // 把当前任务堆栈的空闲区域, 腾出给下一个任务
// {
// *cp1-- = *cp2--;
??C_OSCtxSw_0:
MOV.W @R13, 0(R12)
ADD.W #0xfffe, R13
ADD.W #0xfffe, R12
// }
??C_OSCtxSw_5:
CMP.W R14, R13
JNE ??C_OSCtxSw_0
// temp = GetSP() - OSTaskStackBottom[OSTaskID+1]; // 计算当前堆栈的空闲量,以便更新栈底数组
MOV.W SP, R14
MOV.W &OSTaskID, R15
RLA.W R15
MOV.W OSTaskStackBottom + 2(R15), R15
SUB.W R15, R14
SUB.W #0x2, R14
// SP = (uint16)cp1 + 1; // 将堆栈指针指向新的任务
MOV.W &OSTaskID, R15
RLA.W R15
MOV.W OSTaskStackBottom + 2(R15), R12
MOV.W &OSNextTaskID, R15
RLA.W R15
MOV.W OSTaskStackBottom + 2(R15), R13
SUB.W R13, R12
SUB.W R12, SP
// for(i = OSTaskID+1;i < OSNextTaskID+1; i++) // 更新栈底数组
MOV.W &OSTaskID, R15
ADD.W #0x1, R15
JMP ??C_OSCtxSw_6
// 122 {
// 123 OSTaskStackBottom[i] += temp;
??C_OSCtxSw_1:
MOV.W R15, R12
RLA.W R12
MOV.W R14, R13
ADD.W R13, OSTaskStackBottom(R12)
// }
ADD.W #0x1, R15
??C_OSCtxSw_6:
MOV.W &OSNextTaskID, R12
ADD.W #0x1, R12
CMP.W R12, R15
JNC ??C_OSCtxSw_1
// OSTaskID = OSNextTaskID; // 更新当前任务
MOV.W &OSNextTaskID, &OSTaskID
// LoadCtx(); // 从新的任务堆栈里恢复现场
JMP LoadCtx
// }
// if( OSNextTaskID < OSTaskID)
??C_OSCtxSw_4:
CMP.W &OSTaskID, &OSNextTaskID
JC ??C_OSCtxSw_7
// {
// cp2++;
; ADD.W #0x2, R13
; ADD.W #0x2, R12
; ADD.W #0x2, R14
JMP ??C_OSCtxSw_8
// while(cp1 != (uint16 *)temp) // 把当前任务堆栈的空闲区域, 腾出给下一个任务
// {
// *cp2++ = *cp1++;
??C_OSCtxSw_2:
; MOV.W @R12, 0(R13)
ADD.W #0x2, R12
ADD.W #0x2, R13
MOV.W @R12, 0(R13)
// }
??C_OSCtxSw_8:
CMP.W R14, R12
JNE ??C_OSCtxSw_2
// temp = GetSP() - OSTaskStackBottom[OSTaskID+1]; // 计算当前堆栈的空闲量,以便更新栈底数组
MOV.W SP, R14
MOV.W &OSTaskID, R15
RLA.W R15
MOV.W OSTaskStackBottom + 2(R15), R15
SUB.W R15, R14
SUB.W #0x2, R14
// SP = (uint16)OSTaskStackBottom[OSNextTaskID+1] + 1;
MOV.W &OSNextTaskID, R15
RLA.W R15
MOV.W OSTaskStackBottom + 2(R15), R15
ADD.W #0x2, R15
MOV.W R15, SP
// for( i = OSNextTaskID+1;i < OSTaskID+1; i++ )
MOV.W &OSNextTaskID, R15
ADD.W #0x1, R15
JMP ??C_OSCtxSw_9
// {
// OSTaskStackBottom[i] -= temp;
??C_OSCtxSw_3:
MOV.W R15, R12
RLA.W R12
MOV.W R14, R13
SUB.W R13, OSTaskStackBottom(R12)
// }
ADD.W #0x1, R15
??C_OSCtxSw_9:
MOV.W &OSTaskID, R12
ADD.W #0x1, R12
CMP.W R12, R15
JNC ??C_OSCtxSw_3
// OSTaskID = OSNextTaskID;
MOV.W &OSNextTaskID, &OSTaskID
// }
// LoadCtx();
JMP LoadCtx
??C_OSCtxSw_7:
JMP LoadCtx
;****************************************************************************************
;/*********************************************************************************************************
;** 函数名称: OSIntCtxSw
;** 功能描述: 中断使任务放弃CPU环境保存函数
;** 输 入: OSTaskID
;** 输 出 : 无
;** 全局变量: OSFastSwap
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2002年2月22日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2002年12月2日
;**-------------------------------------------------------------------------------------------------------
;** 修 改:
;** 日 期:
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
OSIntCtxSw:
ADD.W #0x4, SP
JMP C_OSCtxSw
;********************************************************************************************************
; TICK ISR
;
; Description: This ISR handles tick interrupts. This ISR uses the Watchdog timer as the tick source.
;
; Notes : 1) The following C pseudo-code describes the operations being performed in the code below.
;
; Save all the CPU registers
; if (OSIntNesting == 0) {
; OSTCBCur->OSTCBStkPtr = SP;
; SP = OSISRStkPtr; /* Use the ISR stack from now on */
; }
; OSIntNesting++;
; Enable interrupt nesting; /* Allow nesting of interrupts (if needed) */
; Clear the interrupt source;
; OSTimeTick(); /* Call uC/OS-II's tick handler */
; DISABLE general interrupts; /* Must DI before calling OSIntExit() */
; OSIntExit();
; if (OSIntNesting == 0) {
; SP = OSTCBHighRdy->OSTCBStkPtr; /* Restore the current task's stack */
; }
; Restore the CPU registers
; Return from interrupt.
;
; 2) ALL ISRs should be written like this!
;
; 3) You MUST disable general interrupts BEFORE you call OSIntExit() because an interrupt
; COULD occur just as OSIntExit() returns and thus, the new ISR would save the SP of
; the ISR stack and NOT the SP of the task stack. This of course will most likely cause
; the code to crash. By disabling interrupts BEFORE OSIntExit(), interrupts would be
; disabled when OSIntExit() would return. This assumes that you are using OS_CRITICAL_METHOD
; #3 (which is the prefered method).
;
; 4) If you DON'T use a separate ISR stack then you don't need to disable general interrupts
; just before calling OSIntExit(). The pseudo-code for an ISR would thus look like this:
;
; Save all the CPU registers
; if (OSIntNesting == 0) {
; OSTCBCur->OSTCBStkPtr = SP;
; }
; OSIntNesting++;
; Enable interrupt nesting; /* Allow nesting of interrupts (if needed) */
; Clear the interrupt source;
; OSTimeTick(); /* Call uC/OS-II's tick handler */
; OSIntExit();
; Restore the CPU registers
; Return from interrupt.
;********************************************************************************************************
OSTickISR ; basic timer ISR
PUSHALL ; push all registers
CALL #OSTimeTick
CALL #OSIntExit
POPALL
RETI ; return from interrupt
;********************************************************************************************************
; WD TIMER INTERRUPT VECTOR ENTRY
;
; MSP430x11x1/MSP430F14x Interrupt vectors
;********************************************************************************************************
COMMON INTVEC
ORG BASICTIMER_VECTOR
BT_VEC DW OSTickISR ; interrupt vector. Watchdog/Timer, Timer mode
;****************************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -