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

📄 ucos_asm.s03

📁 embed in keil
💻 S03
📖 第 1 页 / 共 2 页
字号:
;----------------------------------------------------------------------------------------+
;                                                                                        |
;                           Real-Time Kernel for the Intel 8052                          |
;                                                                                        |
;  Filename    :  uCOS_asm.s03                                                           |
;                                                                                        |
;  Description :  This file contains the assembly language code that implements the      |
;                 porting of the uC/OS-II Real Time Operating system to the 8052 family  |
;                 of processors, based on the IAR Systems Embedded Workbench toolchain.  |
;                                                                                        |
;  Author      :  Antonio Fuentes  (antonio_fuentes@msl-vlc.com)                         |
;                                                                                        |
;  Date        :  October, 2001                                                          |
;                                                                                        |
;  Changes     :  November, 2001. Support for uC/OS-II, Version 2.51                     |
;                                                                                        |
;----------------------------------------------------------------------------------------+
; This file contains the following functions:                                            
;  
; void  OSStartHighRdy(void)
; void  OSCtxSw(void)
; void  OSIntCtxSw(void)
;
;----------------------------------------------------------------------------------------+
;                               START MULTITASKING                                       |
;                                                                                        |
; void OSStartHighRdy(void)                                                              |
;                                                                                        |
; This module is called to start the kernel running, when all tasks have been created.   |
;----------------------------------------------------------------------------------------+
         MODULE   OSSTARTHIGHRDY    ;Module name
         RSEG     CODE              ;Relocatable Segment

;<---[ "Include" files: ]---------------------------------------------------------------->

$sfr8052.inc                        ;Generic defines for the 8032 chip derivatives
$brd_defs.inc                       ;Specific defines for the processor board

;<---[ Symbols available for other modules: ]-------------------------------------------->

         PUBLIC    OSStartHighRdy   ;Starts running highest priority task (starts OS)
         
;<---[ Module definition for 'C' calls: ]------------------------------------------------>

         $DEFFN    OSStartHighRdy(0,0,0,0,32768,0,0,0)
 
;<---[ Symbols referenced, in other modules: ]------------------------------------------->

         EXTERN    OSTaskSwHook     ;Module: user defined function.
         EXTERN    OSTCBHighRdy     ;TCB of highest priority task ready to run
         EXTERN    OSTCBCur         ;TCB of current task
         EXTERN    OSRunning        ;Boolean: signals the kernel is running
;<--------------------------------------------------------------------------------------->
OSStartHighRdy:                     ;Module entry point

         clr     EA                         ;Enter critical section      
         call    OSTaskSwHook               ;Call user procedure 
         mov     dptr, #OSRunning           ;Point to buffer of boolean flag
         mov     a, #01                     ;Load TRUE
         movx    @dptr, a                   ;Set flag

         mov     dptr, #OSTCBHighRdy + 1    ;Point to top priority ready task TCB (skip pointer type)
         movx    a, @dptr                   ;Read pointer high
         mov     WORK, a                    ;Save in the work area
         inc     dptr                       ;Increment pointer
         movx    a, @dptr                   ;Read pointer low
         mov     WORK+1, a                  ;Save in the work area
         mov     dptr, #OSTCBCur + 1        ;Point to buffer of current TCB task
         mov     a, WORK                    ;Load pointer high
         movx    @dptr, a                   ;Pass it to buffer
         inc     dptr                       ;Increment pointer
         mov     a, WORK+1                  ;Load pointer low
         movx    @dptr, a                   ;Pass it to buffer

; We have just copied OSTCBHighRdy over to OSTCBCur. Now we shall point to the 'xstack' of
; this TCB:

         mov     DPL, a                     ;Load pointer low to TCB current
         mov     DPH, WORK                  ;Load pointer high to TCB current

; Now DPTR points to the Stack address (top-of-stack) of current task's TCB.
; Next we restore the context to internal processor hardware ('istack'):

         inc     dptr                       ;Increment pointer to skip pointer type (always 01)
         movx    a, @dptr                   ;Get pointer high
         mov     WORK, a                    ;Save in work area
         inc     dptr                       ;Increment pointer         
         movx    a, @dptr                   ;Get pointer low
         mov     DPH, WORK                  ;Load pointer high
         clr     c                          ;Clear carry
         subb    a, #02h                    ;Decrement 2 to point to XSP (base of xstack)
         mov     DPL, a                     ;Update pointer low             
         jnc     shr_0                      ;If no carry, skip on
         dec     DPH                        ;DPTR now points to the end of the task's stack

shr_0:   movx    a, @dptr                   ;First byte is base of xstack high (XSP)
         push    ACC                        ;Save on stack
         inc     dptr                       ;Point to next byte (XSP+1)
         movx    a, @dptr                   ;Read byte
         push    ACC                        ;Save it
         inc     dptr                       ;Point to next byte (number of valid bytes in xstack)
         movx    a, @dptr                   ;Read it
         mov     R1, a                      ;Save number of valid stack bytes in R1
         pop     DPL                        ;Update DPTR to point to the base of xstack of
         pop     DPH                        ;..current task
                 
; Now, DPTR points to the base of current task's 'xstack'. We shall copy the valid number
; of bytes from 'xstack' to 'istack':

         mov     R0, #60h                   ;Hardware stack ('istack' at IRAM), starts at 60h
shr_1:   movx    a, @dptr                   ;Get byte from task 'xstack'
         mov     @R0, a                     ;Pass it to 'istack'
         inc     dptr                       ;Increment source pointer   
         inc     R0                         ;Increment destination pointer
         djnz    R1, shr_1                  ;Copy the whole 'xstack' over to 'istack'

         mov     SP, R0                     ;Restore the stack pointer to the top of stack 
         pop     ACC                        ;Dummy pop to adjust SP to first valid data
         pop     XSP+1                      ;Restore the context in the reverse 
         pop     XSP                        ;..order as it was saved
         pop     DPL                        ;Restore pointer low
         pop     DPH                        ;Restore pointer high
         pop     Bk0_r7                     ;Restore register #7
         pop     Bk0_r6                     ;Restore register #6
         pop     Bk0_r5                     ;Restore register #5
         pop     Bk0_r4                     ;Restore register #4
         pop     Bk0_r3                     ;Restore register #3
         pop     Bk0_r2                     ;Restore register #2
         pop     Bk0_r1                     ;Restore register #1
         pop     Bk0_r0                     ;Restore register #0
         pop     b                          ;Restore register B
         pop     ACC                        ;Restore accumulator
         pop     PSW                        ;Restore PSW
         setb    EA                         ;Exit critical section
         reti                               ;Jump to execute scheduled task
     
         ENDMOD
;----------------------------------------------------------------------------------------+
;                           PERFORM A CONTEXT SWITCH (From task level)                   |
;                                                                                        |
; void OSCtxSw(void)                                                                     |
;                                                                                        |
; This module changes task context during a task switch.                                 |
;----------------------------------------------------------------------------------------+
         MODULE   OSCTXSW           ;Module name
         RSEG     CODE              ;Relocatable Segment

;<---[ Symbols available for other modules: ]-------------------------------------------->

         PUBLIC    OSCtxSw          ;Performs a task-level context switch
         
;<---[ Module definition for 'C' calls: ]------------------------------------------------>

         $DEFFN    OSCtxSw(0,0,0,0,32768,0,0,0)

;<---[ Symbols referenced, in other modules: ]------------------------------------------->

         EXTERN    OSTCBHighRdy     ;TCB of highest priority task ready to run
         EXTERN    OSTCBCur         ;TCB of current task
         EXTERN    OSPrioHighRdy    ;Priority of highest priority task ready to run
         EXTERN    OSPrioCur        ;Priority of current task
;<--------------------------------------------------------------------------------------->
OSCtxSw:                            ;Module entry point
          
         clr     EA                         ;Enter critical section   
         push    PSW                        ;Save the Program Status Word
         push    ACC                        ;Save accumulator
         push    b                          ;Save register B
         push    Bk0_r0                     ;Save register R0 (Bank #0)
         push    Bk0_r1                     ;Save register R1 (Bank #0)
         push    Bk0_r2                     ;Save register R2 (Bank #0)
         push    Bk0_r3                     ;Save register R3 (Bank #0)
         push    Bk0_r4                     ;Save register R4 (Bank #0)
         push    Bk0_r5                     ;Save register R5 (Bank #0)
         push    Bk0_r6                     ;Save register R6 (Bank #0)
         push    Bk0_r7                     ;Save register R7 (Bank #0)
         push    DPH                        ;Save Data Pointer high)
         push    DPL                        ;Save Data Pointer low
         push    XSP                        ;Save the 'xstack' base pointer
         push    XSP+1                      ;..(high and low)
  
; Now we shall copy the internal stack over to external stack (XDATA).
; The internal stack starts at 60h. We shall therefore substract 5Fh from
; the stack pointer to determine how far it has grown:, 
  
         clr     c                          ;Clear carry bit
         mov     a, SP                      ;Load stack pointer
         subb    a, #5Fh                    ;Substract 5Fh
         mov     R1,  a                     ;Save internal stack length into R1
         mov     WORK,  a                   ;Also save it in the work area to move it on top of xstack
         mov     R0, #60h                   ;Start address of 'istack' 
         mov     DPH, XSP                   ;Load the 'xstack' base pointer high
         mov     DPL, XSP+1                 ;Idem low

cs_00:   mov     a, @R0                     ;Get the byte from the 'istack'
         movx    @dptr, a                   ;Move it into the 'xstack'
         inc     dptr                       ;Increment destination pointer
         inc     R0                         ;Idem source pointer
         djnz    R1, cs_00                  ;Loop until 'istack' is copied onto 'xstack'
                               
         mov     a, WORK                    ;Save the 'istack' length onto the 'xstack'
         movx    @dptr, a                   ;Save length
         mov     WORK+1, DPH                ;Save the 'xstack' Top-Of-Stack in the work area
         mov     WORK+2, DPL                ;..(HIGH and LOW)
         mov     SP, #60h                   ;Start the new task with SP set to #60h

; The current task's context has been saved over external RAM. Now we need to update
; the new current task TCB Top-Of-Stack field. First, we'll update the piority buffers:

         mov     dptr, #OSPrioHighRdy       ;Point to buffer of top priority ready to run
         movx    a, @dptr                   ;Read it
         mov     dptr, #OSPrioCur           ;Point to buffer of current priority
         movx    @dptr, a                   ;Update current priority

         mov     dptr, #OSTCBCur + 1        ;Point to buffer of current task TCB (skip pointer type)
         movx    a, @dptr                   ;Read pointer high
         mov     WORK, a                    ;Save in the work area
         inc     dptr                       ;Increment pointer
         movx    a, @dptr                   ;Read pointer low
         mov     DPL, a                     ;Point TO OSTCBCUR->STCKPTR 

⌨️ 快捷键说明

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