| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696 |
- /*
- * Copyright (c) 2013-2016 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
- *
- * http://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: Cortex-M Core definitions
- *
- * -----------------------------------------------------------------------------
- */
- #ifndef CORE_CM_H_
- #define CORE_CM_H_
- #include "RTE_Components.h"
- #include CMSIS_device_header
- #ifndef __ARM_ARCH_6M__
- #define __ARM_ARCH_6M__ 0U
- #endif
- #ifndef __ARM_ARCH_7M__
- #define __ARM_ARCH_7M__ 0U
- #endif
- #ifndef __ARM_ARCH_7EM__
- #define __ARM_ARCH_7EM__ 0U
- #endif
- #ifndef __ARM_ARCH_8M_BASE__
- #define __ARM_ARCH_8M_BASE__ 0U
- #endif
- #ifndef __ARM_ARCH_8M_MAIN__
- #define __ARM_ARCH_8M_MAIN__ 0U
- #endif
- #if ((__ARM_ARCH_6M__ + \
- __ARM_ARCH_7M__ + \
- __ARM_ARCH_7EM__ + \
- __ARM_ARCH_8M_BASE__ + \
- __ARM_ARCH_8M_MAIN__) != 1U)
- #error "Unknown ARM Architecture!"
- #endif
- #ifdef RTE_CMSIS_RTOS2_RTX5_ARMV8M_NS
- #define __DOMAIN_NS 1U
- #endif
- #ifndef __DOMAIN_NS
- #define __DOMAIN_NS 0U
- #elif ((__DOMAIN_NS == 1U) && \
- ((__ARM_ARCH_6M__ == 1U) || \
- (__ARM_ARCH_7M__ == 1U) || \
- (__ARM_ARCH_7EM__ == 1U)))
- #error "Non-secure domain requires ARMv8-M Architecture!"
- #endif
- #ifndef __EXCLUSIVE_ACCESS
- #if ((__ARM_ARCH_7M__ == 1U) || \
- (__ARM_ARCH_7EM__ == 1U) || \
- (__ARM_ARCH_8M_BASE__ == 1U) || \
- (__ARM_ARCH_8M_MAIN__ == 1U))
- #define __EXCLUSIVE_ACCESS 1U
- #else
- #define __EXCLUSIVE_ACCESS 0U
- #endif
- #endif
- #define IS_PRIVILEGED() ((__get_CONTROL() & 1U) == 0U)
- #define IS_IRQ_MODE() (__get_IPSR() != 0U)
- #if ((__ARM_ARCH_7M__ == 1U) || \
- (__ARM_ARCH_7EM__ == 1U) || \
- (__ARM_ARCH_8M_MAIN__ == 1U))
- #define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U))
- #else
- #define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
- #endif
- #define XPSR_INITIAL_VALUE 0x01000000U
- #if (__DOMAIN_NS == 1U)
- #define STACK_FRAME_INIT 0xBCU
- #else
- #define STACK_FRAME_INIT 0xFDU
- #endif
- #define IS_EXTENDED_STACK_FRAME(n) (((n) & 0x10U) == 0U)
- // ==== Service Calls definitions ====
- #if ((__ARM_ARCH_7M__ == 1U) || \
- (__ARM_ARCH_7EM__ == 1U) || \
- (__ARM_ARCH_8M_MAIN__ == 1U))
- #define SVC_RegF "r12"
- #elif ((__ARM_ARCH_6M__ == 1U) || \
- (__ARM_ARCH_8M_BASE__ == 1U))
- #define SVC_RegF "r7"
- #endif
- #define SVC_ArgN(n) \
- register uint32_t __r##n __ASM("r"#n)
- #define SVC_ArgR(n,a) \
- register uint32_t __r##n __ASM("r"#n) = (uint32_t)a
- #define SVC_ArgF(f) \
- register uint32_t __rf __ASM(SVC_RegF) = (uint32_t)f
- #define SVC_In0 "r"(__rf)
- #define SVC_In1 "r"(__rf),"r"(__r0)
- #define SVC_In2 "r"(__rf),"r"(__r0),"r"(__r1)
- #define SVC_In3 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2)
- #define SVC_In4 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2),"r"(__r3)
- #define SVC_Out0
- #define SVC_Out1 "=r"(__r0)
- #define SVC_CL0 "r0","r1","r2","r3","lr","cc"
- #define SVC_CL1 "r1","r2","r3","lr","cc"
- #define SVC_CL2 "r2","r3","lr","cc"
- #define SVC_CL3 "r3","lr","cc"
- #define SVC_CL4 "lr","cc"
- #define SVC_Call0(in, out, cl) \
- __ASM volatile ("svc 0" : out : in : cl)
- #define SVC0_0N(f,t) \
- __attribute__((always_inline)) \
- __STATIC_INLINE t __svc##f (void) { \
- SVC_ArgF(os_svc##f); \
- SVC_Call0(SVC_In0, SVC_Out0, SVC_CL0); \
- }
- #define SVC0_0(f,t) \
- __attribute__((always_inline)) \
- __STATIC_INLINE t __svc##f (void) { \
- SVC_ArgN(0); \
- SVC_ArgF(os_svc##f); \
- SVC_Call0(SVC_In0, SVC_Out1, SVC_CL1); \
- return (t) __r0; \
- }
- #define SVC0_1N(f,t,t1) \
- __attribute__((always_inline)) \
- __STATIC_INLINE t __svc##f (t1 a1) { \
- SVC_ArgR(0,a1); \
- SVC_ArgF(os_svc##f); \
- SVC_Call0(SVC_In1, SVC_Out0, SVC_CL1); \
- }
- #define SVC0_1(f,t,t1) \
- __attribute__((always_inline)) \
- __STATIC_INLINE t __svc##f (t1 a1) { \
- SVC_ArgR(0,a1); \
- SVC_ArgF(os_svc##f); \
- SVC_Call0(SVC_In1, SVC_Out1, SVC_CL1); \
- return (t) __r0; \
- }
- #define SVC0_2(f,t,t1,t2) \
- __attribute__((always_inline)) \
- __STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \
- SVC_ArgR(0,a1); \
- SVC_ArgR(1,a2); \
- SVC_ArgF(os_svc##f); \
- SVC_Call0(SVC_In2, SVC_Out1, SVC_CL2); \
- return (t) __r0; \
- }
- #define SVC0_3(f,t,t1,t2,t3) \
- __attribute__((always_inline)) \
- __STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \
- SVC_ArgR(0,a1); \
- SVC_ArgR(1,a2); \
- SVC_ArgR(2,a3); \
- SVC_ArgF(os_svc##f); \
- SVC_Call0(SVC_In3, SVC_Out1, SVC_CL3); \
- return (t) __r0; \
- }
- #define SVC0_4(f,t,t1,t2,t3,t4) \
- __attribute__((always_inline)) \
- __STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
- SVC_ArgR(0,a1); \
- SVC_ArgR(1,a2); \
- SVC_ArgR(2,a3); \
- SVC_ArgR(3,a4); \
- SVC_ArgF(os_svc##f); \
- SVC_Call0(SVC_In4, SVC_Out1, SVC_CL4); \
- return (t) __r0; \
- }
- // ==== Core Peripherals functions ====
- extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
- /// Initialize SVC and PendSV System Service Calls
- __STATIC_INLINE void os_SVC_Initialize (void) {
- #if (__ARM_ARCH_8M_MAIN__ == 1U)
- uint32_t p, n;
- SCB->SHPR[10] = 0xFFU;
- n = 32U - (uint32_t)__CLZ(~(SCB->SHPR[10] | 0xFFFFFF00U));
- p = NVIC_GetPriorityGrouping();
- if (p >= n) {
- n = p + 1U;
- }
- SCB->SHPR[7] = (uint8_t)(0xFEU << n);
- #elif (__ARM_ARCH_8M_BASE__ == 1U)
- SCB->SHPR[1] |= 0x00FF0000U;
- SCB->SHPR[0] |= (SCB->SHPR[1] << (8+1)) & 0xFC000000U;
- #elif ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U))
- uint32_t p, n;
- SCB->SHP[10] = 0xFFU;
- n = 32U - (uint32_t)__CLZ(~(SCB->SHP[10] | 0xFFFFFF00U));
- p = NVIC_GetPriorityGrouping();
- if (p >= n) {
- n = p + 1U;
- }
- SCB->SHP[7] = (uint8_t)(0xFEU << n);
- #elif (__ARM_ARCH_6M__ == 1U)
- SCB->SHP[1] |= 0x00FF0000U;
- SCB->SHP[0] |= (SCB->SHP[1] << (8+1)) & 0xFC000000U;
- #endif
- }
- /// Setup SysTick Timer
- /// \param[in] period Timer Load value
- __STATIC_INLINE void os_SysTick_Setup (uint32_t period) {
- SysTick->LOAD = period - 1U;
- SysTick->VAL = 0U;
- #if (__ARM_ARCH_8M_MAIN__ == 1U)
- SCB->SHPR[11] = 0xFFU;
- #elif (__ARM_ARCH_8M_BASE__ == 1U)
- SCB->SHPR[1] |= 0xFF000000U;
- #elif ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U))
- SCB->SHP[11] = 0xFFU;
- #elif (__ARM_ARCH_6M__ == 1U)
- SCB->SHP[1] |= 0xFF000000U;
- #endif
- }
- /// Get SysTick Period
- /// \return SysTick Period
- __STATIC_INLINE uint32_t os_SysTick_GetPeriod (void) {
- return (SysTick->LOAD + 1U);
- }
- /// Get SysTick Value
- /// \return SysTick Value
- __STATIC_INLINE uint32_t os_SysTick_GetVal (void) {
- return (SysTick->LOAD - SysTick->VAL);
- }
- /// Get SysTick Overflow (Auto Clear)
- /// \return SysTick Overflow flag
- __STATIC_INLINE uint32_t os_SysTick_GetOvf (void) {
- return ((SysTick->CTRL >> 16) & 1U);
- }
- /// Enable SysTick Timer
- __STATIC_INLINE void os_SysTick_Enable (void) {
- SysTick->CTRL = SysTick_CTRL_ENABLE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_CLKSOURCE_Msk;
- }
- /// Disable SysTick Timer
- __STATIC_INLINE void os_SysTick_Disable (void) {
- SysTick->CTRL = 0U;
- }
- /// Setup External Tick Timer Interrupt
- /// \param[in] irqn Interrupt number
- __STATIC_INLINE void os_ExtTick_SetupIRQ (int32_t irqn) {
- #if (__ARM_ARCH_8M_MAIN__ == 1U)
- NVIC->IPR[irqn] = 0xFFU;
- #elif (__ARM_ARCH_8M_BASE__ == 1U)
- NVIC->IPR[irqn >> 2] = (NVIC->IPR[irqn >> 2] & ~(0xFFU << ((irqn & 3) << 3))) |
- (0xFFU << ((irqn & 3) << 3));
- #elif ((__ARM_ARCH_7M__ == 1U) || \
- (__ARM_ARCH_7EM__ == 1U))
- NVIC->IP[irqn] = 0xFFU;
- #elif (__ARM_ARCH_6M__ == 1U)
- NVIC->IP[irqn >> 2] = (NVIC->IP[irqn >> 2] & ~(0xFFU << ((irqn & 3) << 3))) |
- (0xFFU << ((irqn & 3) << 3));
- #endif
- }
- /// Enable External Tick Timer Interrupt
- /// \param[in] irqn Interrupt number
- __STATIC_INLINE void os_ExtTick_EnableIRQ (int32_t irqn) {
- NVIC->ISER[irqn >> 5] = 1U << (irqn & 0x1F);
- }
- /// Disable External Tick Timer Interrupt
- /// \param[in] irqn Interrupt number
- __STATIC_INLINE void os_ExtTick_DisableIRQ (int32_t irqn) {
- NVIC->ICER[irqn >> 5] = 1U << (irqn & 0x1F);
- }
- /// Get Pending SV (Service Call) and ST (SysTick) Flags
- /// \return Pending SV&ST Flags
- __STATIC_INLINE uint8_t os_GetPendSV_ST (void) {
- return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk | SCB_ICSR_PENDSTSET_Msk)) >> 24));
- }
- /// Get Pending SV (Service Call) Flag
- /// \return Pending SV Flag
- __STATIC_INLINE uint8_t os_GetPendSV (void) {
- return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24));
- }
- /// Clear Pending SV (Service Call) and ST (SysTick) Flags
- __STATIC_INLINE void os_ClrPendSV_ST (void) {
- SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
- }
- /// Clear Pending SV (Service Call) Flag
- __STATIC_INLINE void os_ClrPendSV (void) {
- SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk;
- }
- /// Set Pending SV (Service Call) Flag
- __STATIC_INLINE void os_SetPendSV (void) {
- SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
- }
- /// Set Pending Flags
- /// \param[in] flags Flags to set
- __STATIC_INLINE void os_SetPendFlags (uint8_t flags) {
- SCB->ICSR = ((uint32_t)flags << 24);
- }
- // ==== Exclusive Access Operation ====
- #if (__EXCLUSIVE_ACCESS == 1U)
- /// Exclusive Access Operation: Write (8-bit)
- /// \param[in] mem Memory address
- /// \param[in] val Value to write
- /// \return Previous value
- __STATIC_INLINE uint8_t os_exc_wr8 (uint8_t *mem, uint8_t val) {
- register uint32_t res;
- register uint8_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrexb %[ret],[%[mem]]\n\t"
- "strexb %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],2f\n\t"
- "b 1b\n\t"
- "2:"
- : [ret] "=&l" (ret),
- [res] "=&l" (res)
- : [mem] "l" (mem),
- [val] "l" (val)
- : "memory"
- );
- return ret;
- }
- /// Exclusive Access Operation: Set bits (32-bit)
- /// \param[in] mem Memory address
- /// \param[in] bits Bit mask
- /// \return New value
- __STATIC_INLINE uint32_t os_exc_set32 (uint32_t *mem, uint32_t bits) {
- register uint32_t val, res;
- register uint32_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrex %[val],[%[mem]]\n\t"
- #if (__ARM_ARCH_8M_BASE__ == 1U)
- "mov %[ret],%[val]\n\t"
- "orrs %[ret],%[bits]\n\t"
- #else
- "orr %[ret],%[val],%[bits]\n\t"
- #endif
- "strex %[res],%[ret],[%[mem]]\n\t"
- "cbz %[res],2f\n\t"
- "b 1b\n\t"
- "2:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem),
- [bits] "l" (bits)
- #if (__ARM_ARCH_8M_BASE__ == 1U)
- : "memory", "cc"
- #else
- : "memory"
- #endif
- );
- return ret;
- }
- /// Exclusive Access Operation: Clear bits (32-bit)
- /// \param[in] mem Memory address
- /// \param[in] bits Bit mask
- /// \return Previous value
- __STATIC_INLINE uint32_t os_exc_clr32 (uint32_t *mem, uint32_t bits) {
- register uint32_t val, res;
- register uint32_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrex %[ret],[%[mem]]\n\t"
- #if (__ARM_ARCH_8M_BASE__ == 1U)
- "mov %[val],%[ret]\n\t"
- "bics %[val],%[bits]\n\t"
- #else
- "bic %[val],%[ret],%[bits]\n\t"
- #endif
- "strex %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],2f\n\t"
- "b 1b\n\t"
- "2:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem),
- [bits] "l" (bits)
- #if (__ARM_ARCH_8M_BASE__ == 1U)
- : "memory", "cc"
- #else
- : "memory"
- #endif
- );
- return ret;
- }
- /// Exclusive Access Operation: Check if all specified bits (32-bit) are active and clear them
- /// \param[in] mem Memory address
- /// \param[in] bits Bit mask
- /// \return Active bits before clearing or 0 if not active
- __STATIC_INLINE uint32_t os_exc_chk32_all (uint32_t *mem, uint32_t bits) {
- register uint32_t val, res;
- register uint32_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrex %[ret],[%[mem]]\n\t"
- #if (__ARM_ARCH_8M_BASE__ == 1U)
- "mov %[val],%[ret]\n\t"
- "ands %[val],%[bits]\n\t"
- #else
- "and %[val],%[ret],%[bits]\n\t"
- #endif
- "cmp %[val],%[bits]\n\t"
- "beq 2f\n\t"
- "clrex\n\t"
- "movs %[ret],#0\n\t"
- "b 3f\n\t"
- "2:\n\t"
- #if (__ARM_ARCH_8M_BASE__ == 1U)
- "mov %[val],%[ret]\n\t"
- "bics %[val],%[bits]\n\t"
- #else
- "bic %[val],%[ret],%[bits]\n\t"
- #endif
- "strex %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],3f\n\t"
- "b 1b\n\t"
- "3:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem),
- [bits] "l" (bits)
- : "cc", "memory"
- );
- return ret;
- }
- /// Exclusive Access Operation: Check if any specified bits (32-bit) are active and clear them
- /// \param[in] mem Memory address
- /// \param[in] bits Bit mask
- /// \return Active bits before clearing or 0 if not active
- __STATIC_INLINE uint32_t os_exc_chk32_any (uint32_t *mem, uint32_t bits) {
- register uint32_t val, res;
- register uint32_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrex %[ret],[%[mem]]\n\t"
- "tst %[ret],%[bits]\n\t"
- "bne 2f\n\t"
- "clrex\n\t"
- "movs %[ret],#0\n\t"
- "b 3f\n\t"
- "2:\n\t"
- #if (__ARM_ARCH_8M_BASE__ == 1U)
- "mov %[val],%[ret]\n\t"
- "bics %[val],%[bits]\n\t"
- #else
- "bic %[val],%[ret],%[bits]\n\t"
- #endif
- "strex %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],3f\n\t"
- "b 1b\n\t"
- "3:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem),
- [bits] "l" (bits)
- : "cc", "memory"
- );
- return ret;
- }
- /// Exclusive Access Operation: Increment (32-bit)
- /// \param[in] mem Memory address
- /// \return Previous value
- __STATIC_INLINE uint32_t os_exc_inc32 (uint32_t *mem) {
- register uint32_t val, res;
- register uint32_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrex %[ret],[%[mem]]\n\t"
- "adds %[val],%[ret],#1\n\t"
- "strex %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],2f\n\t"
- "b 1b\n\t"
- "2:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem)
- : "cc", "memory"
- );
- return ret;
- }
- /// Exclusive Access Operation: Increment (16-bit) if Less Than
- /// \param[in] mem Memory address
- /// \param[in] max Maximum value
- /// \return Previous value
- __STATIC_INLINE uint16_t os_exc_inc16_lt (uint16_t *mem, uint16_t max) {
- register uint32_t val, res;
- register uint16_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrexh %[ret],[%[mem]]\n\t"
- "cmp %[max],%[ret]\n\t"
- "bhi 2f\n\t"
- "clrex\n\t"
- "b 3f\n\t"
- "2:\n\t"
- "adds %[val],%[ret],#1\n\t"
- "strexh %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],3f\n\t"
- "b 1b\n\t"
- "3:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem),
- [max] "l" (max)
- : "cc", "memory"
- );
- return ret;
- }
- /// Exclusive Access Operation: Increment (16-bit) and clear on Limit
- /// \param[in] mem Memory address
- /// \param[in] max Maximum value
- /// \return Previous value
- __STATIC_INLINE uint16_t os_exc_inc16_lim (uint16_t *mem, uint16_t lim) {
- register uint32_t val, res;
- register uint16_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrexh %[ret],[%[mem]]\n\t"
- "adds %[val],%[ret],#1\n\t"
- "cmp %[lim],%[val]\n\t"
- "bhi 2f\n\t"
- "movs %[val],#0\n\t"
- "2:\n\t"
- "strexh %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],3f\n\t"
- "b 1b\n\t"
- "3:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem),
- [lim] "l" (lim)
- : "cc", "memory"
- );
- return ret;
- }
- /// Exclusive Access Operation: Decrement (32-bit) if Not Zero
- /// \param[in] mem Memory address
- /// \return Previous value
- __STATIC_INLINE uint32_t os_exc_dec32_nz (uint32_t *mem) {
- register uint32_t val, res;
- register uint32_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrex %[ret],[%[mem]]\n\t"
- "cbnz %[ret],2f\n\t"
- "clrex\n\t"
- "b 3f\n\t"
- "2:\n\t"
- "subs %[val],%[ret],#1\n\t"
- "strex %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],3f\n\t"
- "b 1b\n\t"
- "3:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem)
- : "cc", "memory"
- );
- return ret;
- }
- /// Exclusive Access Operation: Decrement (16-bit) if Not Zero
- /// \param[in] mem Memory address
- /// \return Previous value
- __STATIC_INLINE uint16_t os_exc_dec16_nz (uint16_t *mem) {
- register uint32_t val, res;
- register uint16_t ret;
- __ASM volatile (
- ".syntax unified\n\t"
- "1:\n\t"
- "ldrexh %[ret],[%[mem]]\n\t"
- "cbnz %[ret],2f\n\t"
- "clrex\n\t"
- "b 3f\n\t"
- "2:\n\t"
- "subs %[val],%[ret],#1\n\t"
- "strexh %[res],%[val],[%[mem]]\n\t"
- "cbz %[res],3f\n\t"
- "b 1b\n\t"
- "3:"
- : [ret] "=&l" (ret),
- [val] "=&l" (val),
- [res] "=&l" (res)
- : [mem] "l" (mem)
- : "cc", "memory"
- );
- return ret;
- }
- #endif // (__EXCLUSIVE_ACCESS == 1U)
- #endif // CORE_CM_H_
|