os_cpu_a.s
上传用户:jinguanrq
上传日期:2022-06-04
资源大小:724k
文件大小:6k
源码类别:

uCOS

开发平台:

C/C++

  1. ;#------------------------------------------------------------------------------
  2. ;#- File: os_cpu_a.s
  3. ;#------------------------------------------------------------------------------
  4. ;#-            (c) Copyright ARM Limited 1999.  All rights reserved. 
  5. ;#-
  6. ;#-                              ARM Specific code
  7. ;#------------------------------------------------------------------------------
  8. ;#-
  9. ;#- 
  10. ;#- Functions defined in this module:
  11. ;#-
  12. ;#- void ARMDisableInt(void) disable interrupts when in SVC
  13. ;#- void ARMEnableInt(void) enable interrupts when in SVC
  14. ;#- void OS_TASK_SWAP(void) context switch
  15. ;#- void OSStartHighRdy(void) start highest priority task
  16.  PRESERVE8
  17.      AREA |subr|, CODE, READONLY
  18. SwiV        EQU   0x08
  19. IrqV        EQU   0x18
  20. FiqV        EQU   0x1C
  21. NoInt       EQU   0x80
  22. SVC32Mode   EQU   0x13
  23. IRQ32Mode   EQU   0x12
  24. FIQ32Mode   EQU   0x11
  25. OSEnterSWI  EQU   0x00
  26. BIT_TIMER0  EQU   (0x1<<13)
  27. I_ISPC      EQU   0x1e00024
  28. INTMSK      EQU   0x1e0000c
  29. ;# External symbols we need the addresses of
  30.  import OSTCBCur
  31. ;addr_OSTCBCur DCW  OSTCBCur
  32.  import OSTCBHighRdy
  33. ;addr_OSTCBHighRdy DCW  OSTCBHighRdy
  34.      import OSPrioCur
  35. ;addr_OSPrioCur DCW  OSPrioCur
  36.  import OSPrioHighRdy
  37. ;addr_OSPrioHighRdy  DCW     OSPrioHighRdy
  38.  import OSRunning
  39.  import SysENInterrupt
  40.  import OSTaskSwHook 
  41.  import need_to_swap_context
  42.  import IrqStart
  43.  import OSTimeTick
  44.  import IrqFinish
  45.  import SysDISInterrupt
  46.  export IRQContextSwap
  47.  export TickHandler
  48.  export RunNewTask
  49. IRQContextSwap
  50. MOV a1, #1
  51. MOV lr, pc
  52. TickHandler
  53. STMDB    sp!,{r0-r11,lr}
  54. ; #interrupt disable(not nessary)
  55. mrs r0, CPSR
  56. orr r0, r0, #0x80 ; @ and set IRQ disable flag
  57. msr CPSR_cxsf, r0
  58. ldr     r0,=0x4000000
  59. BL      SysDISInterrupt
  60. ; #End of interrupt
  61. ; #(Clear pending bit of INTPEND that don't accessed it.)
  62. ; # rI_ISPC= BIT_TIMER0;
  63. LDR r0, =I_ISPC
  64. LDR r1, =BIT_TIMER0
  65. STR r1, [r0]
  66. BL IrqStart
  67. BL OSTimeTick
  68. BL IrqFinish ;@a1= return value 0:not context switch, otherwise:context switch
  69. CMP a1, #0
  70. LDRNE pc, =_CON_SWAP
  71. _NOT_CON_SWAP
  72. ; #not context switching
  73. ldr     r0,=0x4000000
  74. BL      SysENInterrupt
  75. LDMIA    sp!,{r0-r11, lr}
  76. SUBS pc, lr, #4
  77. _CON_SWAP
  78. ; #now context switching
  79. LDMIA    sp!,{r0-r11,lr}
  80. RunNewTask
  81. SUB lr, lr, #4
  82. STR lr, SAVED_LR ; @STR lr, [pc, #SAVED_LR-.-8]
  83. ; #;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  84. ; #Change Supervisor mode
  85. ; #!!!r12 register don't preserved. (r12 that PC of task)
  86. MRS             lr, SPSR
  87. AND lr, lr, #0xFFFFFFE0
  88. ORR lr, lr, #0x13
  89. MSR             CPSR_cxsf, lr
  90. ; #;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  91. ; #Now  Supervisor mode
  92. ; #;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  93. STR r12, [sp, #-8] ;@ saved r12
  94. LDR r12, SAVED_LR ;@LDR r12, [pc, #SAVED_LR-.-8]
  95. STMFD sp!, {r12} ;@ r12 that PC of task
  96. SUB sp, sp, #4 ;@ inclease stack point
  97. LDMIA sp!, {r12} ;@ restore r12
  98. STMFD sp!, {lr} ;@ save lr
  99. STMFD sp!, {r0-r12} ;@ save register file and ret address
  100. MRS r4, CPSR
  101. STMFD sp!, {r4} ;@ save current PSR
  102. MRS r4, SPSR ;@ YYY+
  103. STMFD sp!, {r4} ;@ YYY+ save SPSR
  104. ; # OSPrioCur = OSPrioHighRdy
  105. LDR r4, =OSPrioCur
  106. LDR r5, =OSPrioHighRdy
  107. LDRB r6, [r5]
  108. STRB r6, [r4]
  109. ; # Get current task TCB address
  110. LDR r4, =OSTCBCur
  111. LDR r5, [r4]
  112. STR sp, [r5] ;@ store sp in preempted tasks's TCB
  113. ; # Get highest priority task TCB address
  114. LDR r6, =OSTCBHighRdy
  115. LDR r6, [r6]
  116. LDR sp, [r6] ;@ get new task's stack pointer
  117. ; # OSTCBCur = OSTCBHighRdy
  118. STR r6, [r4] ;@ set new current task TCB address
  119. LDMFD sp!, {r4} ;@ YYY+
  120. ;# AND r4, r4, #0xFFFFFF20
  121. ;# ORR r4, r4, #0x13
  122. MSR SPSR_cxsf, r4 ;@ YYY+
  123. LDMFD sp!, {r4} ;@ YYY+
  124. ;# AND r4, r4, #0xFFFFFF20
  125. ;# ORR r4, r4, #0x13
  126. MSR CPSR_cxsf, r4 ;@ YYY+
  127. ldr     r0,=0x4000000
  128. BL      SysENInterrupt
  129. LDMFD sp!, {r0-r12, lr, pc} ;@ YYY+
  130. SAVED_LR ;.LONG 0
  131. ;# void DisableInt(void)
  132. ;# void EnableInt(void)
  133. ;#
  134. ;# Disable and enable IRQ and FIQ preserving current CPU mode.
  135. ;#
  136. export ARMDisableInt
  137. ARMDisableInt
  138. STMDB sp!, {r0,lr}
  139. MRS r0, CPSR
  140. ORR r0, r0, #NoInt
  141. MSR CPSR_cxsf, r0
  142. LDMIA sp!, {r0,pc}
  143. ;# MOV pc, lr
  144. export ARMEnableInt
  145. ARMEnableInt
  146. STMDB sp!, {r0,lr}
  147. MRS r0, CPSR
  148. BIC r0, r0, #NoInt
  149. MSR CPSR_cxsf, r0
  150. LDMIA sp!, {r0,pc}
  151. ;# MOV pc, lr
  152. export ARMIsDisableInt
  153. ARMIsDisableInt ;@return value [disable: 1      enable: 0]
  154. MRS a1, CPSR
  155. AND a1, a1, #NoInt
  156. ; bx lr
  157. ;# void OS_TASK_SW(void)
  158. ;#
  159. ;# Perform a context switch.
  160. ;#
  161. ;# On entry, OSTCBCur and OSPrioCur hold the current TCB and priority
  162. ;# and OSTCBHighRdy and OSPrioHighRdy contain the same for the task
  163. ;# to be switched to.
  164. ;#
  165. ;# The following code assumes that the virtual memory is directly
  166. ;# mapped into  physical memory. If this is not true, the cache must 
  167. ;# be flushed at context switch to avoid address aliasing.
  168. export OS_TASK_SW
  169. OS_TASK_SW
  170. STMFD sp!, {lr} ;@ save pc
  171. STMFD sp!, {lr} ;@ save lr
  172. STMFD sp!, {r0-r12} ;@ save register file and ret address
  173. MRS r4, CPSR
  174. STMFD sp!, {r4} ;@ save current PSR
  175. MRS r4, SPSR ;@ YYY+
  176. STMFD sp!, {r4} ;@ YYY+ save SPSR
  177. ; # OSPrioCur = OSPrioHighRdy
  178. LDR r4, =OSPrioCur
  179. LDR r5, =OSPrioHighRdy
  180. LDRB r6, [r5]
  181. STRB r6, [r4]
  182. ; @ Get current task TCB address
  183. LDR r4, =OSTCBCur
  184. LDR r5, [r4]
  185. STR sp, [r5] ;@ store sp in preempted tasks's TCB
  186. ; # Get highest priority task TCB address
  187. LDR r6, =OSTCBHighRdy
  188. LDR r6, [r6]
  189. LDR sp, [r6] ;@ get new task's stack pointer
  190. ; # OSTCBCur = OSTCBHighRdy
  191. STR r6, [r4] ;@ set new current task TCB address
  192. LDMFD sp!, {r4} ;@ YYY+
  193. MSR SPSR_cxsf, r4 ;@ YYY+
  194. LDMFD sp!, {r4} ;@ YYY+
  195. MSR CPSR_cxsf, r4 ;@ YYY+
  196. LDMFD sp!, {r0-r12, lr, pc} ;@ YYY+
  197. ;# void OSStartHighRdy(void)
  198. ;#
  199. ;# Start the task with the highest priority;
  200. ;#
  201. export OSStartHighRdy
  202. OSStartHighRdy
  203. BL OSTaskSwHook
  204. MOV R0,#1
  205. LDR R1,=OSRunning
  206. STRB R0,[R1]
  207. LDR r4, =OSTCBCur ;@ Get current task TCB address
  208. LDR r5, =OSTCBHighRdy ;@ Get highest priority task TCB address
  209. LDR r5, [r5] ;@ get stack pointer
  210. LDR sp, [r5] ;@ switch to the new stack
  211. STR r5, [r4] ;@ set new current task TCB address
  212. LDMFD sp!, {r4} ;@ YYY
  213. MSR SPSR_cxsf, r4
  214. LDMFD sp!, {r4} ;@ get new state from top of the stack
  215. MSR CPSR_cxsf, r4 ;@ CPSR should be SVC32Mode
  216. LDMFD sp!, {r0-r12, lr, pc } ;@ start the new task
  217.     END