rtx_kernel.c 18 KB

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