/* * Copyright (c) 2013-2021 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: RTX Library Configuration * * ----------------------------------------------------------------------------- */ #include "cmsis_compiler.h" #include "rtx_os.h" #ifdef RTE_Compiler_EventRecorder #include "EventRecorder.h" #include "EventRecorderConf.h" #endif #include "rtx_evr.h" // System Configuration // ==================== // Dynamic Memory #if (OS_DYNAMIC_MEM_SIZE != 0) #if ((OS_DYNAMIC_MEM_SIZE % 8) != 0) #error "Invalid Dynamic Memory size!" #endif static uint64_t os_mem[OS_DYNAMIC_MEM_SIZE/8] \ __attribute__((section(".bss.os"))); #endif // Kernel Tick Frequency #if (OS_TICK_FREQ < 1) #error "Invalid Kernel Tick Frequency!" #endif // ISR FIFO Queue #if (OS_ISR_FIFO_QUEUE < 4) #error "Invalid ISR FIFO Queue size!" #endif static void *os_isr_queue[OS_ISR_FIFO_QUEUE] \ __attribute__((section(".bss.os"))); // Thread Configuration // ==================== #if (((OS_STACK_SIZE % 8) != 0) || (OS_STACK_SIZE < 72)) #error "Invalid default Thread Stack size!" #endif #if (((OS_IDLE_THREAD_STACK_SIZE % 8) != 0) || (OS_IDLE_THREAD_STACK_SIZE < 72)) #error "Invalid Idle Thread Stack size!" #endif #if (OS_THREAD_OBJ_MEM != 0) #if (OS_THREAD_NUM == 0) #error "Invalid number of user Threads!" #endif #if ((OS_THREAD_USER_STACK_SIZE != 0) && ((OS_THREAD_USER_STACK_SIZE % 8) != 0)) #error "Invalid total Stack size!" #endif // Thread Control Blocks static osRtxThread_t os_thread_cb[OS_THREAD_NUM] \ __attribute__((section(".bss.os.thread.cb"))); // Thread Default Stack #if (OS_THREAD_DEF_STACK_NUM != 0) static uint64_t os_thread_def_stack[(OS_THREAD_DEF_STACK_NUM*OS_STACK_SIZE)/8] \ __attribute__((section(".bss.os.thread.stack"))); #endif // Memory Pool for Thread Control Blocks static osRtxMpInfo_t os_mpi_thread \ __attribute__((section(".data.os.thread.mpi"))) = { (uint32_t)OS_THREAD_NUM, 0U, (uint32_t)osRtxThreadCbSize, &os_thread_cb[0], NULL, NULL }; // Memory Pool for Thread Default Stack #if (OS_THREAD_DEF_STACK_NUM != 0) static osRtxMpInfo_t os_mpi_def_stack \ __attribute__((section(".data.os.thread.mpi"))) = { (uint32_t)OS_THREAD_DEF_STACK_NUM, 0U, (uint32_t)OS_STACK_SIZE, &os_thread_def_stack[0], NULL, NULL }; #endif // Memory Pool for Thread Stack #if (OS_THREAD_USER_STACK_SIZE != 0) static uint64_t os_thread_stack[(16 + (8*OS_THREAD_NUM) + OS_THREAD_USER_STACK_SIZE)/8] \ __attribute__((section(".bss.os.thread.stack"))); #endif #endif // (OS_THREAD_OBJ_MEM != 0) // Idle Thread Control Block static osRtxThread_t os_idle_thread_cb \ __attribute__((section(".bss.os.thread.cb"))); // Idle Thread Stack static uint64_t os_idle_thread_stack[OS_IDLE_THREAD_STACK_SIZE/8] \ __attribute__((section(".bss.os.thread.idle.stack"))); // Idle Thread Attributes static const osThreadAttr_t os_idle_thread_attr = { #if defined(OS_IDLE_THREAD_NAME) OS_IDLE_THREAD_NAME, #else NULL, #endif osThreadDetached, &os_idle_thread_cb, (uint32_t)sizeof(os_idle_thread_cb), &os_idle_thread_stack[0], (uint32_t)sizeof(os_idle_thread_stack), osPriorityIdle, #if defined(OS_IDLE_THREAD_TZ_MOD_ID) (uint32_t)OS_IDLE_THREAD_TZ_MOD_ID, #else 0U, #endif 0U }; // Timer Configuration // =================== #if (OS_TIMER_OBJ_MEM != 0) #if (OS_TIMER_NUM == 0) #error "Invalid number of Timer objects!" #endif // Timer Control Blocks static osRtxTimer_t os_timer_cb[OS_TIMER_NUM] \ __attribute__((section(".bss.os.timer.cb"))); // Memory Pool for Timer Control Blocks static osRtxMpInfo_t os_mpi_timer \ __attribute__((section(".data.os.timer.mpi"))) = { (uint32_t)OS_TIMER_NUM, 0U, (uint32_t)osRtxTimerCbSize, &os_timer_cb[0], NULL, NULL }; #endif // (OS_TIMER_OBJ_MEM != 0) #if ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) #if (((OS_TIMER_THREAD_STACK_SIZE % 8) != 0) || (OS_TIMER_THREAD_STACK_SIZE < 96)) #error "Invalid Timer Thread Stack size!" #endif // Timer Thread Control Block static osRtxThread_t os_timer_thread_cb \ __attribute__((section(".bss.os.thread.cb"))); // Timer Thread Stack static uint64_t os_timer_thread_stack[OS_TIMER_THREAD_STACK_SIZE/8] \ __attribute__((section(".bss.os.thread.timer.stack"))); // Timer Thread Attributes static const osThreadAttr_t os_timer_thread_attr = { #if defined(OS_TIMER_THREAD_NAME) OS_TIMER_THREAD_NAME, #else NULL, #endif osThreadDetached, &os_timer_thread_cb, (uint32_t)sizeof(os_timer_thread_cb), &os_timer_thread_stack[0], (uint32_t)sizeof(os_timer_thread_stack), //lint -e{9030} -e{9034} "cast from signed to enum" (osPriority_t)OS_TIMER_THREAD_PRIO, #if defined(OS_TIMER_THREAD_TZ_MOD_ID) (uint32_t)OS_TIMER_THREAD_TZ_MOD_ID, #else 0U, #endif 0U }; // Timer Message Queue Control Block static osRtxMessageQueue_t os_timer_mq_cb \ __attribute__((section(".bss.os.msgqueue.cb"))); // Timer Message Queue Data static uint32_t os_timer_mq_data[osRtxMessageQueueMemSize(OS_TIMER_CB_QUEUE,8)/4] \ __attribute__((section(".bss.os.msgqueue.mem"))); // Timer Message Queue Attributes static const osMessageQueueAttr_t os_timer_mq_attr = { NULL, 0U, &os_timer_mq_cb, (uint32_t)sizeof(os_timer_mq_cb), &os_timer_mq_data[0], (uint32_t)sizeof(os_timer_mq_data) }; extern int32_t osRtxTimerSetup (void); extern void osRtxTimerThread (void *argument); #endif // ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) // Event Flags Configuration // ========================= #if (OS_EVFLAGS_OBJ_MEM != 0) #if (OS_EVFLAGS_NUM == 0) #error "Invalid number of Event Flags objects!" #endif // Event Flags Control Blocks static osRtxEventFlags_t os_ef_cb[OS_EVFLAGS_NUM] \ __attribute__((section(".bss.os.evflags.cb"))); // Memory Pool for Event Flags Control Blocks static osRtxMpInfo_t os_mpi_ef \ __attribute__((section(".data.os.evflags.mpi"))) = { (uint32_t)OS_EVFLAGS_NUM, 0U, (uint32_t)osRtxEventFlagsCbSize, &os_ef_cb[0], NULL, NULL }; #endif // (OS_EVFLAGS_OBJ_MEM != 0) // Mutex Configuration // =================== #if (OS_MUTEX_OBJ_MEM != 0) #if (OS_MUTEX_NUM == 0) #error "Invalid number of Mutex objects!" #endif // Mutex Control Blocks static osRtxMutex_t os_mutex_cb[OS_MUTEX_NUM] \ __attribute__((section(".bss.os.mutex.cb"))); // Memory Pool for Mutex Control Blocks static osRtxMpInfo_t os_mpi_mutex \ __attribute__((section(".data.os.mutex.mpi"))) = { (uint32_t)OS_MUTEX_NUM, 0U, (uint32_t)osRtxMutexCbSize, &os_mutex_cb[0], NULL, NULL }; #endif // (OS_MUTEX_OBJ_MEM != 0) // Semaphore Configuration // ======================= #if (OS_SEMAPHORE_OBJ_MEM != 0) #if (OS_SEMAPHORE_NUM == 0) #error "Invalid number of Semaphore objects!" #endif // Semaphore Control Blocks static osRtxSemaphore_t os_semaphore_cb[OS_SEMAPHORE_NUM] \ __attribute__((section(".bss.os.semaphore.cb"))); // Memory Pool for Semaphore Control Blocks static osRtxMpInfo_t os_mpi_semaphore \ __attribute__((section(".data.os.semaphore.mpi"))) = { (uint32_t)OS_SEMAPHORE_NUM, 0U, (uint32_t)osRtxSemaphoreCbSize, &os_semaphore_cb[0], NULL, NULL }; #endif // (OS_SEMAPHORE_OBJ_MEM != 0) // Memory Pool Configuration // ========================= #if (OS_MEMPOOL_OBJ_MEM != 0) #if (OS_MEMPOOL_NUM == 0) #error "Invalid number of Memory Pool objects!" #endif // Memory Pool Control Blocks static osRtxMemoryPool_t os_mp_cb[OS_MEMPOOL_NUM] \ __attribute__((section(".bss.os.mempool.cb"))); // Memory Pool for Memory Pool Control Blocks static osRtxMpInfo_t os_mpi_mp \ __attribute__((section(".data.os.mempool.mpi"))) = { (uint32_t)OS_MEMPOOL_NUM, 0U, (uint32_t)osRtxMemoryPoolCbSize, &os_mp_cb[0], NULL, NULL }; // Memory Pool for Memory Pool Data Storage #if (OS_MEMPOOL_DATA_SIZE != 0) #if ((OS_MEMPOOL_DATA_SIZE % 8) != 0) #error "Invalid Data Memory size for Memory Pools!" #endif static uint64_t os_mp_data[(16 + (8*OS_MEMPOOL_NUM) + OS_MEMPOOL_DATA_SIZE)/8] \ __attribute__((section(".bss.os.mempool.mem"))); #endif #endif // (OS_MEMPOOL_OBJ_MEM != 0) // Message Queue Configuration // =========================== #if (OS_MSGQUEUE_OBJ_MEM != 0) #if (OS_MSGQUEUE_NUM == 0) #error "Invalid number of Message Queue objects!" #endif // Message Queue Control Blocks static osRtxMessageQueue_t os_mq_cb[OS_MSGQUEUE_NUM] \ __attribute__((section(".bss.os.msgqueue.cb"))); // Memory Pool for Message Queue Control Blocks static osRtxMpInfo_t os_mpi_mq \ __attribute__((section(".data.os.msgqueue.mpi"))) = { (uint32_t)OS_MSGQUEUE_NUM, 0U, (uint32_t)osRtxMessageQueueCbSize, &os_mq_cb[0], NULL, NULL }; // Memory Pool for Message Queue Data Storage #if (OS_MSGQUEUE_DATA_SIZE != 0) #if ((OS_MSGQUEUE_DATA_SIZE % 8) != 0) #error "Invalid Data Memory size for Message Queues!" #endif static uint64_t os_mq_data[(16 + ((8+12)*OS_MSGQUEUE_NUM) + OS_MSGQUEUE_DATA_SIZE + 7)/8] \ __attribute__((section(".bss.os.msgqueue.mem"))); #endif #endif // (OS_MSGQUEUE_OBJ_MEM != 0) // Event Recorder Configuration // ============================ #if (defined(OS_EVR_INIT) && (OS_EVR_INIT != 0)) #ifdef RTE_Compiler_EventRecorder // Event Recorder Initialize __STATIC_INLINE void evr_initialize (void) { (void)EventRecorderInitialize(OS_EVR_LEVEL, (uint32_t)OS_EVR_START); #if ((OS_EVR_MEMORY_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_MEMORY_LEVEL & 0x0FU, EvtRtxMemoryNo, EvtRtxMemoryNo); (void)EventRecorderDisable(~OS_EVR_MEMORY_LEVEL & 0x0FU, EvtRtxMemoryNo, EvtRtxMemoryNo); #endif #if ((OS_EVR_KERNEL_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_KERNEL_LEVEL & 0x0FU, EvtRtxKernelNo, EvtRtxKernelNo); (void)EventRecorderDisable(~OS_EVR_KERNEL_LEVEL & 0x0FU, EvtRtxKernelNo, EvtRtxMemoryNo); #endif #if ((OS_EVR_THREAD_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_THREAD_LEVEL & 0x0FU, EvtRtxThreadNo, EvtRtxThreadNo); (void)EventRecorderDisable(~OS_EVR_THREAD_LEVEL & 0x0FU, EvtRtxThreadNo, EvtRtxThreadNo); #endif #if ((OS_EVR_WAIT_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_WAIT_LEVEL & 0x0FU, EvtRtxWaitNo, EvtRtxWaitNo); (void)EventRecorderDisable(~OS_EVR_WAIT_LEVEL & 0x0FU, EvtRtxWaitNo, EvtRtxWaitNo); #endif #if ((OS_EVR_THFLAGS_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_THFLAGS_LEVEL & 0x0FU, EvtRtxThreadFlagsNo, EvtRtxThreadFlagsNo); (void)EventRecorderDisable(~OS_EVR_THFLAGS_LEVEL & 0x0FU, EvtRtxThreadFlagsNo, EvtRtxThreadFlagsNo); #endif #if ((OS_EVR_EVFLAGS_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_EVFLAGS_LEVEL & 0x0FU, EvtRtxEventFlagsNo, EvtRtxEventFlagsNo); (void)EventRecorderDisable(~OS_EVR_EVFLAGS_LEVEL & 0x0FU, EvtRtxEventFlagsNo, EvtRtxEventFlagsNo); #endif #if ((OS_EVR_TIMER_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_TIMER_LEVEL & 0x0FU, EvtRtxTimerNo, EvtRtxTimerNo); (void)EventRecorderDisable(~OS_EVR_TIMER_LEVEL & 0x0FU, EvtRtxTimerNo, EvtRtxTimerNo); #endif #if ((OS_EVR_MUTEX_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_MUTEX_LEVEL & 0x0FU, EvtRtxMutexNo, EvtRtxMutexNo); (void)EventRecorderDisable(~OS_EVR_MUTEX_LEVEL & 0x0FU, EvtRtxMutexNo, EvtRtxMutexNo); #endif #if ((OS_EVR_SEMAPHORE_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_SEMAPHORE_LEVEL & 0x0FU, EvtRtxSemaphoreNo, EvtRtxSemaphoreNo); (void)EventRecorderDisable(~OS_EVR_SEMAPHORE_LEVEL & 0x0FU, EvtRtxSemaphoreNo, EvtRtxSemaphoreNo); #endif #if ((OS_EVR_MEMPOOL_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_MEMPOOL_LEVEL & 0x0FU, EvtRtxMemoryPoolNo, EvtRtxMemoryPoolNo); (void)EventRecorderDisable(~OS_EVR_MEMPOOL_LEVEL & 0x0FU, EvtRtxMemoryPoolNo, EvtRtxMemoryPoolNo); #endif #if ((OS_EVR_MSGQUEUE_LEVEL & 0x80U) != 0U) (void)EventRecorderEnable( OS_EVR_MSGQUEUE_LEVEL & 0x0FU, EvtRtxMessageQueueNo, EvtRtxMessageQueueNo); (void)EventRecorderDisable(~OS_EVR_MSGQUEUE_LEVEL & 0x0FU, EvtRtxMessageQueueNo, EvtRtxMessageQueueNo); #endif } #else #warning "Event Recorder cannot be initialized (Event Recorder component is not selected)!" #define evr_initialize() #endif #endif // (OS_EVR_INIT != 0) // OS Configuration // ================ const osRtxConfig_t osRtxConfig \ __USED \ __attribute__((section(".rodata"))) = { //lint -e{835} "Zero argument to operator" 0U // Flags #if (OS_PRIVILEGE_MODE != 0) | osRtxConfigPrivilegedMode #endif #if (OS_STACK_CHECK != 0) | osRtxConfigStackCheck #endif #if (OS_STACK_WATERMARK != 0) | osRtxConfigStackWatermark #endif , (uint32_t)OS_TICK_FREQ, #if (OS_ROBIN_ENABLE != 0) (uint32_t)OS_ROBIN_TIMEOUT, #else 0U, #endif { &os_isr_queue[0], (uint16_t)(sizeof(os_isr_queue)/sizeof(void *)), 0U }, { // Memory Pools (Variable Block Size) #if ((OS_THREAD_OBJ_MEM != 0) && (OS_THREAD_USER_STACK_SIZE != 0)) &os_thread_stack[0], sizeof(os_thread_stack), #else NULL, 0U, #endif #if ((OS_MEMPOOL_OBJ_MEM != 0) && (OS_MEMPOOL_DATA_SIZE != 0)) &os_mp_data[0], sizeof(os_mp_data), #else NULL, 0U, #endif #if ((OS_MSGQUEUE_OBJ_MEM != 0) && (OS_MSGQUEUE_DATA_SIZE != 0)) &os_mq_data[0], sizeof(os_mq_data), #else NULL, 0U, #endif #if (OS_DYNAMIC_MEM_SIZE != 0) &os_mem[0], (uint32_t)OS_DYNAMIC_MEM_SIZE, #else NULL, 0U #endif }, { // Memory Pools (Fixed Block Size) #if (OS_THREAD_OBJ_MEM != 0) #if (OS_THREAD_DEF_STACK_NUM != 0) &os_mpi_def_stack, #else NULL, #endif &os_mpi_thread, #else NULL, NULL, #endif #if (OS_TIMER_OBJ_MEM != 0) &os_mpi_timer, #else NULL, #endif #if (OS_EVFLAGS_OBJ_MEM != 0) &os_mpi_ef, #else NULL, #endif #if (OS_MUTEX_OBJ_MEM != 0) &os_mpi_mutex, #else NULL, #endif #if (OS_SEMAPHORE_OBJ_MEM != 0) &os_mpi_semaphore, #else NULL, #endif #if (OS_MEMPOOL_OBJ_MEM != 0) &os_mpi_mp, #else NULL, #endif #if (OS_MSGQUEUE_OBJ_MEM != 0) &os_mpi_mq, #else NULL, #endif }, (uint32_t)OS_STACK_SIZE, &os_idle_thread_attr, #if ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) &os_timer_thread_attr, osRtxTimerThread, osRtxTimerSetup, &os_timer_mq_attr, (uint32_t)OS_TIMER_CB_QUEUE #else NULL, NULL, NULL, NULL, 0U #endif }; // Non weak reference to library irq module //lint -esym(526,irqRtxLib) "Defined by Exception handlers" //lint -esym(714,irqRtxLibRef) "Non weak reference" //lint -esym(765,irqRtxLibRef) "Global scope" extern const uint8_t irqRtxLib; extern const uint8_t * const irqRtxLibRef; const uint8_t * const irqRtxLibRef = &irqRtxLib; // Default User SVC Table //lint -esym(714,osRtxUserSVC) "Referenced by Exception handlers" //lint -esym(765,osRtxUserSVC) "Global scope" //lint -e{9067} "extern array declared without size" extern void * const osRtxUserSVC[]; __WEAK void * const osRtxUserSVC[1] = { (void *)0 }; // OS Sections // =========== #if defined(__CC_ARM) || \ (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) // Initialized through linker //lint -esym(728, __os_thread_cb_start__, __os_thread_cb_end__) //lint -esym(728, __os_timer_cb_start__, __os_timer_cb_end__) //lint -esym(728, __os_evflags_cb_start__, __os_evflags_cb_end__) //lint -esym(728, __os_mutex_cb_start__, __os_mutex_cb_end__) //lint -esym(728, __os_semaphore_cb_start__, __os_semaphore_cb_end__) //lint -esym(728, __os_mempool_cb_start__, __os_mempool_cb_end__) //lint -esym(728, __os_msgqueue_cb_start__, __os_msgqueue_cb_end__) static const uint32_t __os_thread_cb_start__ __attribute__((weakref(".bss.os.thread.cb$$Base"))); static const uint32_t __os_thread_cb_end__ __attribute__((weakref(".bss.os.thread.cb$$Limit"))); static const uint32_t __os_timer_cb_start__ __attribute__((weakref(".bss.os.timer.cb$$Base"))); static const uint32_t __os_timer_cb_end__ __attribute__((weakref(".bss.os.timer.cb$$Limit"))); static const uint32_t __os_evflags_cb_start__ __attribute__((weakref(".bss.os.evflags.cb$$Base"))); static const uint32_t __os_evflags_cb_end__ __attribute__((weakref(".bss.os.evflags.cb$$Limit"))); static const uint32_t __os_mutex_cb_start__ __attribute__((weakref(".bss.os.mutex.cb$$Base"))); static const uint32_t __os_mutex_cb_end__ __attribute__((weakref(".bss.os.mutex.cb$$Limit"))); static const uint32_t __os_semaphore_cb_start__ __attribute__((weakref(".bss.os.semaphore.cb$$Base"))); static const uint32_t __os_semaphore_cb_end__ __attribute__((weakref(".bss.os.semaphore.cb$$Limit"))); static const uint32_t __os_mempool_cb_start__ __attribute__((weakref(".bss.os.mempool.cb$$Base"))); static const uint32_t __os_mempool_cb_end__ __attribute__((weakref(".bss.os.mempool.cb$$Limit"))); static const uint32_t __os_msgqueue_cb_start__ __attribute__((weakref(".bss.os.msgqueue.cb$$Base"))); static const uint32_t __os_msgqueue_cb_end__ __attribute__((weakref(".bss.os.msgqueue.cb$$Limit"))); #else extern const uint32_t __os_thread_cb_start__ __attribute__((weak)); extern const uint32_t __os_thread_cb_end__ __attribute__((weak)); extern const uint32_t __os_timer_cb_start__ __attribute__((weak)); extern const uint32_t __os_timer_cb_end__ __attribute__((weak)); extern const uint32_t __os_evflags_cb_start__ __attribute__((weak)); extern const uint32_t __os_evflags_cb_end__ __attribute__((weak)); extern const uint32_t __os_mutex_cb_start__ __attribute__((weak)); extern const uint32_t __os_mutex_cb_end__ __attribute__((weak)); extern const uint32_t __os_semaphore_cb_start__ __attribute__((weak)); extern const uint32_t __os_semaphore_cb_end__ __attribute__((weak)); extern const uint32_t __os_mempool_cb_start__ __attribute__((weak)); extern const uint32_t __os_mempool_cb_end__ __attribute__((weak)); extern const uint32_t __os_msgqueue_cb_start__ __attribute__((weak)); extern const uint32_t __os_msgqueue_cb_end__ __attribute__((weak)); #endif //lint -e{9067} "extern array declared without size" extern const uint32_t * const os_cb_sections[]; //lint -esym(714,os_cb_sections) "Referenced by debugger" //lint -esym(765,os_cb_sections) "Global scope" const uint32_t * const os_cb_sections[] \ __USED \ __attribute__((section(".rodata"))) = { &__os_thread_cb_start__, &__os_thread_cb_end__, &__os_timer_cb_start__, &__os_timer_cb_end__, &__os_evflags_cb_start__, &__os_evflags_cb_end__, &__os_mutex_cb_start__, &__os_mutex_cb_end__, &__os_semaphore_cb_start__, &__os_semaphore_cb_end__, &__os_mempool_cb_start__, &__os_mempool_cb_end__, &__os_msgqueue_cb_start__, &__os_msgqueue_cb_end__ }; // OS Initialization // ================= #if defined(__CC_ARM) || \ (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) #ifndef __MICROLIB //lint -esym(714,_platform_post_stackheap_init) "Referenced by C library" //lint -esym(765,_platform_post_stackheap_init) "Global scope" extern void _platform_post_stackheap_init (void); __WEAK void _platform_post_stackheap_init (void) { (void)osKernelInitialize(); } #endif #elif defined(__GNUC__) extern void software_init_hook (void); __WEAK void software_init_hook (void) { (void)osKernelInitialize(); } #elif defined(__ICCARM__) extern void $Super$$__iar_data_init3 (void); void $Sub$$__iar_data_init3 (void) { $Super$$__iar_data_init3(); (void)osKernelInitialize(); } #endif // OS Hooks // ======== // RTOS Kernel Pre-Initialization Hook #if (defined(OS_EVR_INIT) && (OS_EVR_INIT != 0)) void osRtxKernelPreInit (void); void osRtxKernelPreInit (void) { if (osKernelGetState() == osKernelInactive) { evr_initialize(); } } #endif // C/C++ Standard Library Multithreading Interface // =============================================== #if ( !defined(RTX_NO_MULTITHREAD_CLIB) && \ ( defined(__CC_ARM) || \ (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \ !defined(__MICROLIB)) #define LIBSPACE_SIZE 96 //lint -esym(714,__user_perthread_libspace,_mutex_*) "Referenced by C library" //lint -esym(765,__user_perthread_libspace,_mutex_*) "Global scope" //lint -esym(9003, os_libspace*) "variables 'os_libspace*' defined at module scope" // Memory for libspace static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/4] \ __attribute__((section(".bss.os.libspace"))); // Thread IDs for libspace static osThreadId_t os_libspace_id[OS_THREAD_LIBSPACE_NUM] \ __attribute__((section(".bss.os.libspace"))); // Check if Kernel has been started static uint32_t os_kernel_is_active (void) { static uint8_t os_kernel_active = 0U; if (os_kernel_active == 0U) { if (osKernelGetState() > osKernelReady) { os_kernel_active = 1U; } } return (uint32_t)os_kernel_active; } // Provide libspace for current thread void *__user_perthread_libspace (void); void *__user_perthread_libspace (void) { osThreadId_t id; uint32_t n; if (os_kernel_is_active() != 0U) { id = osThreadGetId(); for (n = 0U; n < (uint32_t)OS_THREAD_LIBSPACE_NUM; n++) { if (os_libspace_id[n] == NULL) { os_libspace_id[n] = id; } if (os_libspace_id[n] == id) { break; } } if (n == (uint32_t)OS_THREAD_LIBSPACE_NUM) { (void)osRtxKernelErrorNotify(osRtxErrorClibSpace, id); } } else { n = OS_THREAD_LIBSPACE_NUM; } //lint -e{9087} "cast between pointers to different object types" return (void *)&os_libspace[n][0]; } // Mutex identifier typedef void *mutex; //lint -save "Function prototypes defined in C library" //lint -e970 "Use of 'int' outside of a typedef" //lint -e818 "Pointer 'm' could be declared as pointing to const" // Initialize mutex __USED int _mutex_initialize(mutex *m); int _mutex_initialize(mutex *m) { int result; *m = osMutexNew(NULL); if (*m != NULL) { result = 1; } else { result = 0; (void)osRtxKernelErrorNotify(osRtxErrorClibMutex, m); } return result; } // Acquire mutex __USED void _mutex_acquire(mutex *m); void _mutex_acquire(mutex *m) { if (os_kernel_is_active() != 0U) { (void)osMutexAcquire(*m, osWaitForever); } } // Release mutex __USED void _mutex_release(mutex *m); void _mutex_release(mutex *m) { if (os_kernel_is_active() != 0U) { (void)osMutexRelease(*m); } } // Free mutex __USED void _mutex_free(mutex *m); void _mutex_free(mutex *m) { (void)osMutexDelete(*m); } //lint -restore #endif