portmacro.s90 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. ;/*
  2. ; * FreeRTOS Kernel V10.4.6
  3. ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. ; *
  5. ; * SPDX-License-Identifier: MIT
  6. ; *
  7. ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. ; * this software and associated documentation files (the "Software"), to deal in
  9. ; * the Software without restriction, including without limitation the rights to
  10. ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  11. ; * the Software, and to permit persons to whom the Software is furnished to do so,
  12. ; * subject to the following conditions:
  13. ; *
  14. ; * The above copyright notice and this permission notice shall be included in all
  15. ; * copies or substantial portions of the Software.
  16. ; *
  17. ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  19. ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  20. ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  21. ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. ; *
  24. ; * https://www.FreeRTOS.org
  25. ; * https://github.com/FreeRTOS
  26. ; *
  27. ; */
  28. #include "porthardware.h"
  29. ; Declare all extern symbols here - including any ISRs that are referenced in
  30. ; the vector table.
  31. ; ISR functions
  32. ; -------------
  33. EXTERN TICK_INT
  34. ; Functions used by scheduler
  35. ; ---------------------------
  36. EXTERN vTaskSwitchContext
  37. EXTERN pxCurrentTCB
  38. EXTERN xTaskIncrementTick
  39. EXTERN uxCriticalNesting
  40. ; Functions implemented in this file
  41. ; ----------------------------------
  42. PUBLIC vPortYield
  43. PUBLIC vPortYieldFromTick
  44. PUBLIC vPortYieldFromISR
  45. PUBLIC vPortStart
  46. ; Interrupt vector table.
  47. ; -----------------------
  48. ;
  49. ; For simplicity the RTOS tick interrupt routine uses the __task keyword.
  50. ; As the IAR compiler does not permit a function to be declared using both
  51. ; __task and __interrupt, the use of __task necessitates that the interrupt
  52. ; vector table be setup manually.
  53. ;
  54. ; To write an ISR, implement the ISR function using the __interrupt keyword
  55. ; but do not install the interrupt using the "#pragma vector=ABC" method.
  56. ; Instead manually place the name of the ISR in the vector table using an
  57. ; ORG and jmp instruction as demonstrated below.
  58. ; You will also have to add an EXTERN statement at the top of the file.
  59. ASEG
  60. ORG TICK_INT_vect ; Vector address
  61. jmp TICK_INT ; ISR
  62. RSEG CODE
  63. CLR_INT MACRO FLAG_REG, FLAG_MASK
  64. st -y, r16
  65. ldi r16, FLAG_MASK
  66. sts FLAG_REG, r16
  67. ld r16, y+
  68. ENDM
  69. ; Saving and Restoring a Task Context and Task Switching
  70. ; ------------------------------------------------------
  71. ;
  72. ; The IAR compiler does not fully support inline assembler, so saving and
  73. ; restoring a task context has to be written in an asm file.
  74. ;
  75. ; vPortYield() and vPortYieldFromTick() are usually written in C. Doing
  76. ; so in this case would required calls to be made to portSAVE_CONTEXT() and
  77. ; portRESTORE_CONTEXT(). This is dis-advantageous as the context switch
  78. ; function would require two extra jump and return instructions over the
  79. ; WinAVR equivalent.
  80. ;
  81. ; To avoid this I have opted to implement both vPortYield() and
  82. ; vPortYieldFromTick() in this assembly file. For convenience
  83. ; portSAVE_CONTEXT and portRESTORE_CONTEXT are implemented as macros.
  84. portSAVE_CONTEXT MACRO
  85. st -y, r0 ; First save the r0 register - we need to use this.
  86. in r0, SREG ; Obtain the SREG value so we can disable interrupts...
  87. cli ; ... as soon as possible.
  88. st -y, r0 ; Store the SREG as it was before we disabled interrupts.
  89. in r0, RAMPZ
  90. st -y, r0
  91. in r0, SPL ; Next store the hardware stack pointer. The IAR...
  92. st -y, r0 ; ... compiler uses the hardware stack as a call stack ...
  93. in r0, SPH ; ... only.
  94. st -y, r0
  95. st -y, r1 ; Now store the rest of the registers. Dont store the ...
  96. st -y, r2 ; ... the Y register here as it is used as the software
  97. st -y, r3 ; stack pointer and will get saved into the TCB.
  98. st -y, r4
  99. st -y, r5
  100. st -y, r6
  101. st -y, r7
  102. st -y, r8
  103. st -y, r9
  104. st -y, r10
  105. st -y, r11
  106. st -y, r12
  107. st -y, r13
  108. st -y, r14
  109. st -y, r15
  110. st -y, r16
  111. st -y, r17
  112. st -y, r18
  113. st -y, r19
  114. st -y, r20
  115. st -y, r21
  116. st -y, r22
  117. st -y, r23
  118. st -y, r24
  119. st -y, r25
  120. st -y, r26
  121. st -y, r27
  122. st -y, r30
  123. st -y, r31
  124. lds r0, uxCriticalNesting
  125. st -y, r0 ; Store the critical nesting counter.
  126. lds r26, pxCurrentTCB ; Finally save the software stack pointer (Y ...
  127. lds r27, pxCurrentTCB + 1 ; ... register) into the TCB.
  128. st x+, r28
  129. st x+, r29
  130. ENDM
  131. portRESTORE_CONTEXT MACRO
  132. lds r26, pxCurrentTCB
  133. lds r27, pxCurrentTCB + 1 ; Restore the software stack pointer from ...
  134. ld r28, x+ ; the TCB into the software stack pointer (...
  135. ld r29, x+ ; ... the Y register).
  136. ld r0, y+
  137. sts uxCriticalNesting, r0
  138. ld r31, y+ ; Restore the registers down to R0. The Y
  139. ld r30, y+ ; register is missing from this list as it
  140. ld r27, y+ ; has already been restored.
  141. ld r26, y+
  142. ld r25, y+
  143. ld r24, y+
  144. ld r23, y+
  145. ld r22, y+
  146. ld r21, y+
  147. ld r20, y+
  148. ld r19, y+
  149. ld r18, y+
  150. ld r17, y+
  151. ld r16, y+
  152. ld r15, y+
  153. ld r14, y+
  154. ld r13, y+
  155. ld r12, y+
  156. ld r11, y+
  157. ld r10, y+
  158. ld r9, y+
  159. ld r8, y+
  160. ld r7, y+
  161. ld r6, y+
  162. ld r5, y+
  163. ld r4, y+
  164. ld r3, y+
  165. ld r2, y+
  166. ld r1, y+
  167. ld r0, y+ ; The next thing on the stack is the ...
  168. out SPH, r0 ; ... hardware stack pointer.
  169. ld r0, y+
  170. out SPL, r0
  171. ld r0, y+
  172. out RAMPZ, r0
  173. ld r0, y+ ; Next there is the SREG register.
  174. out SREG, r0
  175. ld r0, y+ ; Finally we have finished with r0, so restore r0.
  176. ENDM
  177. ; vPortYield(), vPortYieldFromTick() and vPortYieldFromISR()
  178. ; -------------------------------------
  179. ;
  180. ; Manual and preemptive context switch functions respectively.
  181. ; The IAR compiler does not fully support inline assembler,
  182. ; so these are implemented here rather than the more usually
  183. ; place of within port.c.
  184. vPortYield:
  185. portSAVE_CONTEXT ; Save the context of the current task.
  186. call vTaskSwitchContext ; Call the scheduler.
  187. portRESTORE_CONTEXT ; Restore the context of whichever task the ...
  188. ret ; ... scheduler decided should run.
  189. vPortYieldFromTick:
  190. CLR_INT INT_FLAGS, INT_MASK ; Clear tick interrupt flag
  191. portSAVE_CONTEXT ; Save the context of the current task.
  192. call xTaskIncrementTick ; Call the timer tick function.
  193. tst r16
  194. breq SkipTaskSwitch
  195. call vTaskSwitchContext ; Call the scheduler.
  196. SkipTaskSwitch:
  197. portRESTORE_CONTEXT ; Restore the context of whichever task the ...
  198. reti ; ... scheduler decided should run.
  199. vPortYieldFromISR:
  200. portSAVE_CONTEXT ; Save the context of the current task.
  201. call vTaskSwitchContext ; Call the scheduler.
  202. portRESTORE_CONTEXT ; Restore the context of whichever task the ...
  203. reti ; ... scheduler decided should run.
  204. ; vPortStart()
  205. ; ------------
  206. ;
  207. ; Again due to the lack of inline assembler, this is required
  208. ; to get access to the portRESTORE_CONTEXT macro.
  209. vPortStart:
  210. portRESTORE_CONTEXT
  211. ret
  212. ; Just a filler for unused interrupt vectors.
  213. vNoISR:
  214. reti
  215. END