rtx_kernel.c 19 KB

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