⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_a.asm

📁 个人移植的陈明计先生的small_rtos_MSP430版
💻 ASM
📖 第 1 页 / 共 2 页
字号:
//    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 + -