rtx_kernel.c 19 KB

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