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

📄 os_cpu_a.asm

📁 avr平台上移植uc OS的实例
💻 ASM
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                                          AVR Specific code
;                                           (AVR-GCC 2.95.2)
;
;
; File         : OS_CPU_A.ASM
; By           : Ole Saether
; Port Version : V1.01
;
; AVR-GCC port version : 1.0 	2001-04-02 modified/ported to avr-gcc by Jesper Hansen (jesperh@telia.com)
;
;
;********************************************************************************************************

#define OS_CPU_A
#include "os_cpu.h"

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

SREG    = 0x3F
SPH     = 0x3E
SPL     = 0x3D
TCNT0   = 0x32

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

                .global OSStartHighRdy
                .global OSCtxSw
                .global OSIntCtxSw
                .global	OSTickISR

;********************************************************************************************************
;                                         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,SREG
		push	r16

.endm

; Pop all registers and the status registers
.macro	POPRS

		pop		r16
		out		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: RCALL   OSTaskSwHook                ; Invoke user defined context switch hook
                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		SPL,R28
                LD      R29,Z+                      ;
				out		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,SPL
                ST      Z+,R28                      ; Save Y (R29:R28) pointer
				in		r29,SPH
                ST      Z+,R29                      ;

                RCALL   OSTaskSwHook                ; Call user defined task switch hook

                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		SPL,R28
                LD      R29,Z+                      ;
				out		SPH,R29

                POPRS                               ; Restore all registers and the status register
                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:
;
;                                       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:     IN      R28,SPL                    ; Z = SP
                IN      R29,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                      ;

                RCALL   OSTaskSwHook                ; Call user defined task switch hook

                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		SPL,R28
                LD      R29,Z+                      ;
				out		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.
;
;
;********************************************************************************************************

.global	_overflow0_
_overflow0_:
OSTickISR:      SEI                                 ; Enable interrupts
                PUSHRS                              ; Save all registers and status register

                LDS     R16,OSIntNesting            ; Notify uC/OS-II of ISR
                INC     R16                         ;
                STS     OSIntNesting,R16            ;
                
                RCALL   OSTimeTick                  ; Call uC/OS-IIs tick updating function
				NOP
                RCALL   OSIntExit                   ; Notify uC/OS-II about end of ISR
                LDI     R16,256-(11059200/50/1024)   ; Reload timer to overflow at a rate of 50Hz
                OUT     TCNT0,R16                   ; at a prescaler of 1024 and 7.3728 MHz AVR clock

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

⌨️ 快捷键说明

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