681 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			681 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * Copyright (c) 2013-2019 Arm Limited. All rights reserved. | ||
|  |  * | ||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||
|  |  * | ||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||
|  |  * not use this file except in compliance with the License. | ||
|  |  * You may obtain a copy of the License at | ||
|  |  * | ||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||
|  |  * | ||
|  |  * Unless required by applicable law or agreed to in writing, software | ||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
|  |  * See the License for the specific language governing permissions and | ||
|  |  * limitations under the License. | ||
|  |  * | ||
|  |  * ----------------------------------------------------------------------------- | ||
|  |  * | ||
|  |  * Project:     CMSIS-RTOS RTX | ||
|  |  * Title:       Kernel functions | ||
|  |  * | ||
|  |  * ----------------------------------------------------------------------------- | ||
|  |  */ | ||
|  | 
 | ||
|  | #include "rtx_lib.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //  OS Runtime Information
 | ||
|  | osRtxInfo_t osRtxInfo __attribute__((section(".data.os"))) = | ||
|  | //lint -e{785} "Initialize only OS ID, OS Version and Kernel State"
 | ||
|  | { .os_id = osRtxKernelId, .version = osRtxVersionKernel, .kernel.state = osRtxKernelInactive }; | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== Helper functions ====
 | ||
|  | 
 | ||
|  | /// Block Kernel (disable: thread switching, time tick, post ISR processing).
 | ||
|  | static void KernelBlock (void) { | ||
|  | 
 | ||
|  |   OS_Tick_Disable(); | ||
|  | 
 | ||
|  |   osRtxInfo.kernel.blocked = 1U; | ||
|  |   __DSB(); | ||
|  | 
 | ||
|  |   if (GetPendSV() != 0U) { | ||
|  |     ClrPendSV(); | ||
|  |     osRtxInfo.kernel.pendSV = 1U; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | /// Unblock Kernel
 | ||
|  | static void KernelUnblock (void) { | ||
|  | 
 | ||
|  |   osRtxInfo.kernel.blocked = 0U; | ||
|  |   __DSB(); | ||
|  | 
 | ||
|  |   if (osRtxInfo.kernel.pendSV != 0U) { | ||
|  |     osRtxInfo.kernel.pendSV = 0U; | ||
|  |     SetPendSV(); | ||
|  |   } | ||
|  | 
 | ||
|  |   OS_Tick_Enable(); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== Service Calls ====
 | ||
|  | 
 | ||
|  | /// Initialize the RTOS Kernel.
 | ||
|  | /// \note API identical to osKernelInitialize
 | ||
|  | static osStatus_t svcRtxKernelInitialize (void) { | ||
|  | 
 | ||
|  |   if (osRtxInfo.kernel.state == osRtxKernelReady) { | ||
|  |     EvrRtxKernelInitialized(); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osOK; | ||
|  |   } | ||
|  |   if (osRtxInfo.kernel.state != osRtxKernelInactive) { | ||
|  |     EvrRtxKernelError((int32_t)osError); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osError; | ||
|  |   } | ||
|  | 
 | ||
|  | #if (DOMAIN_NS == 1)
 | ||
|  |   // Initialize Secure Process Stack
 | ||
|  |   if (TZ_InitContextSystem_S() == 0U) { | ||
|  |     EvrRtxKernelError(osRtxErrorTZ_InitContext_S); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osError; | ||
|  |   } | ||
|  | #endif
 | ||
|  | 
 | ||
|  |   // Initialize osRtxInfo
 | ||
|  |   memset(&osRtxInfo.kernel, 0, sizeof(osRtxInfo) - offsetof(osRtxInfo_t, kernel)); | ||
|  | 
 | ||
|  |   osRtxInfo.isr_queue.data = osRtxConfig.isr_queue.data; | ||
|  |   osRtxInfo.isr_queue.max  = osRtxConfig.isr_queue.max; | ||
|  | 
 | ||
|  |   osRtxInfo.thread.robin.timeout = osRtxConfig.robin_timeout; | ||
|  | 
 | ||
|  |   // Initialize Memory Pools (Variable Block Size)
 | ||
|  |   if (osRtxMemoryInit(osRtxConfig.mem.common_addr, osRtxConfig.mem.common_size) != 0U) { | ||
|  |     osRtxInfo.mem.common = osRtxConfig.mem.common_addr; | ||
|  |   } | ||
|  |   if (osRtxMemoryInit(osRtxConfig.mem.stack_addr, osRtxConfig.mem.stack_size) != 0U) { | ||
|  |     osRtxInfo.mem.stack = osRtxConfig.mem.stack_addr; | ||
|  |   } else { | ||
|  |     osRtxInfo.mem.stack = osRtxInfo.mem.common; | ||
|  |   } | ||
|  |   if (osRtxMemoryInit(osRtxConfig.mem.mp_data_addr, osRtxConfig.mem.mp_data_size) != 0U) { | ||
|  |     osRtxInfo.mem.mp_data = osRtxConfig.mem.mp_data_addr; | ||
|  |   } else { | ||
|  |     osRtxInfo.mem.mp_data = osRtxInfo.mem.common; | ||
|  |   } | ||
|  |   if (osRtxMemoryInit(osRtxConfig.mem.mq_data_addr, osRtxConfig.mem.mq_data_size) != 0U) { | ||
|  |     osRtxInfo.mem.mq_data = osRtxConfig.mem.mq_data_addr; | ||
|  |   } else { | ||
|  |     osRtxInfo.mem.mq_data = osRtxInfo.mem.common; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Initialize Memory Pools (Fixed Block Size)
 | ||
|  |   if (osRtxConfig.mpi.stack != NULL) { | ||
|  |     (void)osRtxMemoryPoolInit(osRtxConfig.mpi.stack, | ||
|  |                               osRtxConfig.mpi.stack->max_blocks, | ||
|  |                               osRtxConfig.mpi.stack->block_size, | ||
|  |                               osRtxConfig.mpi.stack->block_base); | ||
|  |     osRtxInfo.mpi.stack = osRtxConfig.mpi.stack; | ||
|  |   } | ||
|  |   if (osRtxConfig.mpi.thread != NULL) { | ||
|  |     (void)osRtxMemoryPoolInit(osRtxConfig.mpi.thread, | ||
|  |                               osRtxConfig.mpi.thread->max_blocks, | ||
|  |                               osRtxConfig.mpi.thread->block_size, | ||
|  |                               osRtxConfig.mpi.thread->block_base); | ||
|  |     osRtxInfo.mpi.thread = osRtxConfig.mpi.thread; | ||
|  |   } | ||
|  |   if (osRtxConfig.mpi.timer != NULL) { | ||
|  |     (void)osRtxMemoryPoolInit(osRtxConfig.mpi.timer, | ||
|  |                               osRtxConfig.mpi.timer->max_blocks, | ||
|  |                               osRtxConfig.mpi.timer->block_size, | ||
|  |                               osRtxConfig.mpi.timer->block_base); | ||
|  |     osRtxInfo.mpi.timer = osRtxConfig.mpi.timer; | ||
|  |   } | ||
|  |   if (osRtxConfig.mpi.event_flags != NULL) { | ||
|  |     (void)osRtxMemoryPoolInit(osRtxConfig.mpi.event_flags, | ||
|  |                               osRtxConfig.mpi.event_flags->max_blocks, | ||
|  |                               osRtxConfig.mpi.event_flags->block_size, | ||
|  |                               osRtxConfig.mpi.event_flags->block_base); | ||
|  |     osRtxInfo.mpi.event_flags = osRtxConfig.mpi.event_flags; | ||
|  |   } | ||
|  |   if (osRtxConfig.mpi.mutex != NULL) { | ||
|  |     (void)osRtxMemoryPoolInit(osRtxConfig.mpi.mutex, | ||
|  |                               osRtxConfig.mpi.mutex->max_blocks, | ||
|  |                               osRtxConfig.mpi.mutex->block_size, | ||
|  |                               osRtxConfig.mpi.mutex->block_base); | ||
|  |     osRtxInfo.mpi.mutex = osRtxConfig.mpi.mutex; | ||
|  |   } | ||
|  |   if (osRtxConfig.mpi.semaphore != NULL) { | ||
|  |     (void)osRtxMemoryPoolInit(osRtxConfig.mpi.semaphore, | ||
|  |                               osRtxConfig.mpi.semaphore->max_blocks, | ||
|  |                               osRtxConfig.mpi.semaphore->block_size, | ||
|  |                               osRtxConfig.mpi.semaphore->block_base); | ||
|  |     osRtxInfo.mpi.semaphore = osRtxConfig.mpi.semaphore; | ||
|  |   } | ||
|  |   if (osRtxConfig.mpi.memory_pool != NULL) { | ||
|  |     (void)osRtxMemoryPoolInit(osRtxConfig.mpi.memory_pool, | ||
|  |                               osRtxConfig.mpi.memory_pool->max_blocks, | ||
|  |                               osRtxConfig.mpi.memory_pool->block_size, | ||
|  |                               osRtxConfig.mpi.memory_pool->block_base); | ||
|  |     osRtxInfo.mpi.memory_pool = osRtxConfig.mpi.memory_pool; | ||
|  |   } | ||
|  |   if (osRtxConfig.mpi.message_queue != NULL) { | ||
|  |     (void)osRtxMemoryPoolInit(osRtxConfig.mpi.message_queue, | ||
|  |                               osRtxConfig.mpi.message_queue->max_blocks, | ||
|  |                               osRtxConfig.mpi.message_queue->block_size, | ||
|  |                               osRtxConfig.mpi.message_queue->block_base); | ||
|  |     osRtxInfo.mpi.message_queue = osRtxConfig.mpi.message_queue; | ||
|  |   } | ||
|  | 
 | ||
|  |   osRtxInfo.kernel.state = osRtxKernelReady; | ||
|  | 
 | ||
|  |   EvrRtxKernelInitialized(); | ||
|  | 
 | ||
|  |   return osOK; | ||
|  | } | ||
|  | 
 | ||
|  | ///  Get RTOS Kernel Information.
 | ||
|  | /// \note API identical to osKernelGetInfo
 | ||
|  | static osStatus_t svcRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { | ||
|  |   uint32_t size; | ||
|  | 
 | ||
|  |   if (version != NULL) { | ||
|  |     version->api    = osRtxVersionAPI; | ||
|  |     version->kernel = osRtxVersionKernel; | ||
|  |   } | ||
|  | 
 | ||
|  |   if ((id_buf != NULL) && (id_size != 0U)) { | ||
|  |     if (id_size > sizeof(osRtxKernelId)) { | ||
|  |       size = sizeof(osRtxKernelId); | ||
|  |     } else { | ||
|  |       size = id_size; | ||
|  |     } | ||
|  |     memcpy(id_buf, osRtxKernelId, size); | ||
|  |   } | ||
|  | 
 | ||
|  |   EvrRtxKernelInfoRetrieved(version, id_buf, id_size); | ||
|  | 
 | ||
|  |   return osOK; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the current RTOS Kernel state.
 | ||
|  | /// \note API identical to osKernelGetState
 | ||
|  | static osKernelState_t svcRtxKernelGetState (void) { | ||
|  |   osKernelState_t state = osRtxKernelState(); | ||
|  |   EvrRtxKernelGetState(state); | ||
|  |   return state; | ||
|  | } | ||
|  | 
 | ||
|  | /// Start the RTOS Kernel scheduler.
 | ||
|  | /// \note API identical to osKernelStart
 | ||
|  | static osStatus_t svcRtxKernelStart (void) { | ||
|  |   os_thread_t *thread; | ||
|  | 
 | ||
|  |   if (osRtxInfo.kernel.state != osRtxKernelReady) { | ||
|  |     EvrRtxKernelError(osRtxErrorKernelNotReady); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osError; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Thread startup (Idle and Timer Thread)
 | ||
|  |   if (!osRtxThreadStartup()) { | ||
|  |     EvrRtxKernelError((int32_t)osError); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osError; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Setup SVC and PendSV System Service Calls
 | ||
|  |   SVC_Setup(); | ||
|  | 
 | ||
|  |   // Setup RTOS Tick
 | ||
|  |   if (OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER) != 0) { | ||
|  |     EvrRtxKernelError((int32_t)osError); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osError; | ||
|  |   } | ||
|  |   osRtxInfo.tick_irqn = OS_Tick_GetIRQn(); | ||
|  | 
 | ||
|  |   // Enable RTOS Tick
 | ||
|  |   OS_Tick_Enable(); | ||
|  | 
 | ||
|  |   // Switch to Ready Thread with highest Priority
 | ||
|  |   thread = osRtxThreadListGet(&osRtxInfo.thread.ready); | ||
|  |   osRtxThreadSwitch(thread); | ||
|  | 
 | ||
|  |   if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) { | ||
|  |     // Privileged Thread mode & PSP
 | ||
|  |     __set_CONTROL(0x02U); | ||
|  |   } else { | ||
|  |     // Unprivileged Thread mode & PSP
 | ||
|  |     __set_CONTROL(0x03U); | ||
|  |   } | ||
|  | 
 | ||
|  |   osRtxInfo.kernel.state = osRtxKernelRunning; | ||
|  | 
 | ||
|  |   EvrRtxKernelStarted(); | ||
|  | 
 | ||
|  |   return osOK; | ||
|  | } | ||
|  | 
 | ||
|  | /// Lock the RTOS Kernel scheduler.
 | ||
|  | /// \note API identical to osKernelLock
 | ||
|  | static int32_t svcRtxKernelLock (void) { | ||
|  |   int32_t lock; | ||
|  | 
 | ||
|  |   switch (osRtxInfo.kernel.state) { | ||
|  |     case osRtxKernelRunning: | ||
|  |       osRtxInfo.kernel.state = osRtxKernelLocked; | ||
|  |       EvrRtxKernelLocked(0); | ||
|  |       lock = 0; | ||
|  |       break; | ||
|  |     case osRtxKernelLocked: | ||
|  |       EvrRtxKernelLocked(1); | ||
|  |       lock = 1; | ||
|  |       break; | ||
|  |     default: | ||
|  |       EvrRtxKernelError((int32_t)osError); | ||
|  |       lock = (int32_t)osError; | ||
|  |       break; | ||
|  |   } | ||
|  |   return lock; | ||
|  | } | ||
|  |   | ||
|  | /// Unlock the RTOS Kernel scheduler.
 | ||
|  | /// \note API identical to osKernelUnlock
 | ||
|  | static int32_t svcRtxKernelUnlock (void) { | ||
|  |   int32_t lock; | ||
|  | 
 | ||
|  |   switch (osRtxInfo.kernel.state) { | ||
|  |     case osRtxKernelRunning: | ||
|  |       EvrRtxKernelUnlocked(0); | ||
|  |       lock = 0; | ||
|  |       break; | ||
|  |     case osRtxKernelLocked: | ||
|  |       osRtxInfo.kernel.state = osRtxKernelRunning; | ||
|  |       EvrRtxKernelUnlocked(1); | ||
|  |       lock = 1; | ||
|  |       break; | ||
|  |     default: | ||
|  |       EvrRtxKernelError((int32_t)osError); | ||
|  |       lock = (int32_t)osError; | ||
|  |       break; | ||
|  |   } | ||
|  |   return lock; | ||
|  | } | ||
|  | 
 | ||
|  | /// Restore the RTOS Kernel scheduler lock state.
 | ||
|  | /// \note API identical to osKernelRestoreLock
 | ||
|  | static int32_t svcRtxKernelRestoreLock (int32_t lock) { | ||
|  |   int32_t lock_new; | ||
|  | 
 | ||
|  |   switch (osRtxInfo.kernel.state) { | ||
|  |     case osRtxKernelRunning: | ||
|  |     case osRtxKernelLocked: | ||
|  |       switch (lock) { | ||
|  |         case 0: | ||
|  |           osRtxInfo.kernel.state = osRtxKernelRunning; | ||
|  |           EvrRtxKernelLockRestored(0); | ||
|  |           lock_new = 0; | ||
|  |           break; | ||
|  |         case 1: | ||
|  |           osRtxInfo.kernel.state = osRtxKernelLocked; | ||
|  |           EvrRtxKernelLockRestored(1); | ||
|  |           lock_new = 1; | ||
|  |           break; | ||
|  |         default: | ||
|  |           EvrRtxKernelError((int32_t)osError); | ||
|  |           lock_new = (int32_t)osError; | ||
|  |           break; | ||
|  |       } | ||
|  |       break; | ||
|  |     default: | ||
|  |       EvrRtxKernelError((int32_t)osError); | ||
|  |       lock_new = (int32_t)osError; | ||
|  |       break; | ||
|  |   } | ||
|  |   return lock_new; | ||
|  | } | ||
|  | 
 | ||
|  | /// Suspend the RTOS Kernel scheduler.
 | ||
|  | /// \note API identical to osKernelSuspend
 | ||
|  | static uint32_t svcRtxKernelSuspend (void) { | ||
|  |   const os_thread_t *thread; | ||
|  |   const os_timer_t  *timer; | ||
|  |   uint32_t           delay; | ||
|  | 
 | ||
|  |   if (osRtxInfo.kernel.state != osRtxKernelRunning) { | ||
|  |     EvrRtxKernelError(osRtxErrorKernelNotRunning); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return 0U; | ||
|  |   } | ||
|  | 
 | ||
|  |   KernelBlock(); | ||
|  | 
 | ||
|  |   delay = osWaitForever; | ||
|  | 
 | ||
|  |   // Check Thread Delay list
 | ||
|  |   thread = osRtxInfo.thread.delay_list; | ||
|  |   if (thread != NULL) { | ||
|  |     delay = thread->delay; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Check Active Timer list
 | ||
|  |   timer = osRtxInfo.timer.list; | ||
|  |   if (timer != NULL) { | ||
|  |     if (timer->tick < delay) { | ||
|  |       delay = timer->tick; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   osRtxInfo.kernel.state = osRtxKernelSuspended; | ||
|  | 
 | ||
|  |   EvrRtxKernelSuspended(delay); | ||
|  | 
 | ||
|  |   return delay; | ||
|  | } | ||
|  | 
 | ||
|  | /// Resume the RTOS Kernel scheduler.
 | ||
|  | /// \note API identical to osKernelResume
 | ||
|  | static void svcRtxKernelResume (uint32_t sleep_ticks) { | ||
|  |   os_thread_t *thread; | ||
|  |   os_timer_t  *timer; | ||
|  |   uint32_t     delay; | ||
|  |   uint32_t     ticks; | ||
|  | 
 | ||
|  |   if (osRtxInfo.kernel.state != osRtxKernelSuspended) { | ||
|  |     EvrRtxKernelResumed(); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return; | ||
|  |   } | ||
|  | 
 | ||
|  |   osRtxInfo.kernel.tick += sleep_ticks; | ||
|  | 
 | ||
|  |   // Process Thread Delay list
 | ||
|  |   thread = osRtxInfo.thread.delay_list; | ||
|  |   if (thread != NULL) { | ||
|  |     delay = sleep_ticks; | ||
|  |     do { | ||
|  |       if (delay >= thread->delay) { | ||
|  |         delay -= thread->delay; | ||
|  |         thread->delay = 1U; | ||
|  |         osRtxThreadDelayTick(); | ||
|  |         thread = osRtxInfo.thread.delay_list; | ||
|  |       } else { | ||
|  |         thread->delay -= delay; | ||
|  |         delay = 0U; | ||
|  |       } | ||
|  |     } while ((thread != NULL) && (delay != 0U)); | ||
|  |   } | ||
|  | 
 | ||
|  |   // Process Active Timer list
 | ||
|  |   timer = osRtxInfo.timer.list; | ||
|  |   if (timer != NULL) { | ||
|  |     ticks = sleep_ticks; | ||
|  |     do { | ||
|  |       if (ticks >= timer->tick) { | ||
|  |         ticks -= timer->tick; | ||
|  |         timer->tick = 1U; | ||
|  |         osRtxInfo.timer.tick(); | ||
|  |         timer = osRtxInfo.timer.list; | ||
|  |       } else { | ||
|  |         timer->tick -= ticks; | ||
|  |         ticks = 0U; | ||
|  |       } | ||
|  |     } while ((timer != NULL) && (ticks != 0U)); | ||
|  |   } | ||
|  | 
 | ||
|  |   osRtxInfo.kernel.state = osRtxKernelRunning; | ||
|  | 
 | ||
|  |   osRtxThreadDispatch(NULL); | ||
|  | 
 | ||
|  |   KernelUnblock(); | ||
|  | 
 | ||
|  |   EvrRtxKernelResumed(); | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the RTOS kernel tick count.
 | ||
|  | /// \note API identical to osKernelGetTickCount
 | ||
|  | static uint32_t svcRtxKernelGetTickCount (void) { | ||
|  |   EvrRtxKernelGetTickCount(osRtxInfo.kernel.tick); | ||
|  |   return osRtxInfo.kernel.tick; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the RTOS kernel tick frequency.
 | ||
|  | /// \note API identical to osKernelGetTickFreq
 | ||
|  | static uint32_t svcRtxKernelGetTickFreq (void) { | ||
|  |   EvrRtxKernelGetTickFreq(osRtxConfig.tick_freq); | ||
|  |   return osRtxConfig.tick_freq; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the RTOS kernel system timer count.
 | ||
|  | /// \note API identical to osKernelGetSysTimerCount
 | ||
|  | static uint32_t svcRtxKernelGetSysTimerCount (void) { | ||
|  |   uint32_t tick; | ||
|  |   uint32_t count; | ||
|  | 
 | ||
|  |   tick  = (uint32_t)osRtxInfo.kernel.tick; | ||
|  |   count = OS_Tick_GetCount(); | ||
|  |   if (OS_Tick_GetOverflow() != 0U) { | ||
|  |     count = OS_Tick_GetCount(); | ||
|  |     tick++; | ||
|  |   } | ||
|  |   count += tick * OS_Tick_GetInterval(); | ||
|  |   EvrRtxKernelGetSysTimerCount(count); | ||
|  |   return count; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the RTOS kernel system timer frequency.
 | ||
|  | /// \note API identical to osKernelGetSysTimerFreq
 | ||
|  | static uint32_t svcRtxKernelGetSysTimerFreq (void) { | ||
|  |   uint32_t freq = OS_Tick_GetClock(); | ||
|  |   EvrRtxKernelGetSysTimerFreq(freq); | ||
|  |   return freq; | ||
|  | } | ||
|  | 
 | ||
|  | //  Service Calls definitions
 | ||
|  | //lint ++flb "Library Begin" [MISRA Note 11]
 | ||
|  | SVC0_0 (KernelInitialize,       osStatus_t) | ||
|  | SVC0_3 (KernelGetInfo,          osStatus_t, osVersion_t *, char *, uint32_t) | ||
|  | SVC0_0 (KernelStart,            osStatus_t) | ||
|  | SVC0_0 (KernelLock,             int32_t) | ||
|  | SVC0_0 (KernelUnlock,           int32_t) | ||
|  | SVC0_1 (KernelRestoreLock,      int32_t, int32_t) | ||
|  | SVC0_0 (KernelSuspend,          uint32_t) | ||
|  | SVC0_1N(KernelResume,           void, uint32_t) | ||
|  | SVC0_0 (KernelGetState,         osKernelState_t) | ||
|  | SVC0_0 (KernelGetTickCount,     uint32_t) | ||
|  | SVC0_0 (KernelGetTickFreq,      uint32_t) | ||
|  | SVC0_0 (KernelGetSysTimerCount, uint32_t) | ||
|  | SVC0_0 (KernelGetSysTimerFreq,  uint32_t) | ||
|  | //lint --flb "Library End"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== Library functions ====
 | ||
|  | 
 | ||
|  | /// RTOS Kernel Pre-Initialization Hook
 | ||
|  | //lint -esym(759,osRtxKernelPreInit) "Prototype in header"
 | ||
|  | //lint -esym(765,osRtxKernelPreInit) "Global scope (can be overridden)"
 | ||
|  | //lint -esym(522,osRtxKernelPreInit) "Can be overridden (do not lack side-effects)"
 | ||
|  | __WEAK void osRtxKernelPreInit (void) { | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== Public API ====
 | ||
|  | 
 | ||
|  | /// Initialize the RTOS Kernel.
 | ||
|  | osStatus_t osKernelInitialize (void) { | ||
|  |   osStatus_t status; | ||
|  | 
 | ||
|  |   osRtxKernelPreInit(); | ||
|  |   EvrRtxKernelInitialize(); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxKernelError((int32_t)osErrorISR); | ||
|  |     status = osErrorISR; | ||
|  |   } else { | ||
|  |     status = __svcKernelInitialize(); | ||
|  |   } | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | ///  Get RTOS Kernel Information.
 | ||
|  | osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { | ||
|  |   osStatus_t status; | ||
|  | 
 | ||
|  |   EvrRtxKernelGetInfo(version, id_buf, id_size); | ||
|  |   if (IsIrqMode() || IsIrqMasked() || IsPrivileged()) { | ||
|  |     status = svcRtxKernelGetInfo(version, id_buf, id_size); | ||
|  |   } else { | ||
|  |     status =  __svcKernelGetInfo(version, id_buf, id_size); | ||
|  |   } | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the current RTOS Kernel state.
 | ||
|  | osKernelState_t osKernelGetState (void) { | ||
|  |   osKernelState_t state; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked() || IsPrivileged()) { | ||
|  |     state = svcRtxKernelGetState(); | ||
|  |   } else { | ||
|  |     state =  __svcKernelGetState(); | ||
|  |   } | ||
|  |   return state; | ||
|  | } | ||
|  | 
 | ||
|  | /// Start the RTOS Kernel scheduler.
 | ||
|  | osStatus_t osKernelStart (void) { | ||
|  |   osStatus_t status; | ||
|  | 
 | ||
|  |   EvrRtxKernelStart(); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxKernelError((int32_t)osErrorISR); | ||
|  |     status = osErrorISR; | ||
|  |   } else { | ||
|  |     status = __svcKernelStart(); | ||
|  |   } | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | /// Lock the RTOS Kernel scheduler.
 | ||
|  | int32_t osKernelLock (void) { | ||
|  |   int32_t lock; | ||
|  | 
 | ||
|  |   EvrRtxKernelLock(); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxKernelError((int32_t)osErrorISR); | ||
|  |     lock = (int32_t)osErrorISR; | ||
|  |   } else { | ||
|  |     lock = __svcKernelLock(); | ||
|  |   } | ||
|  |   return lock; | ||
|  | } | ||
|  |   | ||
|  | /// Unlock the RTOS Kernel scheduler.
 | ||
|  | int32_t osKernelUnlock (void) { | ||
|  |   int32_t lock; | ||
|  | 
 | ||
|  |   EvrRtxKernelUnlock(); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxKernelError((int32_t)osErrorISR); | ||
|  |     lock = (int32_t)osErrorISR; | ||
|  |   } else { | ||
|  |     lock = __svcKernelUnlock(); | ||
|  |   } | ||
|  |   return lock; | ||
|  | } | ||
|  | 
 | ||
|  | /// Restore the RTOS Kernel scheduler lock state.
 | ||
|  | int32_t osKernelRestoreLock (int32_t lock) { | ||
|  |   int32_t lock_new; | ||
|  | 
 | ||
|  |   EvrRtxKernelRestoreLock(lock); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxKernelError((int32_t)osErrorISR); | ||
|  |     lock_new = (int32_t)osErrorISR; | ||
|  |   } else { | ||
|  |     lock_new = __svcKernelRestoreLock(lock); | ||
|  |   } | ||
|  |   return lock_new; | ||
|  | } | ||
|  | 
 | ||
|  | /// Suspend the RTOS Kernel scheduler.
 | ||
|  | uint32_t osKernelSuspend (void) { | ||
|  |   uint32_t ticks; | ||
|  | 
 | ||
|  |   EvrRtxKernelSuspend(); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxKernelError((int32_t)osErrorISR); | ||
|  |     ticks = 0U; | ||
|  |   } else { | ||
|  |     ticks = __svcKernelSuspend(); | ||
|  |   } | ||
|  |   return ticks; | ||
|  | } | ||
|  | 
 | ||
|  | /// Resume the RTOS Kernel scheduler.
 | ||
|  | void osKernelResume (uint32_t sleep_ticks) { | ||
|  | 
 | ||
|  |   EvrRtxKernelResume(sleep_ticks); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxKernelError((int32_t)osErrorISR); | ||
|  |   } else { | ||
|  |     __svcKernelResume(sleep_ticks); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the RTOS kernel tick count.
 | ||
|  | uint32_t osKernelGetTickCount (void) { | ||
|  |   uint32_t count; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     count = svcRtxKernelGetTickCount(); | ||
|  |   } else { | ||
|  |     count =  __svcKernelGetTickCount(); | ||
|  |   } | ||
|  |   return count; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the RTOS kernel tick frequency.
 | ||
|  | uint32_t osKernelGetTickFreq (void) { | ||
|  |   uint32_t freq; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     freq = svcRtxKernelGetTickFreq(); | ||
|  |   } else { | ||
|  |     freq =  __svcKernelGetTickFreq(); | ||
|  |   } | ||
|  |   return freq; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the RTOS kernel system timer count.
 | ||
|  | uint32_t osKernelGetSysTimerCount (void) { | ||
|  |   uint32_t count; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     count = svcRtxKernelGetSysTimerCount(); | ||
|  |   } else { | ||
|  |     count =  __svcKernelGetSysTimerCount(); | ||
|  |   } | ||
|  |   return count; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get the RTOS kernel system timer frequency.
 | ||
|  | uint32_t osKernelGetSysTimerFreq (void) { | ||
|  |   uint32_t freq; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     freq = svcRtxKernelGetSysTimerFreq(); | ||
|  |   } else { | ||
|  |     freq =  __svcKernelGetSysTimerFreq(); | ||
|  |   } | ||
|  |   return freq; | ||
|  | } |