rtx_kernel.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  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. if (version != NULL) {
  174. version->api = osRtxVersionAPI;
  175. version->kernel = osRtxVersionKernel;
  176. }
  177. if ((id_buf != NULL) && (id_size != 0U)) {
  178. if (id_size > sizeof(osRtxKernelId)) {
  179. id_size = sizeof(osRtxKernelId);
  180. }
  181. memcpy(id_buf, osRtxKernelId, id_size);
  182. }
  183. EvrRtxKernelInfoRetrieved(version, id_buf);
  184. return osOK;
  185. }
  186. /// Get the current RTOS Kernel state.
  187. /// \note API identical to osKernelGetState
  188. static osKernelState_t svcRtxKernelGetState (void) {
  189. EvrRtxKernelGetState((osKernelState_t)(osRtxInfo.kernel.state));
  190. return ((osKernelState_t)(osRtxInfo.kernel.state));
  191. }
  192. /// Start the RTOS Kernel scheduler.
  193. /// \note API identical to osKernelStart
  194. static osStatus_t svcRtxKernelStart (void) {
  195. os_thread_t *thread;
  196. if (osRtxInfo.kernel.state != osRtxKernelReady) {
  197. EvrRtxKernelError(osRtxErrorKernelNotReady);
  198. return osError;
  199. }
  200. // Thread startup (Idle and Timer Thread)
  201. if (!osRtxThreadStartup()) {
  202. EvrRtxKernelError((int32_t)osError);
  203. return osError;
  204. }
  205. // Setup SVC and PendSV System Service Calls
  206. SVC_Setup();
  207. // Setup RTOS Tick
  208. if (OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER) != 0) {
  209. EvrRtxKernelError((int32_t)osError);
  210. return osError;
  211. }
  212. osRtxInfo.tick_irqn = OS_Tick_GetIRQn();
  213. // Enable RTOS Tick
  214. OS_Tick_Enable();
  215. // Switch to Ready Thread with highest Priority
  216. thread = osRtxThreadListGet(&osRtxInfo.thread.ready);
  217. if (thread == NULL) {
  218. EvrRtxKernelError((int32_t)osError);
  219. return osError;
  220. }
  221. osRtxThreadSwitch(thread);
  222. if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) {
  223. // Privileged Thread mode & PSP
  224. __set_CONTROL(0x02U);
  225. } else {
  226. // Unprivileged Thread mode & PSP
  227. __set_CONTROL(0x03U);
  228. }
  229. osRtxInfo.kernel.state = osRtxKernelRunning;
  230. EvrRtxKernelStarted();
  231. return osOK;
  232. }
  233. /// Lock the RTOS Kernel scheduler.
  234. /// \note API identical to osKernelLock
  235. static int32_t svcRtxKernelLock (void) {
  236. int32_t lock;
  237. switch (osRtxInfo.kernel.state) {
  238. case osRtxKernelRunning:
  239. osRtxInfo.kernel.state = osRtxKernelLocked;
  240. EvrRtxKernelLocked(0);
  241. lock = 0;
  242. break;
  243. case osRtxKernelLocked:
  244. EvrRtxKernelLocked(1);
  245. lock = 1;
  246. break;
  247. default:
  248. EvrRtxKernelError((int32_t)osError);
  249. lock = (int32_t)osError;
  250. break;
  251. }
  252. return lock;
  253. }
  254. /// Unlock the RTOS Kernel scheduler.
  255. /// \note API identical to osKernelUnlock
  256. static int32_t svcRtxKernelUnlock (void) {
  257. int32_t lock;
  258. switch (osRtxInfo.kernel.state) {
  259. case osRtxKernelRunning:
  260. EvrRtxKernelUnlocked(0);
  261. lock = 0;
  262. break;
  263. case osRtxKernelLocked:
  264. osRtxInfo.kernel.state = osRtxKernelRunning;
  265. EvrRtxKernelUnlocked(1);
  266. lock = 1;
  267. break;
  268. default:
  269. EvrRtxKernelError((int32_t)osError);
  270. lock = (int32_t)osError;
  271. break;
  272. }
  273. return lock;
  274. }
  275. /// Restore the RTOS Kernel scheduler lock state.
  276. /// \note API identical to osKernelRestoreLock
  277. static int32_t svcRtxKernelRestoreLock (int32_t lock) {
  278. int32_t lock_new;
  279. switch (osRtxInfo.kernel.state) {
  280. case osRtxKernelRunning:
  281. case osRtxKernelLocked:
  282. switch (lock) {
  283. case 0:
  284. osRtxInfo.kernel.state = osRtxKernelRunning;
  285. EvrRtxKernelLockRestored(0);
  286. lock_new = 0;
  287. break;
  288. case 1:
  289. osRtxInfo.kernel.state = osRtxKernelLocked;
  290. EvrRtxKernelLockRestored(1);
  291. lock_new = 1;
  292. break;
  293. default:
  294. EvrRtxKernelError((int32_t)osError);
  295. lock_new = (int32_t)osError;
  296. break;
  297. }
  298. break;
  299. default:
  300. EvrRtxKernelError((int32_t)osError);
  301. lock_new = (int32_t)osError;
  302. break;
  303. }
  304. return lock_new;
  305. }
  306. /// Suspend the RTOS Kernel scheduler.
  307. /// \note API identical to osKernelSuspend
  308. static uint32_t svcRtxKernelSuspend (void) {
  309. os_thread_t *thread;
  310. os_timer_t *timer;
  311. uint32_t delay;
  312. if (osRtxInfo.kernel.state != osRtxKernelRunning) {
  313. EvrRtxKernelError(osRtxErrorKernelNotRunning);
  314. return 0U;
  315. }
  316. KernelBlock();
  317. delay = osWaitForever;
  318. // Check Thread Delay list
  319. thread = osRtxInfo.thread.delay_list;
  320. if (thread != NULL) {
  321. delay = thread->delay;
  322. }
  323. // Check Active Timer list
  324. timer = osRtxInfo.timer.list;
  325. if (timer != NULL) {
  326. if (timer->tick < delay) {
  327. delay = timer->tick;
  328. }
  329. }
  330. osRtxInfo.kernel.state = osRtxKernelSuspended;
  331. EvrRtxKernelSuspended(delay);
  332. return delay;
  333. }
  334. /// Resume the RTOS Kernel scheduler.
  335. /// \note API identical to osKernelResume
  336. static void svcRtxKernelResume (uint32_t sleep_ticks) {
  337. os_thread_t *thread;
  338. os_timer_t *timer;
  339. uint32_t delay;
  340. if (osRtxInfo.kernel.state != osRtxKernelSuspended) {
  341. EvrRtxKernelResumed();
  342. return;
  343. }
  344. // Process Thread Delay list
  345. thread = osRtxInfo.thread.delay_list;
  346. if (thread != NULL) {
  347. delay = sleep_ticks;
  348. if (delay >= thread->delay) {
  349. delay -= thread->delay;
  350. osRtxInfo.kernel.tick += thread->delay;
  351. thread->delay = 1U;
  352. do {
  353. osRtxThreadDelayTick();
  354. if (delay == 0U) {
  355. break;
  356. }
  357. delay--;
  358. osRtxInfo.kernel.tick++;
  359. } while (osRtxInfo.thread.delay_list != NULL);
  360. } else {
  361. thread->delay -= delay;
  362. osRtxInfo.kernel.tick += delay;
  363. }
  364. } else {
  365. osRtxInfo.kernel.tick += sleep_ticks;
  366. }
  367. // Process Active Timer list
  368. timer = osRtxInfo.timer.list;
  369. if (timer != NULL) {
  370. if (sleep_ticks >= timer->tick) {
  371. sleep_ticks -= timer->tick;
  372. timer->tick = 1U;
  373. do {
  374. osRtxInfo.timer.tick();
  375. if (sleep_ticks == 0U) {
  376. break;
  377. }
  378. sleep_ticks--;
  379. } while (osRtxInfo.timer.list != NULL);
  380. } else {
  381. timer->tick -= sleep_ticks;
  382. }
  383. }
  384. osRtxInfo.kernel.state = osRtxKernelRunning;
  385. osRtxThreadDispatch(NULL);
  386. KernelUnblock();
  387. EvrRtxKernelResumed();
  388. }
  389. /// Get the RTOS kernel tick count.
  390. /// \note API identical to osKernelGetTickCount
  391. static uint32_t svcRtxKernelGetTickCount (void) {
  392. EvrRtxKernelGetTickCount(osRtxInfo.kernel.tick);
  393. return osRtxInfo.kernel.tick;
  394. }
  395. /// Get the RTOS kernel tick frequency.
  396. /// \note API identical to osKernelGetTickFreq
  397. static uint32_t svcRtxKernelGetTickFreq (void) {
  398. EvrRtxKernelGetTickFreq(osRtxConfig.tick_freq);
  399. return osRtxConfig.tick_freq;
  400. }
  401. /// Get the RTOS kernel system timer count.
  402. /// \note API identical to osKernelGetSysTimerCount
  403. static uint32_t svcRtxKernelGetSysTimerCount (void) {
  404. uint32_t tick;
  405. uint32_t count;
  406. tick = (uint32_t)osRtxInfo.kernel.tick;
  407. count = OS_Tick_GetCount();
  408. if (OS_Tick_GetOverflow() != 0U) {
  409. count = OS_Tick_GetCount();
  410. tick++;
  411. }
  412. count += tick * OS_Tick_GetInterval();
  413. EvrRtxKernelGetSysTimerCount(count);
  414. return count;
  415. }
  416. /// Get the RTOS kernel system timer frequency.
  417. /// \note API identical to osKernelGetSysTimerFreq
  418. static uint32_t svcRtxKernelGetSysTimerFreq (void) {
  419. uint32_t freq = OS_Tick_GetClock();
  420. EvrRtxKernelGetSysTimerFreq(freq);
  421. return freq;
  422. }
  423. // Service Calls definitions
  424. SVC0_0 (KernelInitialize, osStatus_t)
  425. SVC0_3 (KernelGetInfo, osStatus_t, osVersion_t *, char *, uint32_t)
  426. SVC0_0 (KernelStart, osStatus_t)
  427. SVC0_0 (KernelLock, int32_t)
  428. SVC0_0 (KernelUnlock, int32_t)
  429. SVC0_1 (KernelRestoreLock, int32_t, int32_t)
  430. SVC0_0 (KernelSuspend, uint32_t)
  431. SVC0_1N(KernelResume, void, uint32_t)
  432. SVC0_0 (KernelGetState, osKernelState_t)
  433. SVC0_0 (KernelGetTickCount, uint32_t)
  434. SVC0_0 (KernelGetTickFreq, uint32_t)
  435. SVC0_0 (KernelGetSysTimerCount, uint32_t)
  436. SVC0_0 (KernelGetSysTimerFreq, uint32_t)
  437. // ==== Public API ====
  438. /// Initialize the RTOS Kernel.
  439. osStatus_t osKernelInitialize (void) {
  440. osStatus_t status;
  441. EvrRtxKernelInitialize();
  442. if (IsIrqMode() || IsIrqMasked()) {
  443. EvrRtxKernelError((int32_t)osErrorISR);
  444. status = osErrorISR;
  445. } else {
  446. status = __svcKernelInitialize();
  447. }
  448. return status;
  449. }
  450. /// Get RTOS Kernel Information.
  451. osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
  452. osStatus_t status;
  453. EvrRtxKernelGetInfo(version, id_buf, id_size);
  454. if (IsPrivileged() || IsIrqMode() || IsIrqMasked()) {
  455. status = svcRtxKernelGetInfo(version, id_buf, id_size);
  456. } else {
  457. status = __svcKernelGetInfo(version, id_buf, id_size);
  458. }
  459. return status;
  460. }
  461. /// Get the current RTOS Kernel state.
  462. osKernelState_t osKernelGetState (void) {
  463. osKernelState_t state;
  464. if (IsPrivileged() || IsIrqMode() || IsIrqMasked()) {
  465. state = svcRtxKernelGetState();
  466. } else {
  467. state = __svcKernelGetState();
  468. }
  469. return state;
  470. }
  471. /// Start the RTOS Kernel scheduler.
  472. osStatus_t osKernelStart (void) {
  473. osStatus_t status;
  474. EvrRtxKernelStart();
  475. if (IsIrqMode() || IsIrqMasked()) {
  476. EvrRtxKernelError((int32_t)osErrorISR);
  477. status = osErrorISR;
  478. } else {
  479. status = __svcKernelStart();
  480. }
  481. return status;
  482. }
  483. /// Lock the RTOS Kernel scheduler.
  484. int32_t osKernelLock (void) {
  485. int32_t lock;
  486. EvrRtxKernelLock();
  487. if (IsIrqMode() || IsIrqMasked()) {
  488. EvrRtxKernelError((int32_t)osErrorISR);
  489. lock = (int32_t)osErrorISR;
  490. } else {
  491. lock = __svcKernelLock();
  492. }
  493. return lock;
  494. }
  495. /// Unlock the RTOS Kernel scheduler.
  496. int32_t osKernelUnlock (void) {
  497. int32_t lock;
  498. EvrRtxKernelUnlock();
  499. if (IsIrqMode() || IsIrqMasked()) {
  500. EvrRtxKernelError((int32_t)osErrorISR);
  501. lock = (int32_t)osErrorISR;
  502. } else {
  503. lock = __svcKernelUnlock();
  504. }
  505. return lock;
  506. }
  507. /// Restore the RTOS Kernel scheduler lock state.
  508. int32_t osKernelRestoreLock (int32_t lock) {
  509. int32_t lock_new;
  510. EvrRtxKernelRestoreLock(lock);
  511. if (IsIrqMode() || IsIrqMasked()) {
  512. EvrRtxKernelError((int32_t)osErrorISR);
  513. lock_new = (int32_t)osErrorISR;
  514. } else {
  515. lock_new = __svcKernelRestoreLock(lock);
  516. }
  517. return lock_new;
  518. }
  519. /// Suspend the RTOS Kernel scheduler.
  520. uint32_t osKernelSuspend (void) {
  521. uint32_t ticks;
  522. EvrRtxKernelSuspend();
  523. if (IsIrqMode() || IsIrqMasked()) {
  524. EvrRtxKernelError((int32_t)osErrorISR);
  525. ticks = 0U;
  526. } else {
  527. ticks = __svcKernelSuspend();
  528. }
  529. return ticks;
  530. }
  531. /// Resume the RTOS Kernel scheduler.
  532. void osKernelResume (uint32_t sleep_ticks) {
  533. EvrRtxKernelResume(sleep_ticks);
  534. if (IsIrqMode() || IsIrqMasked()) {
  535. EvrRtxKernelError((int32_t)osErrorISR);
  536. } else {
  537. __svcKernelResume(sleep_ticks);
  538. }
  539. }
  540. /// Get the RTOS kernel tick count.
  541. uint32_t osKernelGetTickCount (void) {
  542. uint32_t count;
  543. if (IsIrqMode() || IsIrqMasked()) {
  544. count = svcRtxKernelGetTickCount();
  545. } else {
  546. count = __svcKernelGetTickCount();
  547. }
  548. return count;
  549. }
  550. /// Get the RTOS kernel tick frequency.
  551. uint32_t osKernelGetTickFreq (void) {
  552. uint32_t freq;
  553. if (IsIrqMode() || IsIrqMasked()) {
  554. freq = svcRtxKernelGetTickFreq();
  555. } else {
  556. freq = __svcKernelGetTickFreq();
  557. }
  558. return freq;
  559. }
  560. /// Get the RTOS kernel system timer count.
  561. uint32_t osKernelGetSysTimerCount (void) {
  562. uint32_t count;
  563. if (IsIrqMode() || IsIrqMasked()) {
  564. count = svcRtxKernelGetSysTimerCount();
  565. } else {
  566. count = __svcKernelGetSysTimerCount();
  567. }
  568. return count;
  569. }
  570. /// Get the RTOS kernel system timer frequency.
  571. uint32_t osKernelGetSysTimerFreq (void) {
  572. uint32_t freq;
  573. if (IsIrqMode() || IsIrqMasked()) {
  574. freq = svcRtxKernelGetSysTimerFreq();
  575. } else {
  576. freq = __svcKernelGetSysTimerFreq();
  577. }
  578. return freq;
  579. }