rtx_kernel.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. /*
  2. * Copyright (c) 2013-2019 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: Kernel functions
  22. *
  23. * -----------------------------------------------------------------------------
  24. */
  25. #include "rtx_lib.h"
  26. // OS Runtime Information
  27. osRtxInfo_t osRtxInfo __attribute__((section(".data.os"))) =
  28. //lint -e{785} "Initialize only OS ID, OS Version and Kernel State"
  29. { .os_id = osRtxKernelId, .version = osRtxVersionKernel, .kernel.state = osRtxKernelInactive };
  30. // ==== Helper functions ====
  31. /// Block Kernel (disable: thread switching, time tick, post ISR processing).
  32. static void KernelBlock (void) {
  33. OS_Tick_Disable();
  34. osRtxInfo.kernel.blocked = 1U;
  35. __DSB();
  36. if (GetPendSV() != 0U) {
  37. ClrPendSV();
  38. osRtxInfo.kernel.pendSV = 1U;
  39. }
  40. }
  41. /// Unblock Kernel
  42. static void KernelUnblock (void) {
  43. osRtxInfo.kernel.blocked = 0U;
  44. __DSB();
  45. if (osRtxInfo.kernel.pendSV != 0U) {
  46. osRtxInfo.kernel.pendSV = 0U;
  47. SetPendSV();
  48. }
  49. OS_Tick_Enable();
  50. }
  51. // ==== Service Calls ====
  52. /// Initialize the RTOS Kernel.
  53. /// \note API identical to osKernelInitialize
  54. static osStatus_t svcRtxKernelInitialize (void) {
  55. if (osRtxInfo.kernel.state == osRtxKernelReady) {
  56. EvrRtxKernelInitialized();
  57. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  58. return osOK;
  59. }
  60. if (osRtxInfo.kernel.state != osRtxKernelInactive) {
  61. EvrRtxKernelError((int32_t)osError);
  62. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  63. return osError;
  64. }
  65. #if (DOMAIN_NS == 1)
  66. // Initialize Secure Process Stack
  67. if (TZ_InitContextSystem_S() == 0U) {
  68. EvrRtxKernelError(osRtxErrorTZ_InitContext_S);
  69. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  70. return osError;
  71. }
  72. #endif
  73. // Initialize osRtxInfo
  74. memset(&osRtxInfo.kernel, 0, sizeof(osRtxInfo) - offsetof(osRtxInfo_t, kernel));
  75. osRtxInfo.isr_queue.data = osRtxConfig.isr_queue.data;
  76. osRtxInfo.isr_queue.max = osRtxConfig.isr_queue.max;
  77. osRtxInfo.thread.robin.timeout = osRtxConfig.robin_timeout;
  78. // Initialize Memory Pools (Variable Block Size)
  79. if (osRtxMemoryInit(osRtxConfig.mem.common_addr, osRtxConfig.mem.common_size) != 0U) {
  80. osRtxInfo.mem.common = osRtxConfig.mem.common_addr;
  81. }
  82. if (osRtxMemoryInit(osRtxConfig.mem.stack_addr, osRtxConfig.mem.stack_size) != 0U) {
  83. osRtxInfo.mem.stack = osRtxConfig.mem.stack_addr;
  84. } else {
  85. osRtxInfo.mem.stack = osRtxInfo.mem.common;
  86. }
  87. if (osRtxMemoryInit(osRtxConfig.mem.mp_data_addr, osRtxConfig.mem.mp_data_size) != 0U) {
  88. osRtxInfo.mem.mp_data = osRtxConfig.mem.mp_data_addr;
  89. } else {
  90. osRtxInfo.mem.mp_data = osRtxInfo.mem.common;
  91. }
  92. if (osRtxMemoryInit(osRtxConfig.mem.mq_data_addr, osRtxConfig.mem.mq_data_size) != 0U) {
  93. osRtxInfo.mem.mq_data = osRtxConfig.mem.mq_data_addr;
  94. } else {
  95. osRtxInfo.mem.mq_data = osRtxInfo.mem.common;
  96. }
  97. // Initialize Memory Pools (Fixed Block Size)
  98. if (osRtxConfig.mpi.stack != NULL) {
  99. (void)osRtxMemoryPoolInit(osRtxConfig.mpi.stack,
  100. osRtxConfig.mpi.stack->max_blocks,
  101. osRtxConfig.mpi.stack->block_size,
  102. osRtxConfig.mpi.stack->block_base);
  103. osRtxInfo.mpi.stack = osRtxConfig.mpi.stack;
  104. }
  105. if (osRtxConfig.mpi.thread != NULL) {
  106. (void)osRtxMemoryPoolInit(osRtxConfig.mpi.thread,
  107. osRtxConfig.mpi.thread->max_blocks,
  108. osRtxConfig.mpi.thread->block_size,
  109. osRtxConfig.mpi.thread->block_base);
  110. osRtxInfo.mpi.thread = osRtxConfig.mpi.thread;
  111. }
  112. if (osRtxConfig.mpi.timer != NULL) {
  113. (void)osRtxMemoryPoolInit(osRtxConfig.mpi.timer,
  114. osRtxConfig.mpi.timer->max_blocks,
  115. osRtxConfig.mpi.timer->block_size,
  116. osRtxConfig.mpi.timer->block_base);
  117. osRtxInfo.mpi.timer = osRtxConfig.mpi.timer;
  118. }
  119. if (osRtxConfig.mpi.event_flags != NULL) {
  120. (void)osRtxMemoryPoolInit(osRtxConfig.mpi.event_flags,
  121. osRtxConfig.mpi.event_flags->max_blocks,
  122. osRtxConfig.mpi.event_flags->block_size,
  123. osRtxConfig.mpi.event_flags->block_base);
  124. osRtxInfo.mpi.event_flags = osRtxConfig.mpi.event_flags;
  125. }
  126. if (osRtxConfig.mpi.mutex != NULL) {
  127. (void)osRtxMemoryPoolInit(osRtxConfig.mpi.mutex,
  128. osRtxConfig.mpi.mutex->max_blocks,
  129. osRtxConfig.mpi.mutex->block_size,
  130. osRtxConfig.mpi.mutex->block_base);
  131. osRtxInfo.mpi.mutex = osRtxConfig.mpi.mutex;
  132. }
  133. if (osRtxConfig.mpi.semaphore != NULL) {
  134. (void)osRtxMemoryPoolInit(osRtxConfig.mpi.semaphore,
  135. osRtxConfig.mpi.semaphore->max_blocks,
  136. osRtxConfig.mpi.semaphore->block_size,
  137. osRtxConfig.mpi.semaphore->block_base);
  138. osRtxInfo.mpi.semaphore = osRtxConfig.mpi.semaphore;
  139. }
  140. if (osRtxConfig.mpi.memory_pool != NULL) {
  141. (void)osRtxMemoryPoolInit(osRtxConfig.mpi.memory_pool,
  142. osRtxConfig.mpi.memory_pool->max_blocks,
  143. osRtxConfig.mpi.memory_pool->block_size,
  144. osRtxConfig.mpi.memory_pool->block_base);
  145. osRtxInfo.mpi.memory_pool = osRtxConfig.mpi.memory_pool;
  146. }
  147. if (osRtxConfig.mpi.message_queue != NULL) {
  148. (void)osRtxMemoryPoolInit(osRtxConfig.mpi.message_queue,
  149. osRtxConfig.mpi.message_queue->max_blocks,
  150. osRtxConfig.mpi.message_queue->block_size,
  151. osRtxConfig.mpi.message_queue->block_base);
  152. osRtxInfo.mpi.message_queue = osRtxConfig.mpi.message_queue;
  153. }
  154. osRtxInfo.kernel.state = osRtxKernelReady;
  155. EvrRtxKernelInitialized();
  156. return osOK;
  157. }
  158. /// Get RTOS Kernel Information.
  159. /// \note API identical to osKernelGetInfo
  160. static osStatus_t svcRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
  161. uint32_t size;
  162. if (version != NULL) {
  163. version->api = osRtxVersionAPI;
  164. version->kernel = osRtxVersionKernel;
  165. }
  166. if ((id_buf != NULL) && (id_size != 0U)) {
  167. if (id_size > sizeof(osRtxKernelId)) {
  168. size = sizeof(osRtxKernelId);
  169. } else {
  170. size = id_size;
  171. }
  172. memcpy(id_buf, osRtxKernelId, size);
  173. }
  174. EvrRtxKernelInfoRetrieved(version, id_buf, id_size);
  175. return osOK;
  176. }
  177. /// Get the current RTOS Kernel state.
  178. /// \note API identical to osKernelGetState
  179. static osKernelState_t svcRtxKernelGetState (void) {
  180. osKernelState_t state = osRtxKernelState();
  181. EvrRtxKernelGetState(state);
  182. return state;
  183. }
  184. /// Start the RTOS Kernel scheduler.
  185. /// \note API identical to osKernelStart
  186. static osStatus_t svcRtxKernelStart (void) {
  187. os_thread_t *thread;
  188. if (osRtxInfo.kernel.state != osRtxKernelReady) {
  189. EvrRtxKernelError(osRtxErrorKernelNotReady);
  190. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  191. return osError;
  192. }
  193. // Thread startup (Idle and Timer Thread)
  194. if (!osRtxThreadStartup()) {
  195. EvrRtxKernelError((int32_t)osError);
  196. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  197. return osError;
  198. }
  199. // Setup SVC and PendSV System Service Calls
  200. SVC_Setup();
  201. // Setup RTOS Tick
  202. if (OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER) != 0) {
  203. EvrRtxKernelError((int32_t)osError);
  204. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  205. return osError;
  206. }
  207. osRtxInfo.tick_irqn = OS_Tick_GetIRQn();
  208. // Enable RTOS Tick
  209. OS_Tick_Enable();
  210. // Switch to Ready Thread with highest Priority
  211. thread = osRtxThreadListGet(&osRtxInfo.thread.ready);
  212. osRtxThreadSwitch(thread);
  213. if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) {
  214. // Privileged Thread mode & PSP
  215. __set_CONTROL(0x02U);
  216. } else {
  217. // Unprivileged Thread mode & PSP
  218. __set_CONTROL(0x03U);
  219. }
  220. osRtxInfo.kernel.state = osRtxKernelRunning;
  221. EvrRtxKernelStarted();
  222. return osOK;
  223. }
  224. /// Lock the RTOS Kernel scheduler.
  225. /// \note API identical to osKernelLock
  226. static int32_t svcRtxKernelLock (void) {
  227. int32_t lock;
  228. switch (osRtxInfo.kernel.state) {
  229. case osRtxKernelRunning:
  230. osRtxInfo.kernel.state = osRtxKernelLocked;
  231. EvrRtxKernelLocked(0);
  232. lock = 0;
  233. break;
  234. case osRtxKernelLocked:
  235. EvrRtxKernelLocked(1);
  236. lock = 1;
  237. break;
  238. default:
  239. EvrRtxKernelError((int32_t)osError);
  240. lock = (int32_t)osError;
  241. break;
  242. }
  243. return lock;
  244. }
  245. /// Unlock the RTOS Kernel scheduler.
  246. /// \note API identical to osKernelUnlock
  247. static int32_t svcRtxKernelUnlock (void) {
  248. int32_t lock;
  249. switch (osRtxInfo.kernel.state) {
  250. case osRtxKernelRunning:
  251. EvrRtxKernelUnlocked(0);
  252. lock = 0;
  253. break;
  254. case osRtxKernelLocked:
  255. osRtxInfo.kernel.state = osRtxKernelRunning;
  256. EvrRtxKernelUnlocked(1);
  257. lock = 1;
  258. break;
  259. default:
  260. EvrRtxKernelError((int32_t)osError);
  261. lock = (int32_t)osError;
  262. break;
  263. }
  264. return lock;
  265. }
  266. /// Restore the RTOS Kernel scheduler lock state.
  267. /// \note API identical to osKernelRestoreLock
  268. static int32_t svcRtxKernelRestoreLock (int32_t lock) {
  269. int32_t lock_new;
  270. switch (osRtxInfo.kernel.state) {
  271. case osRtxKernelRunning:
  272. case osRtxKernelLocked:
  273. switch (lock) {
  274. case 0:
  275. osRtxInfo.kernel.state = osRtxKernelRunning;
  276. EvrRtxKernelLockRestored(0);
  277. lock_new = 0;
  278. break;
  279. case 1:
  280. osRtxInfo.kernel.state = osRtxKernelLocked;
  281. EvrRtxKernelLockRestored(1);
  282. lock_new = 1;
  283. break;
  284. default:
  285. EvrRtxKernelError((int32_t)osError);
  286. lock_new = (int32_t)osError;
  287. break;
  288. }
  289. break;
  290. default:
  291. EvrRtxKernelError((int32_t)osError);
  292. lock_new = (int32_t)osError;
  293. break;
  294. }
  295. return lock_new;
  296. }
  297. /// Suspend the RTOS Kernel scheduler.
  298. /// \note API identical to osKernelSuspend
  299. static uint32_t svcRtxKernelSuspend (void) {
  300. const os_thread_t *thread;
  301. const os_timer_t *timer;
  302. uint32_t delay;
  303. if (osRtxInfo.kernel.state != osRtxKernelRunning) {
  304. EvrRtxKernelError(osRtxErrorKernelNotRunning);
  305. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  306. return 0U;
  307. }
  308. KernelBlock();
  309. delay = osWaitForever;
  310. // Check Thread Delay list
  311. thread = osRtxInfo.thread.delay_list;
  312. if (thread != NULL) {
  313. delay = thread->delay;
  314. }
  315. // Check Active Timer list
  316. timer = osRtxInfo.timer.list;
  317. if (timer != NULL) {
  318. if (timer->tick < delay) {
  319. delay = timer->tick;
  320. }
  321. }
  322. osRtxInfo.kernel.state = osRtxKernelSuspended;
  323. EvrRtxKernelSuspended(delay);
  324. return delay;
  325. }
  326. /// Resume the RTOS Kernel scheduler.
  327. /// \note API identical to osKernelResume
  328. static void svcRtxKernelResume (uint32_t sleep_ticks) {
  329. os_thread_t *thread;
  330. os_timer_t *timer;
  331. uint32_t delay;
  332. uint32_t ticks;
  333. if (osRtxInfo.kernel.state != osRtxKernelSuspended) {
  334. EvrRtxKernelResumed();
  335. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  336. return;
  337. }
  338. osRtxInfo.kernel.tick += sleep_ticks;
  339. // Process Thread Delay list
  340. thread = osRtxInfo.thread.delay_list;
  341. if (thread != NULL) {
  342. delay = sleep_ticks;
  343. do {
  344. if (delay >= thread->delay) {
  345. delay -= thread->delay;
  346. thread->delay = 1U;
  347. osRtxThreadDelayTick();
  348. thread = osRtxInfo.thread.delay_list;
  349. } else {
  350. thread->delay -= delay;
  351. delay = 0U;
  352. }
  353. } while ((thread != NULL) && (delay != 0U));
  354. }
  355. // Process Active Timer list
  356. timer = osRtxInfo.timer.list;
  357. if (timer != NULL) {
  358. ticks = sleep_ticks;
  359. do {
  360. if (ticks >= timer->tick) {
  361. ticks -= timer->tick;
  362. timer->tick = 1U;
  363. osRtxInfo.timer.tick();
  364. timer = osRtxInfo.timer.list;
  365. } else {
  366. timer->tick -= ticks;
  367. ticks = 0U;
  368. }
  369. } while ((timer != NULL) && (ticks != 0U));
  370. }
  371. osRtxInfo.kernel.state = osRtxKernelRunning;
  372. osRtxThreadDispatch(NULL);
  373. KernelUnblock();
  374. EvrRtxKernelResumed();
  375. }
  376. /// Get the RTOS kernel tick count.
  377. /// \note API identical to osKernelGetTickCount
  378. static uint32_t svcRtxKernelGetTickCount (void) {
  379. EvrRtxKernelGetTickCount(osRtxInfo.kernel.tick);
  380. return osRtxInfo.kernel.tick;
  381. }
  382. /// Get the RTOS kernel tick frequency.
  383. /// \note API identical to osKernelGetTickFreq
  384. static uint32_t svcRtxKernelGetTickFreq (void) {
  385. EvrRtxKernelGetTickFreq(osRtxConfig.tick_freq);
  386. return osRtxConfig.tick_freq;
  387. }
  388. /// Get the RTOS kernel system timer count.
  389. /// \note API identical to osKernelGetSysTimerCount
  390. static uint32_t svcRtxKernelGetSysTimerCount (void) {
  391. uint32_t tick;
  392. uint32_t count;
  393. tick = (uint32_t)osRtxInfo.kernel.tick;
  394. count = OS_Tick_GetCount();
  395. if (OS_Tick_GetOverflow() != 0U) {
  396. count = OS_Tick_GetCount();
  397. tick++;
  398. }
  399. count += tick * OS_Tick_GetInterval();
  400. EvrRtxKernelGetSysTimerCount(count);
  401. return count;
  402. }
  403. /// Get the RTOS kernel system timer frequency.
  404. /// \note API identical to osKernelGetSysTimerFreq
  405. static uint32_t svcRtxKernelGetSysTimerFreq (void) {
  406. uint32_t freq = OS_Tick_GetClock();
  407. EvrRtxKernelGetSysTimerFreq(freq);
  408. return freq;
  409. }
  410. // Service Calls definitions
  411. //lint ++flb "Library Begin" [MISRA Note 11]
  412. SVC0_0 (KernelInitialize, osStatus_t)
  413. SVC0_3 (KernelGetInfo, osStatus_t, osVersion_t *, char *, uint32_t)
  414. SVC0_0 (KernelStart, osStatus_t)
  415. SVC0_0 (KernelLock, int32_t)
  416. SVC0_0 (KernelUnlock, int32_t)
  417. SVC0_1 (KernelRestoreLock, int32_t, int32_t)
  418. SVC0_0 (KernelSuspend, uint32_t)
  419. SVC0_1N(KernelResume, void, uint32_t)
  420. SVC0_0 (KernelGetState, osKernelState_t)
  421. SVC0_0 (KernelGetTickCount, uint32_t)
  422. SVC0_0 (KernelGetTickFreq, uint32_t)
  423. SVC0_0 (KernelGetSysTimerCount, uint32_t)
  424. SVC0_0 (KernelGetSysTimerFreq, uint32_t)
  425. //lint --flb "Library End"
  426. // ==== Library functions ====
  427. /// RTOS Kernel Pre-Initialization Hook
  428. //lint -esym(759,osRtxKernelPreInit) "Prototype in header"
  429. //lint -esym(765,osRtxKernelPreInit) "Global scope (can be overridden)"
  430. //lint -esym(522,osRtxKernelPreInit) "Can be overridden (do not lack side-effects)"
  431. __WEAK void osRtxKernelPreInit (void) {
  432. }
  433. // ==== Public API ====
  434. /// Initialize the RTOS Kernel.
  435. osStatus_t osKernelInitialize (void) {
  436. osStatus_t status;
  437. osRtxKernelPreInit();
  438. EvrRtxKernelInitialize();
  439. if (IsIrqMode() || IsIrqMasked()) {
  440. EvrRtxKernelError((int32_t)osErrorISR);
  441. status = osErrorISR;
  442. } else {
  443. status = __svcKernelInitialize();
  444. }
  445. return status;
  446. }
  447. /// Get RTOS Kernel Information.
  448. osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
  449. osStatus_t status;
  450. EvrRtxKernelGetInfo(version, id_buf, id_size);
  451. if (IsIrqMode() || IsIrqMasked() || IsPrivileged()) {
  452. status = svcRtxKernelGetInfo(version, id_buf, id_size);
  453. } else {
  454. status = __svcKernelGetInfo(version, id_buf, id_size);
  455. }
  456. return status;
  457. }
  458. /// Get the current RTOS Kernel state.
  459. osKernelState_t osKernelGetState (void) {
  460. osKernelState_t state;
  461. if (IsIrqMode() || IsIrqMasked() || IsPrivileged()) {
  462. state = svcRtxKernelGetState();
  463. } else {
  464. state = __svcKernelGetState();
  465. }
  466. return state;
  467. }
  468. /// Start the RTOS Kernel scheduler.
  469. osStatus_t osKernelStart (void) {
  470. osStatus_t status;
  471. EvrRtxKernelStart();
  472. if (IsIrqMode() || IsIrqMasked()) {
  473. EvrRtxKernelError((int32_t)osErrorISR);
  474. status = osErrorISR;
  475. } else {
  476. status = __svcKernelStart();
  477. }
  478. return status;
  479. }
  480. /// Lock the RTOS Kernel scheduler.
  481. int32_t osKernelLock (void) {
  482. int32_t lock;
  483. EvrRtxKernelLock();
  484. if (IsIrqMode() || IsIrqMasked()) {
  485. EvrRtxKernelError((int32_t)osErrorISR);
  486. lock = (int32_t)osErrorISR;
  487. } else {
  488. lock = __svcKernelLock();
  489. }
  490. return lock;
  491. }
  492. /// Unlock the RTOS Kernel scheduler.
  493. int32_t osKernelUnlock (void) {
  494. int32_t lock;
  495. EvrRtxKernelUnlock();
  496. if (IsIrqMode() || IsIrqMasked()) {
  497. EvrRtxKernelError((int32_t)osErrorISR);
  498. lock = (int32_t)osErrorISR;
  499. } else {
  500. lock = __svcKernelUnlock();
  501. }
  502. return lock;
  503. }
  504. /// Restore the RTOS Kernel scheduler lock state.
  505. int32_t osKernelRestoreLock (int32_t lock) {
  506. int32_t lock_new;
  507. EvrRtxKernelRestoreLock(lock);
  508. if (IsIrqMode() || IsIrqMasked()) {
  509. EvrRtxKernelError((int32_t)osErrorISR);
  510. lock_new = (int32_t)osErrorISR;
  511. } else {
  512. lock_new = __svcKernelRestoreLock(lock);
  513. }
  514. return lock_new;
  515. }
  516. /// Suspend the RTOS Kernel scheduler.
  517. uint32_t osKernelSuspend (void) {
  518. uint32_t ticks;
  519. EvrRtxKernelSuspend();
  520. if (IsIrqMode() || IsIrqMasked()) {
  521. EvrRtxKernelError((int32_t)osErrorISR);
  522. ticks = 0U;
  523. } else {
  524. ticks = __svcKernelSuspend();
  525. }
  526. return ticks;
  527. }
  528. /// Resume the RTOS Kernel scheduler.
  529. void osKernelResume (uint32_t sleep_ticks) {
  530. EvrRtxKernelResume(sleep_ticks);
  531. if (IsIrqMode() || IsIrqMasked()) {
  532. EvrRtxKernelError((int32_t)osErrorISR);
  533. } else {
  534. __svcKernelResume(sleep_ticks);
  535. }
  536. }
  537. /// Get the RTOS kernel tick count.
  538. uint32_t osKernelGetTickCount (void) {
  539. uint32_t count;
  540. if (IsIrqMode() || IsIrqMasked()) {
  541. count = svcRtxKernelGetTickCount();
  542. } else {
  543. count = __svcKernelGetTickCount();
  544. }
  545. return count;
  546. }
  547. /// Get the RTOS kernel tick frequency.
  548. uint32_t osKernelGetTickFreq (void) {
  549. uint32_t freq;
  550. if (IsIrqMode() || IsIrqMasked()) {
  551. freq = svcRtxKernelGetTickFreq();
  552. } else {
  553. freq = __svcKernelGetTickFreq();
  554. }
  555. return freq;
  556. }
  557. /// Get the RTOS kernel system timer count.
  558. uint32_t osKernelGetSysTimerCount (void) {
  559. uint32_t count;
  560. if (IsIrqMode() || IsIrqMasked()) {
  561. count = svcRtxKernelGetSysTimerCount();
  562. } else {
  563. count = __svcKernelGetSysTimerCount();
  564. }
  565. return count;
  566. }
  567. /// Get the RTOS kernel system timer frequency.
  568. uint32_t osKernelGetSysTimerFreq (void) {
  569. uint32_t freq;
  570. if (IsIrqMode() || IsIrqMasked()) {
  571. freq = svcRtxKernelGetSysTimerFreq();
  572. } else {
  573. freq = __svcKernelGetSysTimerFreq();
  574. }
  575. return freq;
  576. }