| /* |
| * 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: RTX Library Configuration |
| * |
| * ----------------------------------------------------------------------------- |
| */ |
| |
| #include "cmsis_compiler.h" |
| #include "RTX_Config.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[2 + OS_THREAD_NUM + (OS_THREAD_USER_STACK_SIZE/8)] \ |
| __attribute__((section(".bss.os.thread.stack"))); |
| #endif |
| |
| #endif // (OS_THREAD_OBJ_MEM != 0) |
| |
| |
| // Stack overrun checking |
| #if (OS_STACK_CHECK == 0) |
| // Override library function |
| extern void osRtxThreadStackCheck (void); |
| void osRtxThreadStackCheck (void) {} |
| #endif |
| |
| |
| // 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.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.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) |
| }; |
| |
| #else |
| |
| extern void osRtxTimerThread (void *argument); |
| void osRtxTimerThread (void *argument) { (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[2 + 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[2 + OS_MSGQUEUE_NUM + (OS_MSGQUEUE_DATA_SIZE/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)) |
| |
| // Initial Thread configuration covered also Thread Flags and Generic Wait |
| #if defined(OS_EVR_THREAD_FILTER) |
| #if !defined(OS_EVR_THFLAGS_FILTER) |
| #define OS_EVR_THFLAGS_FILTER OS_EVR_THREAD_FILTER |
| #endif |
| #if !defined(OS_EVR_WAIT_FILTER) |
| #define OS_EVR_WAIT_FILTER OS_EVR_THREAD_FILTER |
| #endif |
| #endif |
| |
| // Migrate initial filter configuration |
| #if defined(OS_EVR_MEMORY_FILTER) |
| #define OS_EVR_MEMORY_LEVEL (((OS_EVR_MEMORY_FILTER & 0x80U) != 0U) ? (OS_EVR_MEMORY_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_KERNEL_FILTER) |
| #define OS_EVR_KERNEL_LEVEL (((OS_EVR_KERNEL_FILTER & 0x80U) != 0U) ? (OS_EVR_KERNEL_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_THREAD_FILTER) |
| #define OS_EVR_THREAD_LEVEL (((OS_EVR_THREAD_FILTER & 0x80U) != 0U) ? (OS_EVR_THREAD_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_WAIT_FILTER) |
| #define OS_EVR_WAIT_LEVEL (((OS_EVR_WAIT_FILTER & 0x80U) != 0U) ? (OS_EVR_WAIT_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_THFLAGS_FILTER) |
| #define OS_EVR_THFLAGS_LEVEL (((OS_EVR_THFLAGS_FILTER & 0x80U) != 0U) ? (OS_EVR_THFLAGS_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_EVFLAGS_FILTER) |
| #define OS_EVR_EVFLAGS_LEVEL (((OS_EVR_EVFLAGS_FILTER & 0x80U) != 0U) ? (OS_EVR_EVFLAGS_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_TIMER_FILTER) |
| #define OS_EVR_TIMER_LEVEL (((OS_EVR_TIMER_FILTER & 0x80U) != 0U) ? (OS_EVR_TIMER_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_MUTEX_FILTER) |
| #define OS_EVR_MUTEX_LEVEL (((OS_EVR_MUTEX_FILTER & 0x80U) != 0U) ? (OS_EVR_MUTEX_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_SEMAPHORE_FILTER) |
| #define OS_EVR_SEMAPHORE_LEVEL (((OS_EVR_SEMAPHORE_FILTER & 0x80U) != 0U) ? (OS_EVR_SEMAPHORE_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_MEMPOOL_FILTER) |
| #define OS_EVR_MEMPOOL_LEVEL (((OS_EVR_MEMPOOL_FILTER & 0x80U) != 0U) ? (OS_EVR_MEMPOOL_FILTER & 0x0FU) : 0U) |
| #endif |
| #if defined(OS_EVR_MSGQUEUE_FILTER) |
| #define OS_EVR_MSGQUEUE_LEVEL (((OS_EVR_MSGQUEUE_FILTER & 0x80U) != 0U) ? (OS_EVR_MSGQUEUE_FILTER & 0x0FU) : 0U) |
| #endif |
| |
| #if defined(RTE_Compiler_EventRecorder) |
| |
| // Event Recorder Initialize |
| __STATIC_INLINE void evr_initialize (void) { |
| |
| (void)EventRecorderInitialize(OS_EVR_LEVEL, (uint32_t)OS_EVR_START); |
| |
| (void)EventRecorderEnable(OS_EVR_MEMORY_LEVEL, EvtRtxMemoryNo, EvtRtxMemoryNo); |
| (void)EventRecorderEnable(OS_EVR_KERNEL_LEVEL, EvtRtxKernelNo, EvtRtxKernelNo); |
| (void)EventRecorderEnable(OS_EVR_THREAD_LEVEL, EvtRtxThreadNo, EvtRtxThreadNo); |
| (void)EventRecorderEnable(OS_EVR_WAIT_LEVEL, EvtRtxWaitNo, EvtRtxWaitNo); |
| (void)EventRecorderEnable(OS_EVR_THFLAGS_LEVEL, EvtRtxThreadFlagsNo, EvtRtxThreadFlagsNo); |
| (void)EventRecorderEnable(OS_EVR_EVFLAGS_LEVEL, EvtRtxEventFlagsNo, EvtRtxEventFlagsNo); |
| (void)EventRecorderEnable(OS_EVR_TIMER_LEVEL, EvtRtxTimerNo, EvtRtxTimerNo); |
| (void)EventRecorderEnable(OS_EVR_MUTEX_LEVEL, EvtRtxMutexNo, EvtRtxMutexNo); |
| (void)EventRecorderEnable(OS_EVR_SEMAPHORE_LEVEL, EvtRtxSemaphoreNo, EvtRtxSemaphoreNo); |
| (void)EventRecorderEnable(OS_EVR_MEMPOOL_LEVEL, EvtRtxMemoryPoolNo, EvtRtxMemoryPoolNo); |
| (void)EventRecorderEnable(OS_EVR_MSGQUEUE_LEVEL, EvtRtxMessageQueueNo, EvtRtxMessageQueueNo); |
| } |
| |
| #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, |
| &os_timer_mq_attr, |
| (uint32_t)OS_TIMER_CB_QUEUE |
| #else |
| 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 uint8_t irqRtxLib; |
| extern const uint8_t *irqRtxLibRef; |
| const uint8_t *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) |
| __asm void os_cb_sections_wrapper (void) { |
| EXTERN ||.bss.os.thread.cb$$Base|| [WEAK] |
| EXTERN ||.bss.os.thread.cb$$Limit|| [WEAK] |
| EXTERN ||.bss.os.timer.cb$$Base|| [WEAK] |
| EXTERN ||.bss.os.timer.cb$$Limit|| [WEAK] |
| EXTERN ||.bss.os.evflags.cb$$Base|| [WEAK] |
| EXTERN ||.bss.os.evflags.cb$$Limit|| [WEAK] |
| EXTERN ||.bss.os.mutex.cb$$Base|| [WEAK] |
| EXTERN ||.bss.os.mutex.cb$$Limit|| [WEAK] |
| EXTERN ||.bss.os.semaphore.cb$$Base|| [WEAK] |
| EXTERN ||.bss.os.semaphore.cb$$Limit|| [WEAK] |
| EXTERN ||.bss.os.mempool.cb$$Base|| [WEAK] |
| EXTERN ||.bss.os.mempool.cb$$Limit|| [WEAK] |
| EXTERN ||.bss.os.msgqueue.cb$$Base|| [WEAK] |
| EXTERN ||.bss.os.msgqueue.cb$$Limit|| [WEAK] |
| |
| AREA ||.rodata||, DATA, READONLY |
| EXPORT os_cb_sections |
| os_cb_sections |
| DCD ||.bss.os.thread.cb$$Base|| |
| DCD ||.bss.os.thread.cb$$Limit|| |
| DCD ||.bss.os.timer.cb$$Base|| |
| DCD ||.bss.os.timer.cb$$Limit|| |
| DCD ||.bss.os.evflags.cb$$Base|| |
| DCD ||.bss.os.evflags.cb$$Limit|| |
| DCD ||.bss.os.mutex.cb$$Base|| |
| DCD ||.bss.os.mutex.cb$$Limit|| |
| DCD ||.bss.os.semaphore.cb$$Base|| |
| DCD ||.bss.os.semaphore.cb$$Limit|| |
| DCD ||.bss.os.mempool.cb$$Base|| |
| DCD ||.bss.os.mempool.cb$$Limit|| |
| DCD ||.bss.os.msgqueue.cb$$Base|| |
| DCD ||.bss.os.msgqueue.cb$$Limit|| |
| |
| AREA ||.emb_text||, CODE |
| }; |
| #endif |
| |
| #if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) |
| //lint -e{19} "Linker symbols" |
| __asm ( |
| ".weakref __os_thread_cb_start__, .bss.os.thread.cb$$Base\n\t" |
| ".weakref __os_thread_cb_end__, .bss.os.thread.cb$$Limit\n\t" |
| ".weakref __os_timer_cb_start__, .bss.os.timer.cb$$Base\n\t" |
| ".weakref __os_timer_cb_end__, .bss.os.timer.cb$$Limit\n\t" |
| ".weakref __os_evflags_cb_start__, .bss.os.evflags.cb$$Base\n\t" |
| ".weakref __os_evflags_cb_end__, .bss.os.evflags.cb$$Limit\n\t" |
| ".weakref __os_mutex_cb_start__, .bss.os.mutex.cb$$Base\n\t" |
| ".weakref __os_mutex_cb_end__, .bss.os.mutex.cb$$Limit\n\t" |
| ".weakref __os_semaphore_cb_start__, .bss.os.semaphore.cb$$Base\n\t" |
| ".weakref __os_semaphore_cb_end__, .bss.os.semaphore.cb$$Limit\n\t" |
| ".weakref __os_mempool_cb_start__, .bss.os.mempool.cb$$Base\n\t" |
| ".weakref __os_mempool_cb_end__, .bss.os.mempool.cb$$Limit\n\t" |
| ".weakref __os_msgqueue_cb_start__, .bss.os.msgqueue.cb$$Base\n\t" |
| ".weakref __os_msgqueue_cb_end__, .bss.os.msgqueue.cb$$Limit\n\t" |
| ); |
| #endif |
| |
| #if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || \ |
| (defined(__GNUC__) && !defined(__CC_ARM)) |
| |
| extern __attribute__((weak)) uint32_t __os_thread_cb_start__; //lint -esym(526,__os_thread_cb_start__) |
| extern __attribute__((weak)) uint32_t __os_thread_cb_end__; //lint -esym(526,__os_thread_cb_end__) |
| extern __attribute__((weak)) uint32_t __os_timer_cb_start__; //lint -esym(526,__os_timer_cb_start__) |
| extern __attribute__((weak)) uint32_t __os_timer_cb_end__; //lint -esym(526,__os_timer_cb_end__) |
| extern __attribute__((weak)) uint32_t __os_evflags_cb_start__; //lint -esym(526,__os_evflags_cb_start__) |
| extern __attribute__((weak)) uint32_t __os_evflags_cb_end__; //lint -esym(526,__os_evflags_cb_end__) |
| extern __attribute__((weak)) uint32_t __os_mutex_cb_start__; //lint -esym(526,__os_mutex_cb_start__) |
| extern __attribute__((weak)) uint32_t __os_mutex_cb_end__; //lint -esym(526,__os_mutex_cb_end__) |
| extern __attribute__((weak)) uint32_t __os_semaphore_cb_start__; //lint -esym(526,__os_semaphore_cb_start__) |
| extern __attribute__((weak)) uint32_t __os_semaphore_cb_end__; //lint -esym(526,__os_semaphore_cb_end__) |
| extern __attribute__((weak)) uint32_t __os_mempool_cb_start__; //lint -esym(526,__os_mempool_cb_start__) |
| extern __attribute__((weak)) uint32_t __os_mempool_cb_end__; //lint -esym(526,__os_mempool_cb_end__) |
| extern __attribute__((weak)) uint32_t __os_msgqueue_cb_start__; //lint -esym(526,__os_msgqueue_cb_start__) |
| extern __attribute__((weak)) uint32_t __os_msgqueue_cb_end__; //lint -esym(526,__os_msgqueue_cb_end__) |
| |
| //lint -e{19} "Global symbol" |
| __asm (".global os_cb_sections"); |
| |
| //lint -e{9067} "extern array declared without size" |
| extern const uint32_t os_cb_sections[]; |
| |
| //lint -esym(714,os_cb_sections) "Referenced by debugger" |
| //lint -esym(765,os_cb_sections) "Global scope" |
| //lint -e{923} -e{9078} "cast from pointer to unsigned int" |
| const uint32_t os_cb_sections[] \ |
| __attribute__((section(".rodata"))) = |
| { |
| (uint32_t)&__os_thread_cb_start__, |
| (uint32_t)&__os_thread_cb_end__, |
| (uint32_t)&__os_timer_cb_start__, |
| (uint32_t)&__os_timer_cb_end__, |
| (uint32_t)&__os_evflags_cb_start__, |
| (uint32_t)&__os_evflags_cb_end__, |
| (uint32_t)&__os_mutex_cb_start__, |
| (uint32_t)&__os_mutex_cb_end__, |
| (uint32_t)&__os_semaphore_cb_start__, |
| (uint32_t)&__os_semaphore_cb_end__, |
| (uint32_t)&__os_mempool_cb_start__, |
| (uint32_t)&__os_mempool_cb_end__, |
| (uint32_t)&__os_msgqueue_cb_start__, |
| (uint32_t)&__os_msgqueue_cb_end__ |
| }; |
| |
| #endif |
| |
| |
| // 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(); |
| } |
| |
| #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)osRtxErrorNotify(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)osRtxErrorNotify(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 |