RTX_CM_lib.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /*----------------------------------------------------------------------------
  2. * CMSIS-RTOS - RTX
  3. *----------------------------------------------------------------------------
  4. * Name: RTX_CM_LIB.H
  5. * Purpose: RTX Kernel System Configuration
  6. * Rev.: V4.82
  7. *----------------------------------------------------------------------------
  8. *
  9. * Copyright (c) 1999-2009 KEIL, 2009-2019 ARM Germany GmbH. All rights reserved.
  10. *
  11. * SPDX-License-Identifier: Apache-2.0
  12. *
  13. * Licensed under the Apache License, Version 2.0 (the License); you may
  14. * not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at
  16. *
  17. * www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  21. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. *---------------------------------------------------------------------------*/
  25. #if defined (__CC_ARM)
  26. #pragma O3
  27. #define __USED __attribute__((used))
  28. #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
  29. #define __USED __attribute__((used))
  30. #elif defined (__GNUC__)
  31. #pragma GCC optimize ("O3")
  32. #define __USED __attribute__((used))
  33. #elif defined (__ICCARM__)
  34. #define __USED __root
  35. #endif
  36. /*----------------------------------------------------------------------------
  37. * Definitions
  38. *---------------------------------------------------------------------------*/
  39. #define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3]
  40. #define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
  41. #define OS_TCB_SIZE 52
  42. #define OS_TMR_SIZE 8
  43. #if (( defined(__CC_ARM) || \
  44. (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \
  45. !defined(__MICROLIB))
  46. typedef void *OS_ID;
  47. typedef uint32_t OS_TID;
  48. typedef uint32_t OS_MUT[4];
  49. typedef uint32_t OS_RESULT;
  50. #define runtask_id() rt_tsk_self()
  51. #define mutex_init(m) rt_mut_init(m)
  52. #define mutex_wait(m) os_mut_wait(m,0xFFFFU)
  53. #define mutex_rel(m) os_mut_release(m)
  54. extern uint8_t os_running;
  55. extern OS_TID rt_tsk_self (void);
  56. extern void rt_mut_init (OS_ID mutex);
  57. extern OS_RESULT rt_mut_release (OS_ID mutex);
  58. extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout);
  59. #if defined(__CC_ARM)
  60. #define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout)
  61. #define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex)
  62. OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0);
  63. OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0);
  64. #else
  65. __attribute__((always_inline))
  66. static __inline OS_RESULT os_mut_release (OS_ID mutex) {
  67. register uint32_t __rf __asm("r12") = (uint32_t)rt_mut_release;
  68. register uint32_t __r0 __asm("r0") = (uint32_t)mutex;
  69. __asm volatile \
  70. ( \
  71. "svc 0" \
  72. : "=r" (__r0) \
  73. : "r" (__rf), "r" (__r0) \
  74. : "r1", "r2" \
  75. );
  76. return (OS_RESULT)__r0;
  77. }
  78. __attribute__((always_inline))
  79. static __inline OS_RESULT os_mut_wait (OS_ID mutex, uint16_t timeout) {
  80. register uint32_t __rf __asm("r12") = (uint32_t)rt_mut_wait;
  81. register uint32_t __r0 __asm("r0") = (uint32_t)mutex;
  82. register uint32_t __r1 __asm("r1") = (uint32_t)timeout;
  83. __asm volatile \
  84. ( \
  85. "svc 0" \
  86. : "=r" (__r0) \
  87. : "r" (__rf), "r" (__r0), "r" (__r1) \
  88. : "r2" \
  89. );
  90. return (OS_RESULT)__r0;
  91. }
  92. #endif
  93. #endif
  94. /*----------------------------------------------------------------------------
  95. * Global Variables
  96. *---------------------------------------------------------------------------*/
  97. #if (OS_TASKCNT == 0)
  98. #error "Invalid number of concurrent running threads!"
  99. #endif
  100. #if (OS_PRIVCNT >= OS_TASKCNT)
  101. #error "Too many threads with user-provided stack size!"
  102. #endif
  103. #if (OS_TIMERS != 0)
  104. #define OS_TASK_CNT (OS_TASKCNT + 1)
  105. #define OS_PRIV_CNT (OS_PRIVCNT + 2)
  106. #define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ))
  107. #else
  108. #define OS_TASK_CNT OS_TASKCNT
  109. #define OS_PRIV_CNT (OS_PRIVCNT + 1)
  110. #define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE))
  111. #endif
  112. #ifndef OS_STKINIT
  113. #define OS_STKINIT 0
  114. #endif
  115. extern uint16_t const os_maxtaskrun;
  116. extern uint32_t const os_stackinfo;
  117. extern uint32_t const os_rrobin;
  118. extern uint32_t const os_trv;
  119. extern uint8_t const os_flags;
  120. uint16_t const os_maxtaskrun = OS_TASK_CNT;
  121. uint32_t const os_stackinfo = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_PRIV_CNT<<16) | (OS_STKSIZE*4);
  122. uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT;
  123. uint32_t const os_tickfreq = OS_CLOCK;
  124. uint16_t const os_tickus_i = OS_CLOCK/1000000;
  125. uint16_t const os_tickus_f = (((uint64_t)(OS_CLOCK-1000000*(OS_CLOCK/1000000)))<<16)/1000000;
  126. uint32_t const os_trv = OS_TRV;
  127. uint8_t const os_flags = OS_RUNPRIV;
  128. /* Export following defines to uVision debugger. */
  129. extern uint32_t const CMSIS_RTOS_API_Version;
  130. __USED uint32_t const CMSIS_RTOS_API_Version = osCMSIS;
  131. extern uint32_t const CMSIS_RTOS_RTX_Version;
  132. __USED uint32_t const CMSIS_RTOS_RTX_Version = osCMSIS_RTX;
  133. extern uint32_t const os_clockrate;
  134. __USED uint32_t const os_clockrate = OS_TICK;
  135. extern uint32_t const os_timernum;
  136. __USED uint32_t const os_timernum = 0U;
  137. /* Memory pool for TCB allocation */
  138. extern
  139. uint32_t mp_tcb[];
  140. _declare_box (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT);
  141. extern
  142. uint16_t const mp_tcb_size;
  143. uint16_t const mp_tcb_size = sizeof(mp_tcb);
  144. /* Memory pool for System stack allocation (+os_idle_demon). */
  145. extern
  146. uint64_t mp_stk[];
  147. _declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1);
  148. extern
  149. uint32_t const mp_stk_size;
  150. uint32_t const mp_stk_size = sizeof(mp_stk);
  151. /* Memory pool for user specified stack allocation (+main, +timer) */
  152. extern
  153. uint64_t os_stack_mem[];
  154. uint64_t os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)];
  155. extern
  156. uint32_t const os_stack_sz;
  157. uint32_t const os_stack_sz = sizeof(os_stack_mem);
  158. #ifndef OS_FIFOSZ
  159. #define OS_FIFOSZ 16
  160. #endif
  161. /* Fifo Queue buffer for ISR requests.*/
  162. extern
  163. uint32_t os_fifo[];
  164. uint32_t os_fifo[OS_FIFOSZ*2+1];
  165. extern
  166. uint8_t const os_fifo_size;
  167. uint8_t const os_fifo_size = OS_FIFOSZ;
  168. /* An array of Active task pointers. */
  169. extern
  170. void *os_active_TCB[];
  171. void *os_active_TCB[OS_TASK_CNT];
  172. /* User Timers Resources */
  173. #if (OS_TIMERS != 0)
  174. extern void osTimerThread (void const *argument);
  175. extern const osThreadDef_t os_thread_def_osTimerThread;
  176. osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ);
  177. extern
  178. osThreadId osThreadId_osTimerThread;
  179. osThreadId osThreadId_osTimerThread;
  180. extern uint32_t os_messageQ_q_osTimerMessageQ[];
  181. extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
  182. osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *);
  183. extern
  184. osMessageQId osMessageQId_osTimerMessageQ;
  185. osMessageQId osMessageQId_osTimerMessageQ;
  186. #else
  187. extern
  188. const osThreadDef_t os_thread_def_osTimerThread;
  189. const osThreadDef_t os_thread_def_osTimerThread = { NULL, osPriorityNormal, 0U, 0U };
  190. extern
  191. osThreadId osThreadId_osTimerThread;
  192. osThreadId osThreadId_osTimerThread;
  193. extern uint32_t os_messageQ_q_osTimerMessageQ[];
  194. extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
  195. osMessageQDef(osTimerMessageQ, 0U, void *);
  196. extern
  197. osMessageQId osMessageQId_osTimerMessageQ;
  198. osMessageQId osMessageQId_osTimerMessageQ;
  199. #endif
  200. /* Legacy RTX User Timers not used */
  201. extern
  202. uint32_t os_tmr;
  203. uint32_t os_tmr = 0U;
  204. extern
  205. uint32_t const *m_tmr;
  206. uint32_t const *m_tmr = NULL;
  207. extern
  208. uint16_t const mp_tmr_size;
  209. uint16_t const mp_tmr_size = 0U;
  210. #if (( defined(__CC_ARM) || \
  211. (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \
  212. !defined(__MICROLIB))
  213. /* A memory space for arm standard library. */
  214. static uint32_t std_libspace[OS_TASK_CNT][96/4];
  215. static OS_MUT std_libmutex[OS_MUTEXCNT];
  216. static uint32_t nr_mutex;
  217. extern void *__libspace_start;
  218. #endif
  219. /*----------------------------------------------------------------------------
  220. * RTX Optimizations (empty functions)
  221. *---------------------------------------------------------------------------*/
  222. #if OS_ROBIN == 0
  223. extern
  224. void rt_init_robin (void);
  225. void rt_init_robin (void) {;}
  226. extern
  227. void rt_chk_robin (void);
  228. void rt_chk_robin (void) {;}
  229. #endif
  230. #if OS_STKCHECK == 0
  231. extern
  232. void rt_stk_check (void);
  233. void rt_stk_check (void) {;}
  234. #endif
  235. /*----------------------------------------------------------------------------
  236. * Standard Library multithreading interface
  237. *---------------------------------------------------------------------------*/
  238. #if (( defined(__CC_ARM) || \
  239. (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \
  240. !defined(__MICROLIB))
  241. /*--------------------------- __user_perthread_libspace ---------------------*/
  242. void *__user_perthread_libspace (void);
  243. void *__user_perthread_libspace (void) {
  244. /* Provide a separate libspace for each task. */
  245. uint32_t idx;
  246. idx = (os_running != 0U) ? runtask_id () : 0U;
  247. if (idx == 0U) {
  248. /* RTX not running yet. */
  249. return (&__libspace_start);
  250. }
  251. return ((void *)&std_libspace[idx-1]);
  252. }
  253. /*--------------------------- _mutex_initialize -----------------------------*/
  254. int _mutex_initialize (OS_ID *mutex);
  255. int _mutex_initialize (OS_ID *mutex) {
  256. /* Allocate and initialize a system mutex. */
  257. if (nr_mutex >= OS_MUTEXCNT) {
  258. /* If you are here, you need to increase the number OS_MUTEXCNT. */
  259. for (;;);
  260. }
  261. *mutex = &std_libmutex[nr_mutex++];
  262. mutex_init (*mutex);
  263. return (1);
  264. }
  265. /*--------------------------- _mutex_acquire --------------------------------*/
  266. __attribute__((used))
  267. void _mutex_acquire (OS_ID *mutex);
  268. void _mutex_acquire (OS_ID *mutex) {
  269. /* Acquire a system mutex, lock stdlib resources. */
  270. if (os_running) {
  271. /* RTX running, acquire a mutex. */
  272. mutex_wait (*mutex);
  273. }
  274. }
  275. /*--------------------------- _mutex_release --------------------------------*/
  276. __attribute__((used))
  277. void _mutex_release (OS_ID *mutex);
  278. void _mutex_release (OS_ID *mutex) {
  279. /* Release a system mutex, unlock stdlib resources. */
  280. if (os_running) {
  281. /* RTX running, release a mutex. */
  282. mutex_rel (*mutex);
  283. }
  284. }
  285. #endif
  286. /*----------------------------------------------------------------------------
  287. * ARMCC6 Wrappers for ARMCC5 Binary
  288. *---------------------------------------------------------------------------*/
  289. #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
  290. typedef uint32_t __attribute__((vector_size(8))) vect64_t;
  291. #undef osSignalWait
  292. __attribute__((pcs("aapcs")))
  293. vect64_t osSignalWait (int32_t signals, uint32_t millisec);
  294. osEvent __osSignalWait (int32_t signals, uint32_t millisec) {
  295. vect64_t v;
  296. osEvent e;
  297. v = osSignalWait(signals, millisec);
  298. e.status = v[0];
  299. e.value.v = v[1];
  300. return e;
  301. }
  302. #undef osMessageGet
  303. __attribute__((pcs("aapcs")))
  304. vect64_t osMessageGet (osMessageQId queue_id, uint32_t millisec);
  305. osEvent __osMessageGet (osMessageQId queue_id, uint32_t millisec) {
  306. vect64_t v;
  307. osEvent e;
  308. v = osMessageGet(queue_id, millisec);
  309. e.status = v[0];
  310. e.value.v = v[1];
  311. return e;
  312. }
  313. #undef osMailGet
  314. __attribute__((pcs("aapcs")))
  315. vect64_t osMailGet (osMailQId queue_id, uint32_t millisec);
  316. osEvent __osMailGet (osMailQId queue_id, uint32_t millisec) {
  317. vect64_t v;
  318. osEvent e;
  319. v = osMailGet(queue_id, millisec);
  320. e.status = v[0];
  321. e.value.v = v[1];
  322. return e;
  323. }
  324. #endif
  325. /*----------------------------------------------------------------------------
  326. * RTX Startup
  327. *---------------------------------------------------------------------------*/
  328. /* Main Thread definition */
  329. extern int main (void);
  330. extern
  331. const osThreadDef_t os_thread_def_main;
  332. const osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1U, 4*OS_MAINSTKSIZE };
  333. #if defined (__CC_ARM)
  334. #ifdef __MICROLIB
  335. __attribute__((section(".ARM.Collect$$$$000000FF")))
  336. void _main_init (void);
  337. void _main_init (void) {
  338. osKernelInitialize();
  339. osThreadCreate(&os_thread_def_main, NULL);
  340. osKernelStart();
  341. for (;;);
  342. }
  343. #else
  344. __asm void _platform_post_lib_init (void) {
  345. IMPORT os_thread_def_main
  346. IMPORT osKernelInitialize
  347. IMPORT osKernelStart
  348. IMPORT osThreadCreate
  349. IMPORT exit
  350. ADD SP,#0x10
  351. BL osKernelInitialize
  352. LDR R0,=os_thread_def_main
  353. MOVS R1,#0
  354. BL osThreadCreate
  355. BL osKernelStart
  356. BL exit
  357. ALIGN
  358. }
  359. #endif
  360. #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
  361. #ifdef __MICROLIB
  362. __attribute__((noreturn, section(".ARM.Collect$$$$000000FF")))
  363. void _main_init (void);
  364. void _main_init (void) {
  365. #else
  366. __asm(" .global __ARM_use_no_argv\n");
  367. __attribute__((noreturn))
  368. void _platform_post_lib_init (void);
  369. void _platform_post_lib_init (void) {
  370. #endif
  371. osKernelInitialize();
  372. osThreadCreate(&os_thread_def_main, NULL);
  373. osKernelStart();
  374. for (;;);
  375. }
  376. #elif defined (__GNUC__)
  377. #ifdef __CS3__
  378. /* CS3 start_c routine.
  379. *
  380. * Copyright (c) 2006, 2007 CodeSourcery Inc
  381. *
  382. * The authors hereby grant permission to use, copy, modify, distribute,
  383. * and license this software and its documentation for any purpose, provided
  384. * that existing copyright notices are retained in all copies and that this
  385. * notice is included verbatim in any distributions. No written agreement,
  386. * license, or royalty fee is required for any of the authorized uses.
  387. * Modifications to this software may be copyrighted by their authors
  388. * and need not follow the licensing terms described here, provided that
  389. * the new terms are clearly indicated on the first page of each file where
  390. * they apply.
  391. */
  392. #include "cs3.h"
  393. extern void __libc_init_array (void);
  394. __attribute ((noreturn)) void __cs3_start_c (void){
  395. unsigned regions = __cs3_region_num;
  396. const struct __cs3_region *rptr = __cs3_regions;
  397. /* Initialize memory */
  398. for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) {
  399. long long *src = (long long *)rptr->init;
  400. long long *dst = (long long *)rptr->data;
  401. unsigned limit = rptr->init_size;
  402. unsigned count;
  403. if (src != dst)
  404. for (count = 0; count != limit; count += sizeof (long long))
  405. *dst++ = *src++;
  406. else
  407. dst = (long long *)((char *)dst + limit);
  408. limit = rptr->zero_size;
  409. for (count = 0; count != limit; count += sizeof (long long))
  410. *dst++ = 0;
  411. }
  412. /* Run initializers. */
  413. __libc_init_array ();
  414. osKernelInitialize();
  415. osThreadCreate(&os_thread_def_main, NULL);
  416. osKernelStart();
  417. for (;;);
  418. }
  419. #else
  420. __attribute__((naked)) void software_init_hook (void) {
  421. __asm (
  422. ".syntax unified\n"
  423. ".thumb\n"
  424. "movs r0,#0\n"
  425. "movs r1,#0\n"
  426. "mov r4,r0\n"
  427. "mov r5,r1\n"
  428. "ldr r0,= __libc_fini_array\n"
  429. "bl atexit\n"
  430. "bl __libc_init_array\n"
  431. "mov r0,r4\n"
  432. "mov r1,r5\n"
  433. "bl osKernelInitialize\n"
  434. "ldr r0,=os_thread_def_main\n"
  435. "movs r1,#0\n"
  436. "bl osThreadCreate\n"
  437. "bl osKernelStart\n"
  438. "bl exit\n"
  439. );
  440. }
  441. #endif
  442. #elif defined (__ICCARM__)
  443. extern int __low_level_init(void);
  444. extern void __iar_data_init3(void);
  445. extern void exit(int arg);
  446. __noreturn __stackless void __cmain(void) {
  447. int a;
  448. if (__low_level_init() != 0) {
  449. __iar_data_init3();
  450. }
  451. osKernelInitialize();
  452. osThreadCreate(&os_thread_def_main, NULL);
  453. a = osKernelStart();
  454. exit(a);
  455. }
  456. #endif
  457. /*----------------------------------------------------------------------------
  458. * end of file
  459. *---------------------------------------------------------------------------*/