Os_cpu_a.s
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:16k
源码类别:

uCOS

开发平台:

C/C++

  1. ;*********************************************************************************************************
  2. ;                                               uC/OS-II
  3. ;                                         The Real-Time Kernel
  4. ;
  5. ;                          (c) Copyright 1992-2003, Jean J. Labrosse, Weston, FL
  6. ;                                          All Rights Reserved
  7. ;
  8. ;                                               ARM920T Port
  9. ;                                            ADS v1.2 Compiler
  10. ;                                             Samsung S3C2440A
  11. ;
  12. ; File    : os_cpu_a.s refrence to ucos application note for arm AN-1014
  13. ; Des   : S3C2440 uC/OS-II Port 
  14. ; by      : tangxiaofeng xidian 503
  15. ; History : 
  16. ;  OSCtxSw(), OSIntCtxSw()  OSStartHighRdy() OS_CPU_IRQ_ISR() OSTickISR()
  17. ;******************************************************************************************************** */
  18. SRCPND    EQU  0x4a000000    ; Source pending
  19. INTPND    EQU  0x4a000010    ; Interrupt request status
  20. rEINTPEND   EQU  0x560000a8
  21. INTOFFSET   EQU  0x4a000014
  22. USERMODE    EQU  0x10
  23. FIQMODE     EQU  0x11
  24. IRQMODE     EQU  0x12
  25. SVCMODE     EQU  0x13
  26. ABORTMODE   EQU  0x17
  27. UNDEFMODE   EQU  0x1b
  28. MODEMASK    EQU  0x1f
  29. NOINT       EQU  0xc0
  30. ;*********************************************************************************************************
  31. ;                                    EXPORT and EXTERNAL REFERENCES
  32. ;*********************************************************************************************************/
  33. IMPORT  OSRunning
  34. IMPORT  OSTCBCur
  35. IMPORT  OSTCBHighRdy
  36. IMPORT  OSPrioCur
  37. IMPORT  OSPrioHighRdy
  38. IMPORT  OSIntNesting
  39. IMPORT  OSIntEnter
  40. IMPORT  OSIntExit
  41. IMPORT  OSTaskSwHook
  42. IMPORT  OSTimeTick
  43. IMPORT  HandleEINT0
  44. EXPORT  OSStartHighRdy
  45. EXPORT  OSCtxSw
  46. EXPORT  OSTickISR
  47. EXPORT  OSIntCtxSw
  48. EXPORT  OSCPUSaveSR
  49. EXPORT  OSCPURestoreSR
  50. EXPORT  OS_CPU_IRQ_ISR
  51. AREA UCOS_ARM, CODE, READONLY
  52. ;*********************************************************************************************************
  53. ;                                          START MULTITASKING
  54. ;                                       void OSStartHighRdy(void)
  55. ;
  56. ; The stack frame is assumed to look as follows:
  57. ;
  58. ;     Entry Point(Task Name) (High memory)
  59. ;                               LR(R14)
  60. ;                               R12
  61. ;                               R11
  62. ;                               R10
  63. ;                               R9
  64. ;                               R8
  65. ;                               R7
  66. ;                               R6
  67. ;                               R5
  68. ;                               R4
  69. ;                               R3
  70. ;                               R2
  71. ;                               R1
  72. ;                               R0 : argument
  73. ; OSTCBHighRdy->OSTCBStkPtr --> CPSR (Low memory)
  74. ;
  75. ; Note : OSStartHighRdy() MUST:
  76. ;           a) Call OSTaskSwHook() then,
  77. ;           b) Set OSRunning to TRUE,
  78. ;           c) Switch to the highest priority task.
  79. ;********************************************************************************************************** */
  80. OSStartHighRdy  
  81. ;----------------------------------------------------------------------------------
  82. ; OSRunning = TRUE;
  83. ;----------------------------------------------------------------------------------
  84. MSR     CPSR_cxsf,#SVCMODE|NOINT     ;Switch to SVC mode with IRQ&FIQ disable
  85. BL OSTaskSwHook            ;Call user define Task switch hook
  86. LDR R0, =OSRunning          ; OSRunning =TRUE
  87. MOV R1, #1
  88. STRB  R1, [R0]
  89. ;----------------------------------------------------------------------------------
  90. ;  SP = OSTCBHighRdy->OSTCBStkPtr;
  91. ;----------------------------------------------------------------------------------
  92. LDR  R0, =OSTCBHighRdy
  93. LDR  R0, [R0]         
  94. LDR  SP, [R0]         
  95. ;----------------------------------------------------------------------------------
  96. ; Prepare to return to proper mode
  97. ;----------------------------------------------------------------------------------
  98. LDMFD  SP!, {R0}  
  99. MSR  SPSR_cxsf, R0
  100. LDMFD  SP!, {R0-R12, LR, PC}^
  101. ;**********************************************************************************************************
  102. ;                                PERFORM A CONTEXT SWITCH (From task level)
  103. ;                                           void OSCtxSw(void)
  104. ;
  105. ; Note(s):     1) Upon entry: 
  106. ;                 OSTCBCur      points to the OS_TCB of the task to suspend
  107. ;                 OSTCBHighRdy  points to the OS_TCB of the task to resume
  108. ;
  109. ;              2) The stack frame of the task to suspend looks as follows:
  110. ;                                                   
  111. ;                                                   PC                    (High memory)
  112. ;    LR(R14)
  113. ;                                R12
  114. ;                                 R11
  115. ;                                 R10
  116. ;                                  R9
  117. ;                                 R8
  118. ;                                R7
  119. ;                                R6
  120. ;                                R5
  121. ;                                R4
  122. ;                                R3
  123. ;                                R2
  124. ;                                R1
  125. ;                                R0
  126. ;  OSTCBCur->OSTCBStkPtr ----> CPSR (Low memory)
  127. ;
  128. ;
  129. ;              3) The stack frame of the task to resume looks as follows:
  130. ;
  131. ;       PC (High memory)
  132. ;                                                   LR(R14)
  133. ;                                 R12
  134. ;                                 R11
  135. ;                                 R10
  136. ;                                  R9
  137. ;                                R8
  138. ;                                R7
  139. ;                                 R6
  140. ;                                 R5
  141. ;                                 R4
  142. ;                                 R3
  143. ;                                R2
  144. ;                                R1
  145. ;                                 R0
  146. ;  OSTCBHighRdy->OSTCBStkPtr ----> CPSR (Low memory)
  147. ;*********************************************************************************************************/
  148. OSCtxSw
  149. STMFD SP!, {LR}           ;PC
  150. STMFD SP!, {R0-R12, LR}   ;R0-R12 LR
  151. MRS R0,  CPSR       ;Push CPSR
  152. STMFD SP!, {R0}
  153. ;----------------------------------------------------------------------------------
  154. ;  OSTCBCur->OSTCBStkPtr = SP
  155. ;----------------------------------------------------------------------------------
  156. LDR R0, =OSTCBCur
  157. LDR R0, [R0]
  158. STR SP, [R0]
  159. ;----------------------------------------------------------------------------------
  160. ; OSTaskSwHook();
  161. ;---------------------------------------------------------------------------------
  162. BL  OSTaskSwHook
  163. ;----------------------------------------------------------------------------------
  164. ; OSTCBCur = OSTCBHighRdy;
  165. ;----------------------------------------------------------------------------------
  166. LDR R0, =OSTCBHighRdy
  167. LDR R1, =OSTCBCur
  168. LDR R0, [R0]
  169. STR R0, [R1]
  170. ;----------------------------------------------------------------------------------
  171. ; OSPrioCur = OSPrioHighRdy;
  172. ;----------------------------------------------------------------------------------
  173. LDR R0, =OSPrioHighRdy
  174. LDR R1, =OSPrioCur
  175. LDRB R0, [R0]
  176. STRB R0, [R1]
  177. ;----------------------------------------------------------------------------------
  178. ;  OSTCBHighRdy->OSTCBStkPtr;
  179. ;----------------------------------------------------------------------------------
  180. LDR R0, =OSTCBHighRdy
  181. LDR R0, [R0]
  182. LDR SP, [R0]
  183. ;----------------------------------------------------------------------------------
  184. ;Restore New task context
  185. ;----------------------------------------------------------------------------------
  186. LDMFD  SP!, {R0} ;POP CPSR
  187. MSR  SPSR_cxsf, R0
  188. LDMFD  SP!, {R0-R12, LR, PC}^
  189. ;*********************************************************************************************************
  190. ;                                            TICK HANDLER
  191. ;
  192. ; Description:  
  193. ;     This handles all the Timer0(INT_TIMER0) interrupt which is used to generate the uC/OS-II tick.
  194. ;*********************************************************************************************************/
  195. OSTickISR
  196. MOV     R5,LR
  197. MOV  R1, #1
  198. MOV R1, R1, LSL #10 ; Timer0 Source Pending Reg.
  199. LDR  R0, =SRCPND
  200. LDR     R2, [R0]
  201. ORR     R1, R1,R2
  202. STR  R1, [R0]
  203. LDR R0, =INTPND
  204. LDR R1, [R0]
  205. STR R1, [R0]
  206. ;----------------------------------------------------------------------------------
  207. ; OSTimeTick();
  208. ;----------------------------------------------------------------------------------
  209. BL OSTimeTick
  210.   
  211. MOV    PC, R5         ; Return 
  212. ;*********************************************************************************************************
  213. ;                                PERFORM A CONTEXT SWITCH (From an ISR)
  214. ;                                        void OSIntCtxSw(void)
  215. ;
  216. ; Description: 1) This code performs a context switch if a higher priority task has been made ready-to-run
  217. ;                during an ISR.
  218. ;
  219. ;              2) The stack frame of the task to suspend looks as follows:
  220. ;
  221. ;    PC (High memory)
  222. ;                                                   LR(R14)
  223. ;                                R12
  224. ;                                 R11
  225. ;                                 R10
  226. ;                                  R9
  227. ;                                 R8
  228. ;                                R7
  229. ;                                R6
  230. ;                                R5
  231. ;                                R4
  232. ;                                R3
  233. ;                                R2
  234. ;                                R1
  235. ;                                R0
  236. ;                               
  237. ;  OSTCBCur->OSTCBStkPtr ----> CPSR (Low memory)
  238. ;
  239. ;
  240. ;              3) The stack frame of the task to resume looks as follows:
  241. ;
  242. ;       PC (High memory)
  243. ;                                                   LR(R14)
  244. ;                                 R12
  245. ;                                 R11
  246. ;                                 R10
  247. ;                                  R9
  248. ;                                R8
  249. ;                                R7
  250. ;                                 R6
  251. ;                                 R5
  252. ;                                 R4
  253. ;                                 R3
  254. ;                                R2
  255. ;                                R1
  256. ;                                 R0
  257. ;  OSTCBHighRdy->OSTCBStkPtr ----> CPSR (Low memory)
  258. ;*********************************************************************************************************/
  259. OSIntCtxSw
  260. ;----------------------------------------------------------------------------------
  261. ; Call OSTaskSwHook();
  262. ;----------------------------------------------------------------------------------
  263. BL  OSTaskSwHook
  264. ;----------------------------------------------------------------------------------
  265. ; OSTCBCur = OSTCBHighRdy;
  266. ;----------------------------------------------------------------------------------
  267. LDR R0, =OSTCBHighRdy
  268. LDR R1, =OSTCBCur
  269. LDR R0, [R0]
  270. STR R0, [R1]
  271. ;----------------------------------------------------------------------------------
  272. ; OSPrioCur = OSPrioHighRdy;
  273. ;----------------------------------------------------------------------------------
  274. LDR R0, =OSPrioHighRdy
  275. LDR R1, =OSPrioCur
  276. LDRB R0, [R0]
  277. STRB R0, [R1]
  278. ;----------------------------------------------------------------------------------
  279. ;  SP = OSTCBHighRdy->OSTCBStkPtr;
  280. ;----------------------------------------------------------------------------------
  281. LDR R0, =OSTCBHighRdy
  282. LDR R0, [R0]
  283. LDR SP, [R0]
  284. ;----------------------------------------------------------------------------------
  285. ; Restore New Task context
  286. ;----------------------------------------------------------------------------------
  287. LDMFD  SP!, {R0}              ;POP CPSR
  288. MSR  SPSR_cxsf, R0
  289. LDMFD  SP!, {R0-R12, LR, PC}^
  290. OS_CPU_IRQ_ISR 
  291. STMFD   SP!, {R1-R3} ; We will use R1-R3 as temporary registers
  292. ;----------------------------------------------------------------------------
  293. ;   R1--SP
  294. ; R2--PC 
  295. ;   R3--SPSR
  296. ;------------------------------------------------------------------------
  297. MOV     R1, SP
  298. ADD     SP, SP, #12             ;Adjust IRQ stack pointer
  299. SUB     R2, LR, #4              ;Adjust PC for return address to task
  300. MRS     R3, SPSR ; Copy SPSR (Task CPSR)
  301.    
  302. MSR     CPSR_cxsf, #SVCMODE|NOINT   ;Change to SVC mode
  303. ; SAVE TASK''S CONTEXT ONTO OLD TASK''S STACK
  304. STMFD   SP!, {R2} ; Push task''s PC 
  305. STMFD   SP!, {R4-R12, LR} ; Push task''s LR,R12-R4
  306. LDMFD   R1!, {R4-R6} ; Load Task''s R1-R3 from IRQ stack 
  307. STMFD   SP!, {R4-R6} ; Push Task''s R1-R3 to SVC stack
  308. STMFD   SP!, {R0}     ; Push Task''s R0 to SVC stack
  309. STMFD   SP!, {R3} ; Push task''s CPSR
  310. LDR     R0,=OSIntNesting        ;OSIntNesting++
  311. LDRB    R1,[R0]
  312. ADD     R1,R1,#1
  313. STRB    R1,[R0] 
  314. CMP     R1,#1                   ;if(OSIntNesting==1){
  315. BNE     %F1
  316.  
  317. LDR     R4,=OSTCBCur            ;OSTCBHighRdy->OSTCBStkPtr=SP;
  318. LDR     R5,[R4]
  319. STR     SP,[R5]                 ;}
  320. 1
  321. MSR    CPSR_c,#IRQMODE|NOINT    ;Change to IRQ mode to use IRQ stack to handle interrupt
  322. LDR     R0, =INTOFFSET
  323.     LDR     R0, [R0]
  324.        
  325.     LDR     R1, IRQIsrVect
  326.     MOV     LR, PC                          ; Save LR befor jump to the C function we need return back
  327.     LDR     PC, [R1, R0, LSL #2]            ; Call OS_CPU_IRQ_ISR_handler();   
  328.     
  329.     MSR CPSR_c,#SVCMODE|NOINT   ;Change to SVC mode
  330.     BL  OSIntExit           ;Call OSIntExit
  331.     
  332.     LDMFD   SP!,{R4}               ;POP the task''s CPSR 
  333.     MSR SPSR_cxsf,R4
  334.     LDMFD   SP!,{R0-R12,LR,PC}^    ;POP new Task''s context
  335. IRQIsrVect DCD HandleEINT0
  336.     
  337. ;*********************************************************************************************************
  338. ;                                   CRITICAL SECTION METHOD 3 FUNCTIONS
  339. ;
  340. ; Description: Disable/Enable interrupts by preserving the state of interrupts.  Generally speaking you
  341. ;              would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
  342. ;              disable interrupts.  'cpu_sr' is allocated in all of uC/OS-II''s functions that need to 
  343. ;              disable interrupts.  You would restore the interrupt disable state by copying back 'cpu_sr'
  344. ;              into the CPU''s status register.
  345. ;
  346. ; Prototypes : OS_CPU_SR  OSCPUSaveSR(void);
  347. ;              void       OSCPURestoreSR(OS_CPU_SR cpu_sr);
  348. ;
  349. ;
  350. ; Note(s)    : 1) These functions are used in general like this:
  351. ;
  352. ;                 void Task (void *p_arg)
  353. ;                 {
  354. ;                 #if OS_CRITICAL_METHOD == 3          /* Allocate storage for CPU status register */
  355. ;                     OS_CPU_SR  cpu_sr;
  356. ;                 #endif
  357. ;
  358. ;                          :
  359. ;                          :
  360. ;                     OS_ENTER_CRITICAL();             /* cpu_sr = OSCPUSaveSR();                */
  361. ;                          :
  362. ;                          :
  363. ;                     OS_EXIT_CRITICAL();              /* OSCPURestoreSR(cpu_sr);                */
  364. ;                          :
  365. ;                          :
  366. ;                 }
  367. ;
  368. ;              2) OSCPUSaveSR() is implemented as recommended by Atmel''s application note:
  369. ;
  370. ;                    "Disabling Interrupts at Processor Level"
  371. ;*********************************************************************************************************
  372. OSCPUSaveSR
  373. MRS     R0, CPSR ; Set IRQ and FIQ bits in CPSR to disable all interrupts
  374. ORR     R1, R0, #0xC0
  375. MSR     CPSR_c, R1
  376. MRS     R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags
  377. AND     R1, R1, #0xC0
  378. CMP     R1, #0xC0
  379. BNE     OSCPUSaveSR ; Not properly disabled (try again)
  380. MOV     PC, LR ; Disabled, return the original CPSR contents in R0
  381. OSCPURestoreSR
  382. MSR     CPSR_c, R0
  383. MOV     PC, LR
  384.         
  385. END