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

📄 os_cpu_a32.s

📁 nios开发ucos源码
💻 S
📖 第 1 页 / 共 2 页
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                          (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
;                                          All Rights Reserved
;
;
;                                       NIOS 32bits Specific code
;
;
;                                     GNU ASSEMBLER nios-elf-as.exe
;
; File         : OS_CPU_A.S
; By           : Farid LEZIAR    (fleziar@yahoo.fr)
; Version      : 2.0
;
;
;    This port is free. you can use it, redistribute it
;    and/or modify it under the following terms:
;
;    1. You are not allowed to remove or modify this copyright notice
;       and License paragraphs, even if parts of the software is used.
;    2. The improvements and/or extentions you make must be available
;       for the community under THIS license, source code included.
;    4. You may NOT distribute this software under another license without
;       explicit permission from farid LEZIAR (fleziar@yahoo.fr).
;    5. This software is free, and distributed in the hope that it will be
;       useful, but WITHOUT ANY WARRANTY.
;    6. Tou have you inform me whenever you use this software.
;
;********************************************************************************************************

;********************************************************************************************************
;                                    PUBLIC and EXTERNAL REFERENCES
;********************************************************************************************************
            .include "macros.s"
            .text
            .global OSTickISR
            .global OSStartHighRdy
            .global OSCtxSw
            .global OSIntCtxSw

            .equ    regwidth, 4                         ; 4 bytes register width for 32bits version
            .equ    timer_address, na_timer_1		    ; see excalibur.s or excalibur.h
            .equ    OS_CPU_HOOKS_EN,1                   ; must the the same in OS_CFG.H

;*********************************************************************************************************
;                                          START MULTITASKING
;                                       void OSStartHighRdy(void)
;
; The stack frame is assumed to look as follows:
;
;                                   return address    <-- +1
;                                   ISTATUS           <-- +8
;                                   %g0-%g7           <-- +8
;                                   CWP_ISR(%i)       <-- +16
;                                   CWP_TASK(%i-%L)   <-- +16
;                                   ...
;                                   ...
;                                   CWP_HL-1(%i-%L)   <-- +16
;                                   CWPHILIMIT(%i-%L) <-- +16
;                                   STATUS(ISR)       <-- +24
; OSTCBHighRdy->OSTCBStkPtr -->     Compiler space    <-- 0
;
; Note : OSStartHighRdy() MUST:
;           a) Call OSTaskSwHook() then,
;           b) Set OSRunning to TRUE,
;           c) Switch to the highest priority task.
;*********************************************************************************************************

OSStartHighRdy:
   ; C function starts with "save %sp,xx"
   ; Call OSTaskSwHook()
    .if (OS_CPU_HOOKS_EN == 1)
      MOVI32    %g0, OSTaskSwHook@h
      CALL      %g0
      NOP
    .endif

   ; OSRunning = TRUE;
      inc8      OSRunning

   ; Switch to the highest priority task.
   ; %sp = OSTCBHighRdy->OSTCBStkPtr
      MOVI32    %g0, OSTCBHighRdy          ; %g0 = &OSTCBHighRdy
      LD        %g1, [%g0]                 ; %g1 = &OS_TCB
      LD        %sp, [%g1]                 ; stack is the first element

      LOAD_CONTEXT

      TRET      %o7                        ; ISTATUS -> STATUS (no change in fact)
      NOP




;*********************************************************************************************************
;                                PERFORM A CONTEXT SWITCH (From task level)
;                                           void OSCtxSw(void)
;
; 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 processor decrement CWP in order to save %i,%L :
;              It Save interrupt status to ISTATUS register
;
;
;          3) The stack frame of the task to resume looks as follows:
;
;                                   return address    <-- +1
;                                   ISTATUS           <-- +8
;                                   %g0-%g7           <-- +8
;                                   CWP_ISR(%i)       <-- +16
;                                   CWP_TASK(%i-%L)   <-- +16
;                                   ...
;                                   ...
;                                   CWP_HL-1(%i-%L)   <-- +16
;                                   CWPHILIMIT(%i-%L) <-- +16
;                                   STATUS(ISR)       <-- +24
; OSTCBHighRdy->OSTCBStkPtr -->     Compiler space    <-- 0
;
;*********************************************************************************************************

OSCtxSw:
   ; This is the entry of a TRAP instruction
   ; We are in a new CWP and ISTATUS is the saved status
   ; %o7 is the Interrupt return address

      SAVE_CONTEXT                          ; affects (%sp, CWP, %g0, %g1, %g2, %g6 and %g7)

   ; OSTCBCur->OSTCBStkPtr = %sp
      MOVI32   %g0, OSTCBCur                ; %g0 = &OSTCBHighRdy
      LD       %g1, [%g0]                   ; %g1 = &OS_TCB
      ST       [%g1], %sp                   ; stack is the first element

   ; Call OSTaskSwHook()
    .if (OS_CPU_HOOKS_EN == 1)
      MOVI32   %g0, OSTaskSwHook@h
      CALL     %g0
      NOP
    .endif

   ; OSTCBCur = OSTCBHighRdy
      MOVI32   %g0, OSTCBHighRdy
      LD       %g1, [%g0]                    ; %g1 = HighRdy TCB
      MOVI32   %g0, OSTCBCur
      ST       [%g0], %g1

   ; OSPrioCur = OSPrioHighRdy
      MOVI32   %g2, OSPrioHighRdy
      LD       %g3, [%g2]                    ; %g3 = HighPrioRdy
      MOVI32   %g2, OSPrioCur
      ST       [%g2], %g3


   ; Switch to the highest priority task.
   ; %sp = OSTCBHighRdy->OSTCBStkPtr (%g1 = OSTCBHighRdy)
      ;MOVI32   %g0, OSTCBHighRdy          ; %g0 = &OSTCBHighRdy
      ;LD       %g1, [%g0]                 ; %g1 = &OS_TCB
      LD       %sp, [%g1]                 ; stack is the first element

      LOAD_CONTEXT

      TRET           %o7
      NOP




;*********************************************************************************************************
;                                            HANDLE TICK ISR
;
;
; Arguments  : none
;
; Returns    : none
;
; Note(s)    : The following C-like pseudo-code describe the operation being performed in the code below.
;
;              Save all registers on the current task's stack;
;              OSIntNesting++;
;              if (OSIntNesting == 1) {
;                 OSTCBCur->OSTCBStkPtr = %sp
;              }
;              OSTimeTick();              Notify uC/OS-II that a tick has occured
;              OSIntExit();               Notify uC/OS-II about end of ISR
;              Restore all registers that were save on the current task's stack;
;              Return from Interrupt;
;*********************************************************************************************************
;
OSTickISR:
   ; We are in a new CWP and ISTATUS is the saved status
   ; %o7 is the Interrupt return address


      SAVE_CONTEXT                          ; affects (%sp, CWP, %g0, %g1, %g2, %g6 and %g7)

   ; Call OSIntEnter() or OSIntNesting++;
   ; warning !! OSIntNesting is 8bits value !!
      MOVI32    %g2, OSIntNesting           ; %g2 = &OSIntNesting
      LD        %g1, [%g2]                  ; %g1 = OSIntNesting
      EXT8D     %g1, %g2                    ; extract byte
      ADDI      %g1, 1                      ; %g1 ++
      FILL8     %r0, %g1                    ; %g0 = %g1 %g1 %g1 %g1
      ST8D      [%g2], %r0                  ; store %g1




   ; if (OSIntNesting == 1) OSTCBCur->OSTCBStkPtr = %sp
   ; %g1 = OSIntNesting
      CMPI      %g1, 1                      ; %g1 == 1
      SKPS      cc_eq                       ; %g1 == 0 ?
      BR        next                        ; no
      ;NOP                                   ; yes
      MOVI32   %g0, OSTCBCur                ; %g0 = &OSTCBHighRdy
      LD       %g1, [%g0]                   ; %g1 = &OS_TCB
      ST       [%g1], %sp                   ; stack is the first element


next:
   ; Clear the interrupt
   ; Clear the timer interrupt : writing to np_timerstatus register
      MOVI32    %g0, timer_address          ; (depends on the design)
      ST        [%g0], %g1

   ; Call OSTimeTick()
      MOVI32   %g0, OSTimeTick@h
      CALL     %g0
      NOP

   ; Call OSIntExit()
      MOVI32   %g0, OSIntExit@h
      CALL     %g0
      NOP

      LOAD_CONTEXT

      TRET           %o7
      NOP



⌨️ 快捷键说明

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