rtx_lib.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /*
  2. * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * -----------------------------------------------------------------------------
  19. *
  20. * Project: CMSIS-RTOS RTX
  21. * Title: RTX Library Configuration
  22. *
  23. * -----------------------------------------------------------------------------
  24. */
  25. #include "cmsis_compiler.h"
  26. #include "RTX_Config.h"
  27. #include "rtx_os.h"
  28. // System Configuration
  29. // ====================
  30. // Dynamic Memory
  31. #if (OS_DYNAMIC_MEM_SIZE != 0)
  32. #if ((OS_DYNAMIC_MEM_SIZE % 8) != 0)
  33. #error "Invalid Dynamic Memory size!"
  34. #endif
  35. static uint64_t os_mem[OS_DYNAMIC_MEM_SIZE/8] \
  36. __attribute__((section(".bss.os")));
  37. #endif
  38. // Kernel Tick Frequency
  39. #if (OS_TICK_FREQ < 1)
  40. #error "Invalid Kernel Tick Frequency!"
  41. #endif
  42. // ISR FIFO Queue
  43. static void *os_isr_queue[OS_ISR_FIFO_QUEUE] \
  44. __attribute__((section(".bss.os")));
  45. // Thread Configuration
  46. // ====================
  47. #if (((OS_STACK_SIZE % 8) != 0) || (OS_STACK_SIZE < 72))
  48. #error "Invalid default Thread Stack size!"
  49. #endif
  50. #if (((OS_IDLE_THREAD_STACK_SIZE % 8) != 0) || (OS_IDLE_THREAD_STACK_SIZE < 72))
  51. #error "Invalid Idle Thread Stack size!"
  52. #endif
  53. #if (OS_THREAD_OBJ_MEM != 0)
  54. #if (OS_THREAD_NUM == 0)
  55. #error "Invalid number of user Threads!"
  56. #endif
  57. #if ((OS_THREAD_USER_STACK_SIZE != 0) && ((OS_THREAD_USER_STACK_SIZE % 8) != 0))
  58. #error "Invalid total Stack size!"
  59. #endif
  60. // Thread Control Blocks
  61. static osRtxThread_t os_thread_cb[OS_THREAD_NUM] \
  62. __attribute__((section(".bss.os.thread.cb")));
  63. // Thread Default Stack
  64. #if (OS_THREAD_DEF_STACK_NUM != 0)
  65. static uint64_t os_thread_def_stack[OS_THREAD_DEF_STACK_NUM*(OS_STACK_SIZE/8)] \
  66. __attribute__((section(".bss.os.thread.stack")));
  67. #endif
  68. // Memory Pool for Thread Control Blocks
  69. static osRtxMpInfo_t os_mpi_thread \
  70. __attribute__((section(".data.os.thread.mpi"))) =
  71. { (uint32_t)OS_THREAD_NUM, 0U, (uint32_t)osRtxThreadCbSize, &os_thread_cb[0], NULL, NULL };
  72. // Memory Pool for Thread Default Stack
  73. #if (OS_THREAD_DEF_STACK_NUM != 0)
  74. static osRtxMpInfo_t os_mpi_def_stack \
  75. __attribute__((section(".data.os.thread.mpi"))) =
  76. { (uint32_t)OS_THREAD_DEF_STACK_NUM, 0U, (uint32_t)OS_STACK_SIZE, &os_thread_def_stack[0], NULL, NULL };
  77. #endif
  78. // Memory Pool for Thread Stack
  79. #if (OS_THREAD_USER_STACK_SIZE != 0)
  80. static uint64_t os_thread_stack[2 + OS_THREAD_NUM + (OS_THREAD_USER_STACK_SIZE/8)] \
  81. __attribute__((section(".bss.os.thread.stack")));
  82. #endif
  83. #endif // (OS_THREAD_OBJ_MEM != 0)
  84. // Stack overrun checking
  85. #if (OS_STACK_CHECK == 0)
  86. // Override library function
  87. void osRtxThreadStackCheck (void);
  88. void osRtxThreadStackCheck (void) {}
  89. #endif
  90. // Idle Thread Control Block
  91. static osRtxThread_t os_idle_thread_cb \
  92. __attribute__((section(".bss.os.thread.cb")));
  93. // Idle Thread Stack
  94. static uint64_t os_idle_thread_stack[OS_IDLE_THREAD_STACK_SIZE/8] \
  95. __attribute__((section(".bss.os.thread.stack")));
  96. // Idle Thread Attributes
  97. static const osThreadAttr_t os_idle_thread_attr = {
  98. NULL,
  99. osThreadDetached,
  100. &os_idle_thread_cb,
  101. (uint32_t)sizeof(os_idle_thread_cb),
  102. &os_idle_thread_stack[0],
  103. (uint32_t)sizeof(os_idle_thread_stack),
  104. osPriorityIdle,
  105. #if defined(OS_IDLE_THREAD_TZ_MOD_ID)
  106. (uint32_t)OS_IDLE_THREAD_TZ_MOD_ID,
  107. #else
  108. 0U,
  109. #endif
  110. 0U
  111. };
  112. // Timer Configuration
  113. // ===================
  114. #if (OS_TIMER_OBJ_MEM != 0)
  115. #if (OS_TIMER_NUM == 0)
  116. #error "Invalid number of Timer objects!"
  117. #endif
  118. // Timer Control Blocks
  119. static osRtxTimer_t os_timer_cb[OS_TIMER_NUM] \
  120. __attribute__((section(".bss.os.timer.cb")));
  121. // Memory Pool for Timer Control Blocks
  122. static osRtxMpInfo_t os_mpi_timer \
  123. __attribute__((section(".data.os.timer.mpi"))) =
  124. { (uint32_t)OS_TIMER_NUM, 0U, (uint32_t)osRtxTimerCbSize, &os_timer_cb[0], NULL, NULL };
  125. #endif // (OS_TIMER_OBJ_MEM != 0)
  126. #if ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0))
  127. #if (((OS_TIMER_THREAD_STACK_SIZE % 8) != 0) || (OS_TIMER_THREAD_STACK_SIZE < 96))
  128. #error "Invalid Timer Thread Stack size!"
  129. #endif
  130. // Timer Thread Control Block
  131. static osRtxThread_t os_timer_thread_cb \
  132. __attribute__((section(".bss.os.thread.cb")));
  133. // Timer Thread Stack
  134. static uint64_t os_timer_thread_stack[OS_TIMER_THREAD_STACK_SIZE/8] \
  135. __attribute__((section(".bss.os.thread.stack")));
  136. // Timer Thread Attributes
  137. static const osThreadAttr_t os_timer_thread_attr = {
  138. NULL,
  139. osThreadDetached,
  140. &os_timer_thread_cb,
  141. (uint32_t)sizeof(os_timer_thread_cb),
  142. &os_timer_thread_stack[0],
  143. (uint32_t)sizeof(os_timer_thread_stack),
  144. //lint -e{9030} -e{9034} "cast from signed to enum"
  145. (osPriority_t)OS_TIMER_THREAD_PRIO,
  146. #if defined(OS_TIMER_THREAD_TZ_MOD_ID)
  147. (uint32_t)OS_TIMER_THREAD_TZ_MOD_ID,
  148. #else
  149. 0U,
  150. #endif
  151. 0U
  152. };
  153. // Timer Message Queue Control Block
  154. static osRtxMessageQueue_t os_timer_mq_cb \
  155. __attribute__((section(".bss.os.msgqueue.cb")));
  156. // Timer Message Queue Data
  157. static uint32_t os_timer_mq_data[osRtxMessageQueueMemSize(OS_TIMER_CB_QUEUE,8)/4] \
  158. __attribute__((section(".bss.os.msgqueue.mem")));
  159. // Timer Message Queue Attributes
  160. static const osMessageQueueAttr_t os_timer_mq_attr = {
  161. NULL,
  162. 0U,
  163. &os_timer_mq_cb,
  164. (uint32_t)sizeof(os_timer_mq_cb),
  165. &os_timer_mq_data[0],
  166. (uint32_t)sizeof(os_timer_mq_data)
  167. };
  168. #else
  169. extern void osRtxTimerThread (void *argument);
  170. void osRtxTimerThread (void *argument) {}
  171. #endif // ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0))
  172. // Event Flags Configuration
  173. // =========================
  174. #if (OS_EVFLAGS_OBJ_MEM != 0)
  175. #if (OS_EVFLAGS_NUM == 0)
  176. #error "Invalid number of Event Flags objects!"
  177. #endif
  178. // Event Flags Control Blocks
  179. static osRtxEventFlags_t os_ef_cb[OS_EVFLAGS_NUM] \
  180. __attribute__((section(".bss.os.evflags.cb")));
  181. // Memory Pool for Event Flags Control Blocks
  182. static osRtxMpInfo_t os_mpi_ef \
  183. __attribute__((section(".data.os.evflags.mpi"))) =
  184. { (uint32_t)OS_EVFLAGS_NUM, 0U, (uint32_t)osRtxEventFlagsCbSize, &os_ef_cb[0], NULL, NULL };
  185. #endif // (OS_EVFLAGS_OBJ_MEM != 0)
  186. // Mutex Configuration
  187. // ===================
  188. #if (OS_MUTEX_OBJ_MEM != 0)
  189. #if (OS_MUTEX_NUM == 0)
  190. #error "Invalid number of Mutex objects!"
  191. #endif
  192. // Mutex Control Blocks
  193. static osRtxMutex_t os_mutex_cb[OS_MUTEX_NUM] \
  194. __attribute__((section(".bss.os.mutex.cb")));
  195. // Memory Pool for Mutex Control Blocks
  196. static osRtxMpInfo_t os_mpi_mutex \
  197. __attribute__((section(".data.os.mutex.mpi"))) =
  198. { (uint32_t)OS_MUTEX_NUM, 0U, (uint32_t)osRtxMutexCbSize, &os_mutex_cb[0], NULL, NULL };
  199. #endif // (OS_MUTEX_OBJ_MEM != 0)
  200. // Semaphore Configuration
  201. // =======================
  202. #if (OS_SEMAPHORE_OBJ_MEM != 0)
  203. #if (OS_SEMAPHORE_NUM == 0)
  204. #error "Invalid number of Semaphore objects!"
  205. #endif
  206. // Semaphore Control Blocks
  207. static osRtxSemaphore_t os_semaphore_cb[OS_SEMAPHORE_NUM] \
  208. __attribute__((section(".bss.os.semaphore.cb")));
  209. // Memory Pool for Semaphore Control Blocks
  210. static osRtxMpInfo_t os_mpi_semaphore \
  211. __attribute__((section(".data.os.semaphore.mpi"))) =
  212. { (uint32_t)OS_SEMAPHORE_NUM, 0U, (uint32_t)osRtxSemaphoreCbSize, &os_semaphore_cb[0], NULL, NULL };
  213. #endif // (OS_SEMAPHORE_OBJ_MEM != 0)
  214. // Memory Pool Configuration
  215. // =========================
  216. #if (OS_MEMPOOL_OBJ_MEM != 0)
  217. #if (OS_MEMPOOL_NUM == 0)
  218. #error "Invalid number of Memory Pool objects!"
  219. #endif
  220. // Memory Pool Control Blocks
  221. static osRtxMemoryPool_t os_mp_cb[OS_MEMPOOL_NUM] \
  222. __attribute__((section(".bss.os.mempool.cb")));
  223. // Memory Pool for Memory Pool Control Blocks
  224. static osRtxMpInfo_t os_mpi_mp \
  225. __attribute__((section(".data.os.mempool.mpi"))) =
  226. { (uint32_t)OS_MEMPOOL_NUM, 0U, (uint32_t)osRtxMemoryPoolCbSize, &os_mp_cb[0], NULL, NULL };
  227. // Memory Pool for Memory Pool Data Storage
  228. #if (OS_MEMPOOL_DATA_SIZE != 0)
  229. #if ((OS_MEMPOOL_DATA_SIZE % 8) != 0)
  230. #error "Invalid Data Memory size for Memory Pools!"
  231. #endif
  232. static uint64_t os_mp_data[2 + OS_MEMPOOL_NUM + (OS_MEMPOOL_DATA_SIZE/8)] \
  233. __attribute__((section(".bss.os.mempool.mem")));
  234. #endif
  235. #endif // (OS_MEMPOOL_OBJ_MEM != 0)
  236. // Message Queue Configuration
  237. // ===========================
  238. #if (OS_MSGQUEUE_OBJ_MEM != 0)
  239. #if (OS_MSGQUEUE_NUM == 0)
  240. #error "Invalid number of Message Queue objects!"
  241. #endif
  242. // Message Queue Control Blocks
  243. static osRtxMessageQueue_t os_mq_cb[OS_MSGQUEUE_NUM] \
  244. __attribute__((section(".bss.os.msgqueue.cb")));
  245. // Memory Pool for Message Queue Control Blocks
  246. static osRtxMpInfo_t os_mpi_mq \
  247. __attribute__((section(".data.os.msgqueue.mpi"))) =
  248. { (uint32_t)OS_MSGQUEUE_NUM, 0U, (uint32_t)osRtxMessageQueueCbSize, &os_mq_cb[0], NULL, NULL };
  249. // Memory Pool for Message Queue Data Storage
  250. #if (OS_MSGQUEUE_DATA_SIZE != 0)
  251. #if ((OS_MSGQUEUE_DATA_SIZE % 8) != 0)
  252. #error "Invalid Data Memory size for Message Queues!"
  253. #endif
  254. static uint64_t os_mq_data[2 + OS_MSGQUEUE_NUM + (OS_MSGQUEUE_DATA_SIZE/8)] \
  255. __attribute__((section(".bss.os.msgqueue.mem")));
  256. #endif
  257. #endif // (OS_MSGQUEUE_OBJ_MEM != 0)
  258. // OS Configuration
  259. // ================
  260. const osRtxConfig_t osRtxConfig \
  261. __USED \
  262. __attribute__((section(".rodata"))) =
  263. {
  264. //lint -e{835} "Zero argument to operator"
  265. 0U // Flags
  266. #if (OS_PRIVILEGE_MODE != 0)
  267. | osRtxConfigPrivilegedMode
  268. #endif
  269. #if (OS_STACK_CHECK != 0)
  270. | osRtxConfigStackCheck
  271. #endif
  272. #if (OS_STACK_WATERMARK != 0)
  273. | osRtxConfigStackWatermark
  274. #endif
  275. ,
  276. (uint32_t)OS_TICK_FREQ,
  277. #if (OS_ROBIN_ENABLE != 0)
  278. (uint32_t)OS_ROBIN_TIMEOUT,
  279. #else
  280. 0U,
  281. #endif
  282. { &os_isr_queue[0], (uint16_t)(sizeof(os_isr_queue)/sizeof(void *)), 0U },
  283. {
  284. // Memory Pools (Variable Block Size)
  285. #if ((OS_THREAD_OBJ_MEM != 0) && (OS_THREAD_USER_STACK_SIZE != 0))
  286. &os_thread_stack[0], sizeof(os_thread_stack),
  287. #else
  288. NULL, 0U,
  289. #endif
  290. #if ((OS_MEMPOOL_OBJ_MEM != 0) && (OS_MEMPOOL_DATA_SIZE != 0))
  291. &os_mp_data[0], sizeof(os_mp_data),
  292. #else
  293. NULL, 0U,
  294. #endif
  295. #if ((OS_MSGQUEUE_OBJ_MEM != 0) && (OS_MSGQUEUE_DATA_SIZE != 0))
  296. &os_mq_data[0], sizeof(os_mq_data),
  297. #else
  298. NULL, 0U,
  299. #endif
  300. #if (OS_DYNAMIC_MEM_SIZE != 0)
  301. &os_mem[0], (uint32_t)OS_DYNAMIC_MEM_SIZE,
  302. #else
  303. NULL, 0U
  304. #endif
  305. },
  306. {
  307. // Memory Pools (Fixed Block Size)
  308. #if (OS_THREAD_OBJ_MEM != 0)
  309. #if (OS_THREAD_DEF_STACK_NUM != 0)
  310. &os_mpi_def_stack,
  311. #else
  312. NULL,
  313. #endif
  314. &os_mpi_thread,
  315. #else
  316. NULL,
  317. NULL,
  318. #endif
  319. #if (OS_TIMER_OBJ_MEM != 0)
  320. &os_mpi_timer,
  321. #else
  322. NULL,
  323. #endif
  324. #if (OS_EVFLAGS_OBJ_MEM != 0)
  325. &os_mpi_ef,
  326. #else
  327. NULL,
  328. #endif
  329. #if (OS_MUTEX_OBJ_MEM != 0)
  330. &os_mpi_mutex,
  331. #else
  332. NULL,
  333. #endif
  334. #if (OS_SEMAPHORE_OBJ_MEM != 0)
  335. &os_mpi_semaphore,
  336. #else
  337. NULL,
  338. #endif
  339. #if (OS_MEMPOOL_OBJ_MEM != 0)
  340. &os_mpi_mp,
  341. #else
  342. NULL,
  343. #endif
  344. #if (OS_MSGQUEUE_OBJ_MEM != 0)
  345. &os_mpi_mq,
  346. #else
  347. NULL,
  348. #endif
  349. },
  350. (uint32_t)OS_STACK_SIZE,
  351. &os_idle_thread_attr,
  352. #if ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0))
  353. &os_timer_thread_attr,
  354. &os_timer_mq_attr,
  355. (uint32_t)OS_TIMER_CB_QUEUE
  356. #else
  357. NULL,
  358. NULL,
  359. 0U
  360. #endif
  361. };
  362. // Non weak reference to library irq module
  363. //lint -esym(526,irqRtxLib) "Defined by Exception handlers"
  364. //lint -esym(714,irqRtxLibRef) "Non weak reference"
  365. //lint -esym(765,irqRtxLibRef) "Global scope"
  366. extern uint8_t irqRtxLib;
  367. extern const uint8_t *irqRtxLibRef;
  368. const uint8_t *irqRtxLibRef = &irqRtxLib;
  369. // Default User SVC Table
  370. //lint -esym(714,osRtxUserSVC) "Referenced by Exception handlers"
  371. //lint -esym(765,osRtxUserSVC) "Global scope"
  372. //lint -e{9067} "extern array declared without size"
  373. extern void * const osRtxUserSVC[];
  374. __WEAK void * const osRtxUserSVC[1] = { (void *)0 };
  375. // OS Sections
  376. // ===========
  377. #if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
  378. //lint -e{19} "Linker symbols"
  379. __asm (
  380. ".weakref __os_thread_cb_start__, .bss.os.thread.cb$$Base\n\t"
  381. ".weakref __os_thread_cb_end__, .bss.os.thread.cb$$Limit\n\t"
  382. ".weakref __os_timer_cb_start__, .bss.os.timer.cb$$Base\n\t"
  383. ".weakref __os_timer_cb_end__, .bss.os.timer.cb$$Limit\n\t"
  384. ".weakref __os_evflags_cb_start__, .bss.os.evflags.cb$$Base\n\t"
  385. ".weakref __os_evflags_cb_end__, .bss.os.evflags.cb$$Limit\n\t"
  386. ".weakref __os_mutex_cb_start__, .bss.os.mutex.cb$$Base\n\t"
  387. ".weakref __os_mutex_cb_end__, .bss.os.mutex.cb$$Limit\n\t"
  388. ".weakref __os_semaphore_cb_start__, .bss.os.semaphore.cb$$Base\n\t"
  389. ".weakref __os_semaphore_cb_end__, .bss.os.semaphore.cb$$Limit\n\t"
  390. ".weakref __os_mempool_cb_start__, .bss.os.mempool.cb$$Base\n\t"
  391. ".weakref __os_mempool_cb_end__, .bss.os.mempool.cb$$Limit\n\t"
  392. ".weakref __os_msgqueue_cb_start__, .bss.os.msgqueue.cb$$Base\n\t"
  393. ".weakref __os_msgqueue_cb_end__, .bss.os.msgqueue.cb$$Limit\n\t"
  394. );
  395. #endif
  396. #if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || \
  397. (defined(__GNUC__) && !defined(__CC_ARM))
  398. extern __attribute__((weak)) uint32_t __os_thread_cb_start__; //lint -esym(526,__os_thread_cb_start__)
  399. extern __attribute__((weak)) uint32_t __os_thread_cb_end__; //lint -esym(526,__os_thread_cb_end__)
  400. extern __attribute__((weak)) uint32_t __os_timer_cb_start__; //lint -esym(526,__os_timer_cb_start__)
  401. extern __attribute__((weak)) uint32_t __os_timer_cb_end__; //lint -esym(526,__os_timer_cb_end__)
  402. extern __attribute__((weak)) uint32_t __os_evflags_cb_start__; //lint -esym(526,__os_evflags_cb_start__)
  403. extern __attribute__((weak)) uint32_t __os_evflags_cb_end__; //lint -esym(526,__os_evflags_cb_end__)
  404. extern __attribute__((weak)) uint32_t __os_mutex_cb_start__; //lint -esym(526,__os_mutex_cb_start__)
  405. extern __attribute__((weak)) uint32_t __os_mutex_cb_end__; //lint -esym(526,__os_mutex_cb_end__)
  406. extern __attribute__((weak)) uint32_t __os_semaphore_cb_start__; //lint -esym(526,__os_semaphore_cb_start__)
  407. extern __attribute__((weak)) uint32_t __os_semaphore_cb_end__; //lint -esym(526,__os_semaphore_cb_end__)
  408. extern __attribute__((weak)) uint32_t __os_mempool_cb_start__; //lint -esym(526,__os_mempool_cb_start__)
  409. extern __attribute__((weak)) uint32_t __os_mempool_cb_end__; //lint -esym(526,__os_mempool_cb_end__)
  410. extern __attribute__((weak)) uint32_t __os_msgqueue_cb_start__; //lint -esym(526,__os_msgqueue_cb_start__)
  411. extern __attribute__((weak)) uint32_t __os_msgqueue_cb_end__; //lint -esym(526,__os_msgqueue_cb_end__)
  412. //lint -e{19} "Global symbol"
  413. __asm (".global os_cb_sections");
  414. //lint -e{9067} "extern array declared without size"
  415. extern const uint32_t os_cb_sections[];
  416. //lint -esym(714,os_cb_sections) "Referenced by debugger"
  417. //lint -esym(765,os_cb_sections) "Global scope"
  418. //lint -e{923} -e{9078} "cast from pointer to unsigned int"
  419. const uint32_t os_cb_sections[] \
  420. __attribute__((section(".rodata"))) =
  421. {
  422. (uint32_t)&__os_thread_cb_start__,
  423. (uint32_t)&__os_thread_cb_end__,
  424. (uint32_t)&__os_timer_cb_start__,
  425. (uint32_t)&__os_timer_cb_end__,
  426. (uint32_t)&__os_evflags_cb_start__,
  427. (uint32_t)&__os_evflags_cb_end__,
  428. (uint32_t)&__os_mutex_cb_start__,
  429. (uint32_t)&__os_mutex_cb_end__,
  430. (uint32_t)&__os_semaphore_cb_start__,
  431. (uint32_t)&__os_semaphore_cb_end__,
  432. (uint32_t)&__os_mempool_cb_start__,
  433. (uint32_t)&__os_mempool_cb_end__,
  434. (uint32_t)&__os_msgqueue_cb_start__,
  435. (uint32_t)&__os_msgqueue_cb_end__
  436. };
  437. #endif
  438. // OS Initialization
  439. // =================
  440. #if defined(__CC_ARM) || \
  441. (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
  442. #ifndef __MICROLIB
  443. //lint -esym(714,_platform_post_stackheap_init) "Referenced by C library"
  444. //lint -esym(765,_platform_post_stackheap_init) "Global scope"
  445. extern void _platform_post_stackheap_init (void);
  446. __WEAK void _platform_post_stackheap_init (void) {
  447. (void)osKernelInitialize();
  448. }
  449. #endif
  450. #elif defined(__GNUC__)
  451. extern void software_init_hook (void);
  452. __WEAK void software_init_hook (void) {
  453. (void)osKernelInitialize();
  454. }
  455. #endif
  456. // C/C++ Standard Library Multithreading Interface
  457. // ===============================================
  458. #if ( !defined(RTX_NO_MULTITHREAD_CLIB) && \
  459. ( defined(__CC_ARM) || \
  460. (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \
  461. !defined(__MICROLIB))
  462. #define LIBSPACE_SIZE 96
  463. //lint -esym(714,__user_perthread_libspace,_mutex_*) "Referenced by C library"
  464. //lint -esym(765,__user_perthread_libspace,_mutex_*) "Global scope"
  465. //lint -esym(9003, os_libspace*) "variables 'os_libspace*' defined at module scope"
  466. // Memory for libspace
  467. static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/4] \
  468. __attribute__((section(".bss.os")));
  469. // Thread IDs for libspace
  470. static osThreadId_t os_libspace_id[OS_THREAD_LIBSPACE_NUM] \
  471. __attribute__((section(".bss.os")));
  472. // Check if Kernel has been started
  473. static uint32_t os_kernel_is_active (void) {
  474. static uint8_t os_kernel_active = 0U;
  475. if (os_kernel_active == 0U) {
  476. if (osKernelGetState() > osKernelReady) {
  477. os_kernel_active = 1U;
  478. }
  479. }
  480. return (uint32_t)os_kernel_active;
  481. }
  482. // Provide libspace for current thread
  483. void *__user_perthread_libspace (void);
  484. void *__user_perthread_libspace (void) {
  485. osThreadId_t id;
  486. uint32_t n;
  487. if (os_kernel_is_active() != 0U) {
  488. id = osThreadGetId();
  489. for (n = 0U; n < (uint32_t)OS_THREAD_LIBSPACE_NUM; n++) {
  490. if (os_libspace_id[n] == NULL) {
  491. os_libspace_id[n] = id;
  492. }
  493. if (os_libspace_id[n] == id) {
  494. break;
  495. }
  496. }
  497. if (n == (uint32_t)OS_THREAD_LIBSPACE_NUM) {
  498. (void)osRtxErrorNotify(osRtxErrorClibSpace, id);
  499. }
  500. } else {
  501. n = OS_THREAD_LIBSPACE_NUM;
  502. }
  503. //lint -e{9087} "cast between pointers to different object types"
  504. return (void *)&os_libspace[n][0];
  505. }
  506. // Mutex identifier
  507. typedef void *mutex;
  508. //lint -save "Function prototypes defined in C library"
  509. //lint -e970 "Use of 'int' outside of a typedef"
  510. //lint -e818 "Pointer 'm' could be declared as pointing to const"
  511. // Initialize mutex
  512. __USED
  513. int _mutex_initialize(mutex *m);
  514. int _mutex_initialize(mutex *m) {
  515. int result;
  516. *m = osMutexNew(NULL);
  517. if (*m != NULL) {
  518. result = 1;
  519. } else {
  520. result = 0;
  521. (void)osRtxErrorNotify(osRtxErrorClibMutex, m);
  522. }
  523. return result;
  524. }
  525. // Acquire mutex
  526. __USED
  527. void _mutex_acquire(mutex *m);
  528. void _mutex_acquire(mutex *m) {
  529. if (os_kernel_is_active() != 0U) {
  530. (void)osMutexAcquire(*m, osWaitForever);
  531. }
  532. }
  533. // Release mutex
  534. __USED
  535. void _mutex_release(mutex *m);
  536. void _mutex_release(mutex *m) {
  537. if (os_kernel_is_active() != 0U) {
  538. (void)osMutexRelease(*m);
  539. }
  540. }
  541. // Free mutex
  542. __USED
  543. void _mutex_free(mutex *m);
  544. void _mutex_free(mutex *m) {
  545. (void)osMutexDelete(*m);
  546. }
  547. //lint -restore
  548. #endif