portmacro.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * FreeRTOS Kernel <DEVELOPMENT BRANCH>
  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. #ifndef PORTMACRO_H
  29. #define PORTMACRO_H
  30. /* *INDENT-OFF* */
  31. #ifdef __cplusplus
  32. extern "C" {
  33. #endif
  34. /* *INDENT-ON* */
  35. /*-----------------------------------------------------------
  36. * Port specific definitions.
  37. *
  38. * The settings in this file configure FreeRTOS correctly for the given hardware
  39. * and compiler.
  40. *
  41. * These settings should not be altered.
  42. *-----------------------------------------------------------
  43. */
  44. /* Type definitions. */
  45. #define portCHAR char
  46. #define portFLOAT float
  47. #define portDOUBLE double
  48. #define portLONG long
  49. #define portSHORT short
  50. #define portSTACK_TYPE uint32_t
  51. #define portBASE_TYPE long
  52. typedef portSTACK_TYPE StackType_t;
  53. typedef long BaseType_t;
  54. typedef unsigned long UBaseType_t;
  55. typedef uint32_t TickType_t;
  56. #define portMAX_DELAY ( ( TickType_t ) 0xffffffffUL )
  57. /*-----------------------------------------------------------*/
  58. /* Hardware specifics. */
  59. #define portSTACK_GROWTH ( -1 )
  60. #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
  61. #define portBYTE_ALIGNMENT 32
  62. /*-----------------------------------------------------------*/
  63. /* Task utilities. */
  64. /* The interrupt priority (for vectors 16 to 255) is determined using vector/16.
  65. * The quotient is rounded to the nearest integer with 1 being the lowest priority
  66. * and 15 is the highest. Therefore the following two interrupts are at the lowest
  67. * priority. *NOTE 1* If the yield vector is changed then it must also be changed
  68. * in the portYIELD_INTERRUPT definition immediately below. */
  69. #define portAPIC_TIMER_INT_VECTOR ( 0x21 )
  70. #define portAPIC_YIELD_INT_VECTOR ( 0x20 )
  71. /* Build yield interrupt instruction. */
  72. #define portYIELD_INTERRUPT "int $0x20"
  73. /* APIC register addresses. */
  74. #define portAPIC_EOI ( *( ( volatile uint32_t * ) 0xFEE000B0UL ) )
  75. /* APIC bit definitions. */
  76. #define portAPIC_ENABLE_BIT ( 1UL << 8UL )
  77. #define portAPIC_TIMER_PERIODIC ( 1UL << 17UL )
  78. #define portAPIC_DISABLE ( 1UL << 16UL )
  79. #define portAPIC_NMI ( 4 << 8 )
  80. #define portAPIC_DIV_16 ( 0x03 )
  81. /* Define local API register addresses. */
  82. #define portAPIC_ID_REGISTER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x20UL ) ) )
  83. #define portAPIC_SPURIOUS_INT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xF0UL ) ) )
  84. #define portAPIC_LVT_TIMER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x320UL ) ) )
  85. #define portAPIC_TIMER_INITIAL_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x380UL ) ) )
  86. #define portAPIC_TIMER_CURRENT_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x390UL ) ) )
  87. #define portAPIC_TASK_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x80UL ) ) )
  88. #define portAPIC_LVT_ERROR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x370UL ) ) )
  89. #define portAPIC_ERROR_STATUS ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x280UL ) ) )
  90. #define portAPIC_LDR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xD0UL ) ) )
  91. #define portAPIC_TMRDIV ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x3E0UL ) ) )
  92. #define portAPIC_LVT_PERF ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x340UL ) ) )
  93. #define portAPIC_LVT_LINT0 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x350UL ) ) )
  94. #define portAPIC_LVT_LINT1 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x360UL ) ) )
  95. /* Don't yield if inside a critical section - instead hold the yield pending
  96. * so it is performed when the critical section is exited. */
  97. #define portYIELD() \
  98. { \
  99. extern volatile uint32_t ulCriticalNesting; \
  100. extern volatile uint32_t ulPortYieldPending; \
  101. if( ulCriticalNesting != 0 ) \
  102. { \
  103. ulPortYieldPending = pdTRUE; \
  104. } \
  105. else \
  106. { \
  107. __asm volatile ( portYIELD_INTERRUPT ); \
  108. } \
  109. }
  110. /* Called at the end of an ISR that can cause a context switch - pend a yield if
  111. * xSwitchRequired is not false. */
  112. #define portEND_SWITCHING_ISR( xSwitchRequired ) \
  113. { \
  114. extern volatile uint32_t ulPortYieldPending; \
  115. if( xSwitchRequired != pdFALSE ) \
  116. { \
  117. ulPortYieldPending = 1; \
  118. } \
  119. }
  120. /* Same as portEND_SWITCHING_ISR() - take your pick which name to use. */
  121. #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
  122. /*-----------------------------------------------------------
  123. * Critical section control
  124. *----------------------------------------------------------*/
  125. /* Critical sections for use in interrupts. */
  126. #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
  127. #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
  128. extern void vPortEnterCritical( void );
  129. extern void vPortExitCritical( void );
  130. extern uint32_t ulPortSetInterruptMask( void );
  131. extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
  132. /* These macros do not globally disable/enable interrupts. They do mask off
  133. * interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
  134. #define portENTER_CRITICAL() vPortEnterCritical()
  135. #define portEXIT_CRITICAL() vPortExitCritical()
  136. #define portDISABLE_INTERRUPTS() __asm volatile ( "cli" )
  137. #define portENABLE_INTERRUPTS() __asm volatile ( "sti" )
  138. /*-----------------------------------------------------------*/
  139. /* Task function macros as described on the FreeRTOS.org WEB site. These are
  140. * not required for this port but included in case common demo code that uses these
  141. * macros is used. */
  142. #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
  143. #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
  144. /* Architecture specific optimisations. */
  145. #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
  146. /* Store/clear the ready priorities in a bit map. */
  147. #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
  148. __asm volatile ( "bsr %1, %0\n\t" \
  149. : "=r" ( uxTopPriority ) : "rm" ( uxReadyPriorities ) : "cc" )
  150. #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
  151. #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
  152. #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
  153. #define portNOP() __asm volatile ( "NOP" )
  154. /*-----------------------------------------------------------
  155. * Misc
  156. *----------------------------------------------------------*/
  157. #define portNUM_VECTORS 256
  158. #define portMAX_PRIORITY 15
  159. typedef void ( * ISR_Handler_t ) ( void );
  160. /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
  161. * before any floating point instructions are executed. */
  162. #ifndef configSUPPORT_FPU
  163. #define configSUPPORT_FPU 0
  164. #endif
  165. #if configSUPPORT_FPU == 1
  166. void vPortTaskUsesFPU( void );
  167. #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
  168. #endif
  169. /* See the comments under the configUSE_COMMON_INTERRUPT_ENTRY_POINT definition
  170. * below. */
  171. BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler,
  172. uint32_t ulVectorNumber );
  173. BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler,
  174. uint32_t ulVectorNumber );
  175. #ifndef configAPIC_BASE
  176. /* configAPIC_BASE_ADDRESS sets the base address of the local APIC. It can
  177. * be overridden in FreeRTOSConfig.h should it not be constant. */
  178. #define configAPIC_BASE 0xFEE00000UL
  179. #endif
  180. #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
  181. /* The FreeRTOS scheduling algorithm selects the task that will enter the
  182. * Running state. configUSE_PORT_OPTIMISED_TASK_SELECTION is used to set how
  183. * that is done.
  184. *
  185. * If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0 then the task to
  186. * enter the Running state is selected using a portable algorithm written in
  187. * C. This is the slowest method, but the algorithm does not restrict the
  188. * maximum number of unique RTOS task priorities that are available.
  189. *
  190. * If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 then the task to
  191. * enter the Running state is selected using a single assembly instruction.
  192. * This is the fastest method, but restricts the maximum number of unique RTOS
  193. * task priorities to 32 (the same task priority can be assigned to any number
  194. * of RTOS tasks). */
  195. #warning configUSE_PORT_OPTIMISED_TASK_SELECTION was not defined in FreeRTOSConfig.h and has been defaulted to 1
  196. #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
  197. #endif
  198. #ifndef configUSE_COMMON_INTERRUPT_ENTRY_POINT
  199. /* There are two ways of implementing interrupt handlers:
  200. *
  201. * 1) As standard C functions -
  202. *
  203. * This method can only be used if configUSE_COMMON_INTERRUPT_ENTRY_POINT
  204. * is set to 1. The C function is installed using
  205. * xPortRegisterCInterruptHandler().
  206. *
  207. * This is the simplest of the two methods but incurs a slightly longer
  208. * interrupt entry time.
  209. *
  210. * 2) By using an assembly stub that wraps the handler in the FreeRTOS
  211. * portFREERTOS_INTERRUPT_ENTRY and portFREERTOS_INTERRUPT_EXIT macros.
  212. *
  213. * This method can always be used. It is slightly more complex than
  214. * method 1 but benefits from a faster interrupt entry time. */
  215. #warning configUSE_COMMON_INTERRUPT_ENTRY_POINT was not defined in FreeRTOSConfig.h and has been defaulted to 1.
  216. #define configUSE_COMMON_INTERRUPT_ENTRY_POINT 1
  217. #endif
  218. #ifndef configISR_STACK_SIZE
  219. /* Interrupt entry code will switch the stack in use to a dedicated system
  220. * stack.
  221. *
  222. * configISR_STACK_SIZE defines the number of 32-bit values that can be stored
  223. * on the system stack, and must be large enough to hold a potentially nested
  224. * interrupt stack frame. */
  225. #error configISR_STACK_SIZE was not defined in FreeRTOSConfig.h.
  226. #endif
  227. #ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
  228. /* Interrupt safe FreeRTOS functions (those that end in "FromISR" must not
  229. * be called from an interrupt that has a priority above that set by
  230. * configMAX_API_CALL_INTERRUPT_PRIORITY. */
  231. #warning configMAX_API_CALL_INTERRUPT_PRIORITY was not defined in FreeRTOSConfig.h and has been defaulted to 10
  232. #define configMAX_API_CALL_INTERRUPT_PRIORITY 10
  233. #endif
  234. #ifndef configSUPPORT_FPU
  235. #warning configSUPPORT_FPU was not defined in FreeRTOSConfig.h and has been defaulted to 0
  236. #define configSUPPORT_FPU 0
  237. #endif
  238. /* The value written to the task priority register to raise the interrupt mask
  239. * to the maximum from which FreeRTOS API calls can be made. */
  240. #define portAPIC_PRIORITY_SHIFT ( 4UL )
  241. #define portAPIC_MAX_SUB_PRIORITY ( 0x0fUL )
  242. #define portMAX_API_CALL_PRIORITY ( ( configMAX_API_CALL_INTERRUPT_PRIORITY << portAPIC_PRIORITY_SHIFT ) | portAPIC_MAX_SUB_PRIORITY )
  243. /* Asserts if interrupt safe FreeRTOS functions are called from a priority
  244. * above the max system call interrupt priority. */
  245. #define portAPIC_PROCESSOR_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xA0UL ) ) )
  246. #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( portAPIC_PROCESSOR_PRIORITY ) <= ( portMAX_API_CALL_PRIORITY ) )
  247. /* *INDENT-OFF* */
  248. #ifdef __cplusplus
  249. }
  250. #endif
  251. /* *INDENT-ON* */
  252. #endif /* PORTMACRO_H */