| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- /*
- * Copyright (c) 2013-2023 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: System functions
- *
- * -----------------------------------------------------------------------------
- */
- #include "rtx_lib.h"
- // ==== Helper functions ====
- /// Put Object into ISR Queue.
- /// \param[in] object object.
- /// \return 1 - success, 0 - failure.
- static uint32_t isr_queue_put (os_object_t *object) {
- #if (EXCLUSIVE_ACCESS == 0)
- uint32_t primask = __get_PRIMASK();
- #else
- uint32_t n;
- #endif
- uint16_t max;
- uint32_t ret;
- max = osRtxInfo.isr_queue.max;
- #if (EXCLUSIVE_ACCESS == 0)
- __disable_irq();
- if (osRtxInfo.isr_queue.cnt < max) {
- osRtxInfo.isr_queue.cnt++;
- osRtxInfo.isr_queue.data[osRtxInfo.isr_queue.in] = object;
- if (++osRtxInfo.isr_queue.in == max) {
- osRtxInfo.isr_queue.in = 0U;
- }
- ret = 1U;
- } else {
- ret = 0U;
- }
-
- if (primask == 0U) {
- __enable_irq();
- }
- #else
- if (atomic_inc16_lt(&osRtxInfo.isr_queue.cnt, max) < max) {
- n = atomic_inc16_lim(&osRtxInfo.isr_queue.in, max);
- osRtxInfo.isr_queue.data[n] = object;
- ret = 1U;
- } else {
- ret = 0U;
- }
- #endif
- return ret;
- }
- /// Get Object from ISR Queue.
- /// \return object or NULL.
- static os_object_t *isr_queue_get (void) {
- #if (EXCLUSIVE_ACCESS != 0)
- uint32_t n;
- #endif
- uint16_t max;
- os_object_t *ret;
- max = osRtxInfo.isr_queue.max;
- #if (EXCLUSIVE_ACCESS == 0)
- __disable_irq();
- if (osRtxInfo.isr_queue.cnt != 0U) {
- osRtxInfo.isr_queue.cnt--;
- ret = osRtxObject(osRtxInfo.isr_queue.data[osRtxInfo.isr_queue.out]);
- if (++osRtxInfo.isr_queue.out == max) {
- osRtxInfo.isr_queue.out = 0U;
- }
- } else {
- ret = NULL;
- }
- __enable_irq();
- #else
- if (atomic_dec16_nz(&osRtxInfo.isr_queue.cnt) != 0U) {
- n = atomic_inc16_lim(&osRtxInfo.isr_queue.out, max);
- ret = osRtxObject(osRtxInfo.isr_queue.data[n]);
- } else {
- ret = NULL;
- }
- #endif
- return ret;
- }
- // ==== Library Functions ====
- /// Tick Handler.
- //lint -esym(714,osRtxTick_Handler) "Referenced by Exception handlers"
- //lint -esym(759,osRtxTick_Handler) "Prototype in header"
- //lint -esym(765,osRtxTick_Handler) "Global scope"
- void osRtxTick_Handler (void) {
- os_thread_t *thread;
- OS_Tick_AcknowledgeIRQ();
- osRtxInfo.kernel.tick++;
- // Process Thread Delays
- osRtxThreadDelayTick();
- osRtxThreadDispatch(NULL);
- // Process Timers
- if (osRtxInfo.timer.tick != NULL) {
- osRtxInfo.timer.tick();
- }
- #ifdef RTX_THREAD_WATCHDOG
- // Process Watchdog Timers
- osRtxThreadWatchdogTick();
- #endif
- // Check Round Robin timeout
- if (osRtxInfo.thread.robin.timeout != 0U) {
- thread = osRtxInfo.thread.run.next;
- if (thread != osRtxInfo.thread.robin.thread) {
- osRtxInfo.thread.robin.thread = thread;
- if (thread->delay == 0U) {
- // Reset Round Robin
- thread->delay = osRtxInfo.thread.robin.timeout;
- }
- }
- if (thread->delay != 0U) {
- thread->delay--;
- }
- if (thread->delay == 0U) {
- // Round Robin Timeout
- if (osRtxKernelGetState() == osRtxKernelRunning) {
- thread = osRtxInfo.thread.ready.thread_list;
- if ((thread != NULL) && (thread->priority == osRtxInfo.thread.robin.thread->priority)) {
- osRtxThreadListRemove(thread);
- osRtxThreadReadyPut(osRtxInfo.thread.robin.thread);
- EvrRtxThreadPreempted(osRtxInfo.thread.robin.thread);
- osRtxThreadSwitch(thread);
- osRtxInfo.thread.robin.thread = thread;
- thread->delay = osRtxInfo.thread.robin.timeout;
- }
- }
- }
- }
- }
- /// Pending Service Call Handler.
- //lint -esym(714,osRtxPendSV_Handler) "Referenced by Exception handlers"
- //lint -esym(759,osRtxPendSV_Handler) "Prototype in header"
- //lint -esym(765,osRtxPendSV_Handler) "Global scope"
- void osRtxPendSV_Handler (void) {
- os_object_t *object;
- for (;;) {
- object = isr_queue_get();
- if (object == NULL) {
- break;
- }
- switch (object->id) {
- case osRtxIdThread:
- osRtxInfo.post_process.thread(osRtxThreadObject(object));
- break;
- case osRtxIdEventFlags:
- osRtxInfo.post_process.event_flags(osRtxEventFlagsObject(object));
- break;
- case osRtxIdSemaphore:
- osRtxInfo.post_process.semaphore(osRtxSemaphoreObject(object));
- break;
- case osRtxIdMemoryPool:
- osRtxInfo.post_process.memory_pool(osRtxMemoryPoolObject(object));
- break;
- case osRtxIdMessage:
- osRtxInfo.post_process.message(osRtxMessageObject(object));
- break;
- default:
- // Should never come here
- break;
- }
- }
- osRtxThreadDispatch(NULL);
- }
- /// Register post ISR processing.
- /// \param[in] object generic object.
- void osRtxPostProcess (os_object_t *object) {
- if (isr_queue_put(object) != 0U) {
- if (osRtxInfo.kernel.blocked == 0U) {
- SetPendSV();
- } else {
- osRtxInfo.kernel.pendSV = 1U;
- }
- } else {
- (void)osRtxKernelErrorNotify(osRtxErrorISRQueueOverflow, object);
- }
- }
|