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

📄 ucosmcfa.s

📁 uCOSII code for Coldfire processor
💻 S
字号:
/********************************************************************/
/**  Unit : uCOSMCFa                                               **/
/**                                                                **/
/**  Description : This unit contains the assembler functions for  **/
/**  the ColdFire port of uC/OS. These perform context switching   **/
/**  and handle the timer ticks.                                   **/
/**                                                                **/
/**  Version History :                                             **/
/**                                                                **/
/**  A0.01     Initial version started                   15/09/97  **/
/**                                                                **/
/** Copyright (c) 1997 David Fiddes, D.J.Fiddes@hw.ac.uk           **/
/********************************************************************/

/********************************************************************/
/**  A note for the interested:                                    **/ 
/**                                                                **/     
/**  I've use the movem.l (%a7),%d0-%d7/%a0-%a6, lea 60(%a7)%a7    **/ 
/**  construct in place of the traditional 68xxx                   **/
/**  movem.l (%a7)+,%d0-%d7/%a0-%a6. It is perfectly in order to   **/
/**  push/pop individual registers using movem.l (%a7)+,%d2 , etc. **/
/**  but it's a bit slower (and more verbose)                      **/
/**                                                                **/     
/**  The lea instruction is required because the ColdFire can't    **/     
/**  push multiple registers directly to the stack...              **/     
/********************************************************************/
            .text
            .global OSStartHighRdy
            .global OSCtxSw
            .global OSIntCtxSw
            .global OSTickISR

            .extern  OSIntEnter
            .extern  OSIntExit
            .extern  OSTimeTick
            .extern  OSTCBCur
            .extern  OSTCBHighRdy


/********************************************************************/
/**  Procedure : OSStartHighRdy                                    **/
/**                                                                **/
/**  The procedure gets the highest priority task then loads its   **/
/**  stack before restoring all of the registers and doing an RTE  **/
/**  to actually start the task. Called directly from uC/OS        **/
/********************************************************************/
OSStartHighRdy:

  move.l   (OSTCBHighRdy),%a1   |Get highest prio. task
  move.l   %a1,(OSTCBCur)
  move.l   (%a1),%a7            |Get ptr to top of stack

  movem.l (%a7),%d0-%d7/%a0-%a6 |Store all the regs
  lea     60(%a7),%a7           |Advance the stack pointer

  rte                           |Return to task


/********************************************************************/
/**  Procedure : OSCtxSw                                           **/
/**                                                                **/
/**  The procedure is installed as an interrupt handler and called **/
/**  using a TRAP instruction within the uC/OS scheduler to swap   **/
/**  contexts at the task level.                                   **/
/********************************************************************/
OSCtxSw:
  lea      -60(%a7),%a7
  movem.l  %d0-%d7/%a0-%a6,(%a7)


  move.l   (OSTCBCur),%a1     |Save stack ptr in TCB
  move.l   %a7,(%a1)

  move.l   (OSTCBHighRdy),%a1 |Point to HI Prio. Task Rdy
  move.l   %a1,(OSTCBCur)     |This is now current TCB

  move.l   (%a1),%A7          |Get new task's stack ptr
  
  movem.l  (%a7),%d0-%d7/%a0-%a6
  lea      60(%a7),%a7

  rte                         |Return to new task
  

/********************************************************************/
/**  Procedure : OSIntCtxSw                                        **/
/**                                                                **/
/**  The procedure is called by when the uC/OS wants to return to  **/
/**  a different task at interrupt time. Used primarily within the **/
/**  timer tick interrupt.                                         **/
/********************************************************************/
OSIntCtxSw:

  adda.l   #16,%a7 |For C -O2 -> -O4 optimisation level
  
|  adda.l   #20,%a7 |For unoptimsed C (Something to do with frame pointers being optimised out in OSIntExit)
  
/*
* Note: the stack adjustment compensates for the following:
*
*   OSIntExit call                               4
*   OSIntExit stack frame adjust                 4 <- goes to 0 for -O2
*   OSIntExit locals 3 * 4 =                     8
*   OSIntCtxSw call                              4
*                                              --- 
*                                               20 or 16
*
*   The interrupt context save and the full register set must
*   be on the stack in the correct order prior to the OSIntExit call
*/

  move.l   (OSTCBCur),%a1     |Save stack ptr in TCB
  move.l   %a7,(%a1)

  move.l   (OSTCBHighRdy),%a1 |Point to HI Prio. Task Rdy
  move.l   %a1,(OSTCBCur)     |This is now current TCB

  move.l   (%a1),%a7          |Get new task's stack ptr

  movem.l  (%a7),%d0-%d7/%a0-%a6
  lea      60(%a7),%a7

  rte                         |Return to new task


/********************************************************************/
/**  Procedure : OSTickISR                                         **/
/**                                                                **/
/**  The procedure is installed as the timer tick ISR and called   **/
/**  each time TIMER1 on the MCF5206 reaches it's reference value. **/
/**  It stores the current context before calling the uC/OS int    **/
/**  nesting logic and timer tick routine which can cause the      **/
/**  context to change. Use this as an example of how to write     **/
/**  ISRs in uC/OS.                                                **/
/********************************************************************/
OSTickISR:

  lea      -60(%a7),%a7
  movem.l  %d0-%d7/%a0-%a6,(%a7)
  
  move.l   #0x10000111,%a0 |Reset the timer chip (hard coded Timer1.TER reg value - bad)
  move.b   #0x03,(%a0)

  jsr      OSIntEnter
  jsr      OSTimeTick
  jsr      OSIntExit

  movem.l  (%a7),%d0-%d7/%a0-%a6
  lea      60(%a7),%a7
 
  rte

⌨️ 快捷键说明

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