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

📄 os_cpu_a.s

📁 一个最新的uCOS-II的GCCAVR移植版本 可移植于mega128的ucos 采用winavr编程
💻 S
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                                          ATmega128 Specific code for V2.8x
;                                           (AVR-GCC 4.1.1)
;
;
; File         : OS_CPU_A.ASM
; By           : Xiawei   <xiawei0311@gmail.com>
; AVR-GCC  version : 4.1.1 , WinAVR 20070122
; Date       : September 9th,2007
;
;********************************************************************************************************
#include <avr/io.h>
#define OS_CPU_A
#include "../Config/OS_CFG.h"
#include "OS_CPU.h"

;********************************************************************************************************
;                                           I/O PORT ADDRESSES
;********************************************************************************************************




;********************************************************************************************************
;                                          PUBLIC DECLARATIONS
;********************************************************************************************************

                .global OSStartHighRdy
                .global OSCtxSw
                .global OSIntCtxSw
                .global TIMER0_COMP_vect
                .global OSTickISR
                .global OSTickISR2
                .global OS_CPU_SR_Save
                .global OS_CPU_SR_Restore

;********************************************************************************************************
;                                         EXTERNAL DECLARATIONS
;********************************************************************************************************

                .extern OSIntExit
                .extern OSIntNesting
                .extern OSPrioCur
                .extern OSPrioHighRdy
                .extern OSRunning
                .extern OSTaskSwHook
                .extern OSTCBCur
                .extern OSTCBHighRdy
                .extern OSTimeTick

;********************************************************************************************************
;                                         MACROS
;********************************************************************************************************

; Push all registers and the status register	
.macro	PUSHRS
		push	r0
		push	r1
		push	r2
		push	r3
		push	r4
		push	r5
		push	r6
		push	r7
		push	r8
		push	r9
		push	r10
		push	r11
		push	r12
		push	r13
		push	r14
		push	r15
		push	r16
		push	r17
		push	r18
		push	r19
		push	r20
		push	r21
		push	r22
		push	r23
		push	r24
		push	r25
		push	r26
		push	r27
		push	r28
		push	r29
		push	r30
		push	r31
		in		r16,_SFR_IO_ADDR(SREG)
		push	r16

.endm

; Pop all registers and the status registers
.macro	POPRS

		pop		r16
		out		_SFR_IO_ADDR(SREG),r16
		pop		r31
		pop		r30
		pop		r29
		pop		r28
		pop		r27
		pop		r26
		pop		r25
		pop		r24
		pop		r23
		pop		r22
		pop		r21
		pop		r20
		pop		r19
		pop		r18
		pop		r17
		pop		r16
		pop		r15
		pop		r14
		pop		r13
		pop		r12
		pop		r11
		pop		r10
		pop		r9
		pop		r8
		pop		r7
		pop		r6
		pop		r5
		pop		r4
		pop		r3
		pop		r2
		pop		r1
		pop		r0

.endm

			.text
			.section	.text
			

;********************************************************************************************************
;                               START HIGHEST PRIORITY TASK READY-TO-RUN
;
; Description : This function is called by OSStart() to start the highest priority task that was created
;               by your application before calling OSStart().
;
; Note(s)     : 1) The (data)stack frame is assumed to look as follows:
;
;                  OSTCBHighRdy->OSTCBStkPtr --> LSB of (return) stack pointer           (Low memory)
;                                                SPH of (return) stack pointer
;                                                Flags to load in status register
;                                                R31
;                                                R30
;                                                R7
;                                                .
;                                                .
;                                                .
;                                                R0                                      (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_CPU_HOOKS_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

                POPRS                               ; Pop all registers and status register
                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 --> LSB of (return) stack pointer           (Low memory)
;                                                SPH of (return) stack pointer
;                                                Flags to load in status register
;                                                R31
;                                                R30
;                                                R7
;                                                .
;                                                .
;                                                .
;                                                R0                                      (High memory)
;********************************************************************************************************

OSCtxSw:
                PUSHRS                              ; Save current tasks context

                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_CPU_HOOKS_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

                POPRS                               ; Restore all registers and the status register
                RETI


;*********************************************************************************************************
;                                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:
;
;                                       SP+0 --> LSB of return address of OSIntCtxSw()   (Low memory)
;                                         +1     MSB of return address of OSIntCtxSw()
;                                         +2     LSB of return address of OSIntExit()
;                                         +3     MSB of return address of OSIntExit()
;			 							possible SREG save	
;                                         +4     LSB of task code address
;                                         +5     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                                      (High memory)
;*********************************************************************************************************

OSIntCtxSw:
#if OS_CPU_HOOKS_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

                POPRS                               ; Restore all registers and status register
                RET

;********************************************************************************************************
;                                           SYSTEM TICK ISR
;
; Description : This function is the ISR used to notify uC/OS-II that a system tick has occurred.
;
;
;********************************************************************************************************
TIMER0_COMP_vect:
OSTickISR:
                PUSHRS                              ; Save all registers and status register

                LDS     R16,OSIntNesting            ; Notify uC/OS-II of ISR
                INC     R16                         ;
                STS     OSIntNesting,R16            ;
                
                CLZ                                 ;清零Z标志位,为下面的比较做好准备
                CPI     R16,1                       ;比较OSIntNesting是否为1
                BREQ    OSTickISR2                  ;如果是1,则跳转至OSTickISR2
                
                SEI                                 ; Enable interrupts
                
                CALL   OSTimeTick                   ; Call uC/OS-IIs tick updating function

                CALL   OSIntExit                   ; Notify uC/OS-II about end of ISR

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

OSTickISR2:
                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                      ;OSTCBCur->OSTCBStkPtr=SP

                SEI                                 ; 使能中断,继续执行OSTickISR中被打断的指令(可选用)
                CALL   OSTimeTick                  ; Call uC/OS-IIs tick updating function

                CALL   OSIntExit                   ; Notify uC/OS-II about end of ISR

                POPRS                               ; Restore all registers and status register
                RET                                 ;

;********************************************************************************************************
;                            DISABLE/ENABLE INTERRUPTS USING OS_CRITICAL_METHOD #3
;
; Description : These functions are used to disable and enable interrupts using OS_CRITICAL_METHOD #3.
;
;               OS_CPU_SR  OSCPUSaveSR (void)
;                     Get current value of SREG
;                     Disable interrupts
;                     Return original value of SREG
;
;               void  OSCPURestoreSR (OS_CPU_SR cpu_sr)
;                     Set SREG to cpu_sr
;                     Return
;********************************************************************************************************

OS_CPU_SR_Save:
                IN      R16,_SFR_IO_ADDR(SREG)      ; Get current state of interrupts disable flag
                CLI                                 ; Disable interrupts
                RET                                 ; Return original SREG value in R16


OS_CPU_SR_Restore:
                OUT     _SFR_IO_ADDR(SREG),R16      ; Restore SREG
                RET                                 ; Return

⌨️ 快捷键说明

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