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

📄 os_cpu_a.asm

📁 这是一个UCOS的AVR移植程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;                                                .
;                                                .
;                                                .
;                                                R0
;                                                PCH
;                                                PCL                                     (High memory)
;
;                  where the stack pointer points to the task start address.
;
;
;               2) OSStartHighRdy() MUST:
;                      a) Call OSTaskSwHook() then,
;                      b) Set OSRunning to TRUE,
;                      c) Switch to the highest priority task.
;********************************************************************************************************

OSStartHighRdy: 
#if OS_TASK_SW_HOOK_EN > 0
	        call    OSTaskSwHook                ; Invoke user defined context switch hook
#endif
                lds     R16,OSRunning               ; Indicate that we are multitasking
                inc     R16                         ;
                sts     OSRunning,R16               ;

                lds     R30,OSTCBHighRdy            ; Let Z point to TCB of highest priority task
                lds     R31,OSTCBHighRdy+1          ; ready to run

                ld      R28,Z+                      ; Load stack L pointer
                out     _SFR_IO_ADDR(SPL),R28
                ld      R29,Z+                      ;
                out     _SFR_IO_ADDR(SPH),R29

                POPSREG                             ; Pop the status register
                POPRS                               ; Pop all registers
                ret                                 ; Start task

;********************************************************************************************************
;                                       TASK LEVEL CONTEXT SWITCH
;
; Description : This function is called when a task makes a higher priority task ready-to-run.
;
; Note(s)     : 1) Upon entry,
;                  OSTCBCur     points to the OS_TCB of the task to suspend
;                  OSTCBHighRdy points to the OS_TCB of the task to resume
;
;               2) The stack frame of the task to suspend looks as follows:
;
;                                       SP+0 --> LSB of task code address
;                                         +1     MSB of task code address                (High memory)
;
;               3) The saved context of the task to resume looks as follows:
;
;                  OSTCBHighRdy->OSTCBStkPtr --> Flags to load in status register (Low memory)
;                                                R31
;                                                R30
;                                                R7
;                                                .
;                                                .
;                                                .
;                                                R0
;                                                PCH
;                                                PCL                                     (High memory)
;********************************************************************************************************

OSCtxSw:        PUSHRS                              ; Save current tasks context
                PUSHSREG                            ; Save SREG

                lds     R30,OSTCBCur                ; Z = OSTCBCur->OSTCBStkPtr
                lds     R31,OSTCBCur+1              ;

                in      r28,_SFR_IO_ADDR(SPL)
                st      Z+,R28                      ; Save Y (R29:R28) pointer
                in      r29,_SFR_IO_ADDR(SPH)
                st      Z+,R29                      ;

#if OS_TASK_SW_HOOK_EN > 0
                call    OSTaskSwHook                ; Call user defined task switch hook
#endif

                lds     R16,OSPrioHighRdy           ; OSPrioCur = OSPrioHighRdy
                sts     OSPrioCur,R16

                lds     R30,OSTCBHighRdy            ; Let Z point to TCB of highest priority task
                lds     R31,OSTCBHighRdy+1          ; ready to run
                sts     OSTCBCur,R30                ; OSTCBCur = OSTCBHighRdy
                sts     OSTCBCur+1,R31              ;

                ld      R28,Z+                      ; Restore Y pointer
                out     _SFR_IO_ADDR(SPL),R28
                ld      R29,Z+                      ;
                out     _SFR_IO_ADDR(SPH),R29

                POPSREG                             ; Restore the status register
                POPRS                               ; Restore all registers
                ret


;*********************************************************************************************************
;                                INTERRUPT LEVEL CONTEXT SWITCH
;
; Description : This function is called by OSIntExit() to perform a context switch to a task that has
;               been made ready-to-run by an ISR.
;
; Note(s)     : 1) Upon entry,
;                  OSTCBCur     points to the OS_TCB of the task to suspend
;                  OSTCBHighRdy points to the OS_TCB of the task to resume
;
;               2) The stack frame of the task to suspend looks as follows:
;
;                  OSTCBCur->OSTCBStkPtr ------> Flags to load in status register        (Low memory)
;                                                R31
;                                                R30
;                                                R27
;                                                .
;                                                .
;                                                R0
;                                                PCH
;                                                PCL                                     (High memory)
;
;               3) The saved context of the task to resume looks as follows:
;
;                  OSTCBHighRdy->OSTCBStkPtr --> Flags to load in status register         (Low memory)
;                                                R31
;                                                R30
;                                                R7
;                                                .
;                                                .
;                                                .
;                                                R0                                      (High memory)
;*********************************************************************************************************

OSIntCtxSw:     
;*********************************************************************************************************
; You should enable the lines between #if 0 and #endif only if you use uC/OS-II version 2.51 or below!
; (Unfortunately OS_VERSION is not defined here (how to do it elegantly?)
;*********************************************************************************************************
#if 0
                in      R28,_SFR_IO_ADDR(SPL)       ; Z = SP
                in      R29,_SFR_IO_ADDR(SPH)

#if      OS_CRITICAL_METHOD == 1
                adiw    R28,4                       ; Use if OS_CRITICAL_METHOD is 1, see OS_CPU.H
#endif
#if      OS_CRITICAL_METHOD == 2
                adiw    R28,5                       ; Use if OS_CRITICAL_METHOD is 2, see OS_CPU.H
#endif

                lds     R30,OSTCBCur                ; Z = OSTCBCur->OSTCBStkPtr
                lds     R31,OSTCBCur+1              ;
                st      Z+,R28                      ; Save Y pointer
                st      Z+,R29                      ;
#endif
;*********************************************************************************************************

#if OS_TASK_SW_HOOK_EN > 0
                call    OSTaskSwHook                ; Call user defined task switch hook
#endif
                lds     R16,OSPrioHighRdy           ; OSPrioCur = OSPrioHighRdy
                sts     OSPrioCur,R16               ;

                lds     R30,OSTCBHighRdy            ; Z = OSTCBHighRdy->OSTCBStkPtr
                lds     R31,OSTCBHighRdy+1          ;
                sts     OSTCBCur,R30                ; OSTCBCur = OSTCBHighRdy
                sts     OSTCBCur+1,R31              ;

                ld      R28,Z+                      ; Restore Y pointer
                out     _SFR_IO_ADDR(SPL),R28
                ld      R29,Z+                      ;
                out     _SFR_IO_ADDR(SPH),R29

                POPSREG                             ; Restore the status register
                POPRS                               ; Restore all registers
                ret

;********************************************************************************************************
;                                           SYSTEM TICK ISR
;
; Description : This function is the ISR used to notify uC/OS-II that a system tick has occurred.
;
; (Julius Luukko/2003-02-14): Changed the name of vector to SIG_OVERFLOW0. In order to the corresponding 
; interrupt vector to be set to point to SIG_OVERFLOW0, one has to also #include <avr/io.h> in this file. 
; Note that no error message or warning will be given, if the include is not present, the interupt just
; won't get vectored.
;
;********************************************************************************************************
.global	SIG_OVERFLOW1
SIG_OVERFLOW1:
OSTickISR:      PUSHRS                              ; Save all registers
                PUSHSREGISR                         ; Save SREG with I bit set!

                lds     R16,OSIntNesting            ; Notify uC/OS-II of ISR
                inc     R16                         ;
                sts     OSIntNesting,R16            ;
                
;*********************************************************************************************************
; You should disable the lines between #if 1 and #endif if you use uC/OS-II version 2.51 or below!
; (Unfortunately OS_VERSION is not defined here (how to do it elegantly? On possibility would be to
;  code this ISR with C in os_cpu_c.c or use inline assembler in os_cpu_c.c)
;*********************************************************************************************************
#if 1
                cpi     R16,0x01
                brne    _not_first_int

                in      R28,_SFR_IO_ADDR(SPL)       ; Z = SP
                in      R29,_SFR_IO_ADDR(SPH)
                lds     R30,OSTCBCur                ; Z = OSTCBCur->OSTCBStkPtr
                lds     R31,OSTCBCur+1              ;
                st      Z+,R28                      ; Save Y pointer
                st      Z+,R29                      ;
_not_first_int:
#endif
                ldi	r24, 0xBF   					; TCNT1 = 65535 - (FOC_U / CLK / 256);
                ldi	r25, 0xFD                       ; Reload timer to overflow at a rate of OS_TICKS_PER_SEC
                out	0x2d, r25					    ; at a prescaler of 1024 and CPU_CLOCK_HZ AVR clock
				out	0x2c, r24
                sei                                 ; Enable interrupts
                
                call    OSTimeTick                  ; Call uC/OS-IIs tick updating function
                nop
                call    OSIntExit                   ; Notify uC/OS-II about end of ISR

                POPSREG
                POPRS                               ; Restore all registers and status register
                ret                                 ; Note: RET instead of RETI


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -