portmacro.s90 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 <iom323.h>
  29. ; Declare all extern symbols here - including any ISRs that are referenced in
  30. ; the vector table.
  31. ; ISR functions
  32. ; -------------
  33. EXTERN SIG_OUTPUT_COMPARE1A
  34. EXTERN SIG_UART_RECV
  35. EXTERN SIG_UART_DATA
  36. ; Functions used by scheduler
  37. ; ---------------------------
  38. EXTERN vTaskSwitchContext
  39. EXTERN pxCurrentTCB
  40. EXTERN xTaskIncrementTick
  41. EXTERN uxCriticalNesting
  42. ; Functions implemented in this file
  43. ; ----------------------------------
  44. PUBLIC vPortYield
  45. PUBLIC vPortYieldFromTick
  46. PUBLIC vPortStart
  47. ; Interrupt vector table.
  48. ; -----------------------
  49. ;
  50. ; For simplicity the RTOS tick interrupt routine uses the __task keyword.
  51. ; As the IAR compiler does not permit a function to be declared using both
  52. ; __task and __interrupt, the use of __task necessitates that the interrupt
  53. ; vector table be setup manually.
  54. ;
  55. ; To write an ISR, implement the ISR function using the __interrupt keyword
  56. ; but do not install the interrupt using the "#pragma vector=ABC" method.
  57. ; Instead manually place the name of the ISR in the vector table using an
  58. ; ORG and jmp instruction as demonstrated below.
  59. ; You will also have to add an EXTERN statement at the top of the file.
  60. ASEG
  61. ORG TIMER1_COMPA_vect ; Vector address
  62. jmp SIG_OUTPUT_COMPARE1A ; ISR
  63. ORG USART_RXC_vect ; Vector address
  64. jmp SIG_UART_RECV ; ISR
  65. ORG USART_UDRE_vect ; Vector address
  66. jmp SIG_UART_DATA ; ISR
  67. RSEG CODE
  68. ; Saving and Restoring a Task Context and Task Switching
  69. ; ------------------------------------------------------
  70. ;
  71. ; The IAR compiler does not fully support inline assembler, so saving and
  72. ; restoring a task context has to be written in an asm file.
  73. ;
  74. ; vPortYield() and vPortYieldFromTick() are usually written in C. Doing
  75. ; so in this case would required calls to be made to portSAVE_CONTEXT() and
  76. ; portRESTORE_CONTEXT(). This is dis-advantageous as the context switch
  77. ; function would require two extra jump and return instructions over the
  78. ; WinAVR equivalent.
  79. ;
  80. ; To avoid this I have opted to implement both vPortYield() and
  81. ; vPortYieldFromTick() in this assembly file. For convenience
  82. ; portSAVE_CONTEXT and portRESTORE_CONTEXT are implemented as macros.
  83. portSAVE_CONTEXT MACRO
  84. st -y, r0 ; First save the r0 register - we need to use this.
  85. in r0, SREG ; Obtain the SREG value so we can disable interrupts...
  86. cli ; ... as soon as possible.
  87. st -y, r0 ; Store the SREG as it was before we disabled interrupts.
  88. in r0, SPL ; Next store the hardware stack pointer. The IAR...
  89. st -y, r0 ; ... compiler uses the hardware stack as a call stack ...
  90. in r0, SPH ; ... only.
  91. st -y, r0
  92. st -y, r1 ; Now store the rest of the registers. Dont store the ...
  93. st -y, r2 ; ... the Y register here as it is used as the software
  94. st -y, r3 ; stack pointer and will get saved into the TCB.
  95. st -y, r4
  96. st -y, r5
  97. st -y, r6
  98. st -y, r7
  99. st -y, r8
  100. st -y, r9
  101. st -y, r10
  102. st -y, r11
  103. st -y, r12
  104. st -y, r13
  105. st -y, r14
  106. st -y, r15
  107. st -y, r16
  108. st -y, r17
  109. st -y, r18
  110. st -y, r19
  111. st -y, r20
  112. st -y, r21
  113. st -y, r22
  114. st -y, r23
  115. st -y, r24
  116. st -y, r25
  117. st -y, r26
  118. st -y, r27
  119. st -y, r30
  120. st -y, r31
  121. lds r0, uxCriticalNesting
  122. st -y, r0 ; Store the critical nesting counter.
  123. lds r26, pxCurrentTCB ; Finally save the software stack pointer (Y ...
  124. lds r27, pxCurrentTCB + 1 ; ... register) into the TCB.
  125. st x+, r28
  126. st x+, r29
  127. ENDM
  128. portRESTORE_CONTEXT MACRO
  129. lds r26, pxCurrentTCB
  130. lds r27, pxCurrentTCB + 1 ; Restore the software stack pointer from ...
  131. ld r28, x+ ; the TCB into the software stack pointer (...
  132. ld r29, x+ ; ... the Y register).
  133. ld r0, y+
  134. sts uxCriticalNesting, r0
  135. ld r31, y+ ; Restore the registers down to R0. The Y
  136. ld r30, y+ ; register is missing from this list as it
  137. ld r27, y+ ; has already been restored.
  138. ld r26, y+
  139. ld r25, y+
  140. ld r24, y+
  141. ld r23, y+
  142. ld r22, y+
  143. ld r21, y+
  144. ld r20, y+
  145. ld r19, y+
  146. ld r18, y+
  147. ld r17, y+
  148. ld r16, y+
  149. ld r15, y+
  150. ld r14, y+
  151. ld r13, y+
  152. ld r12, y+
  153. ld r11, y+
  154. ld r10, y+
  155. ld r9, y+
  156. ld r8, y+
  157. ld r7, y+
  158. ld r6, y+
  159. ld r5, y+
  160. ld r4, y+
  161. ld r3, y+
  162. ld r2, y+
  163. ld r1, y+
  164. ld r0, y+ ; The next thing on the stack is the ...
  165. out SPH, r0 ; ... hardware stack pointer.
  166. ld r0, y+
  167. out SPL, r0
  168. ld r0, y+ ; Next there is the SREG register.
  169. out SREG, r0
  170. ld r0, y+ ; Finally we have finished with r0, so restore r0.
  171. ENDM
  172. ; vPortYield() and vPortYieldFromTick()
  173. ; -------------------------------------
  174. ;
  175. ; Manual and preemptive context switch functions respectively.
  176. ; The IAR compiler does not fully support inline assembler,
  177. ; so these are implemented here rather than the more usually
  178. ; place of within port.c.
  179. vPortYield:
  180. portSAVE_CONTEXT ; Save the context of the current task.
  181. call vTaskSwitchContext ; Call the scheduler.
  182. portRESTORE_CONTEXT ; Restore the context of whichever task the ...
  183. ret ; ... scheduler decided should run.
  184. vPortYieldFromTick:
  185. portSAVE_CONTEXT ; Save the context of the current task.
  186. call xTaskIncrementTick ; Call the timer tick function.
  187. tst r16
  188. breq SkipTaskSwitch
  189. call vTaskSwitchContext ; Call the scheduler.
  190. SkipTaskSwitch:
  191. portRESTORE_CONTEXT ; Restore the context of whichever task the ...
  192. ret ; ... scheduler decided should run.
  193. ; vPortStart()
  194. ; ------------
  195. ;
  196. ; Again due to the lack of inline assembler, this is required
  197. ; to get access to the portRESTORE_CONTEXT macro.
  198. vPortStart:
  199. portRESTORE_CONTEXT
  200. ret
  201. ; Just a filler for unused interrupt vectors.
  202. vNoISR:
  203. reti
  204. END