|
|
@@ -29,6 +29,10 @@
|
|
|
#include "RTE_Components.h"
|
|
|
#include CMSIS_device_header
|
|
|
|
|
|
+#if (defined (__CC_ARM) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__))
|
|
|
+#define __ARM_ARCH_6M__ 1U
|
|
|
+#endif
|
|
|
+
|
|
|
#ifndef __ARM_ARCH_6M__
|
|
|
#define __ARM_ARCH_6M__ 0U
|
|
|
#endif
|
|
|
@@ -103,6 +107,75 @@
|
|
|
|
|
|
// ==== Service Calls definitions ====
|
|
|
|
|
|
+#if defined(__CC_ARM)
|
|
|
+
|
|
|
+#if ((__ARM_ARCH_7M__ == 1U) || \
|
|
|
+ (__ARM_ARCH_7EM__ == 1U) || \
|
|
|
+ (__ARM_ARCH_8M_MAIN__ == 1U))
|
|
|
+#define __SVC_INDIRECT(n) __svc_indirect(n)
|
|
|
+#elif ((__ARM_ARCH_6M__ == 1U) || \
|
|
|
+ (__ARM_ARCH_8M_BASE__ == 1U))
|
|
|
+#define __SVC_INDIRECT(n) __svc_indirect_r7(n)
|
|
|
+#endif
|
|
|
+
|
|
|
+#define SVC0_0N(f,t) \
|
|
|
+__SVC_INDIRECT(0) t _svc##f (t(*)()); \
|
|
|
+ t os_svc##f (void); \
|
|
|
+__attribute__((always_inline)) \
|
|
|
+__STATIC_INLINE t __svc##f (void) { \
|
|
|
+ _svc##f(os_svc##f); \
|
|
|
+}
|
|
|
+
|
|
|
+#define SVC0_0(f,t) \
|
|
|
+__SVC_INDIRECT(0) t _svc##f (t(*)()); \
|
|
|
+ t os_svc##f (void); \
|
|
|
+__attribute__((always_inline)) \
|
|
|
+__STATIC_INLINE t __svc##f (void) { \
|
|
|
+ return _svc##f(os_svc##f); \
|
|
|
+}
|
|
|
+
|
|
|
+#define SVC0_1N(f,t,t1) \
|
|
|
+__SVC_INDIRECT(0) t _svc##f (t(*)(t1),t1); \
|
|
|
+ t os_svc##f (t1 a1); \
|
|
|
+__attribute__((always_inline)) \
|
|
|
+__STATIC_INLINE t __svc##f (t1 a1) { \
|
|
|
+ _svc##f(os_svc##f,a1); \
|
|
|
+}
|
|
|
+
|
|
|
+#define SVC0_1(f,t,t1) \
|
|
|
+__SVC_INDIRECT(0) t _svc##f (t(*)(t1),t1); \
|
|
|
+ t os_svc##f (t1 a1); \
|
|
|
+__attribute__((always_inline)) \
|
|
|
+__STATIC_INLINE t __svc##f (t1 a1) { \
|
|
|
+ return _svc##f(os_svc##f,a1); \
|
|
|
+}
|
|
|
+
|
|
|
+#define SVC0_2(f,t,t1,t2) \
|
|
|
+__SVC_INDIRECT(0) t _svc##f (t(*)(t1,t2),t1,t2); \
|
|
|
+ t os_svc##f (t1 a1, t2 a2); \
|
|
|
+__attribute__((always_inline)) \
|
|
|
+__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \
|
|
|
+ return _svc##f(os_svc##f,a1,a2); \
|
|
|
+}
|
|
|
+
|
|
|
+#define SVC0_3(f,t,t1,t2,t3) \
|
|
|
+__SVC_INDIRECT(0) t _svc##f (t(*)(t1,t2,t3),t1,t2,t3); \
|
|
|
+ t os_svc##f (t1 a1, t2 a2, t3 a3); \
|
|
|
+__attribute__((always_inline)) \
|
|
|
+__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \
|
|
|
+ return _svc##f(os_svc##f,a1,a2,a3); \
|
|
|
+}
|
|
|
+
|
|
|
+#define SVC0_4(f,t,t1,t2,t3,t4) \
|
|
|
+__SVC_INDIRECT(0) t _svc##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \
|
|
|
+ t os_svc##f (t1 a1, t2 a2, t3 a3, t4 a4); \
|
|
|
+__attribute__((always_inline)) \
|
|
|
+__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
|
|
|
+ return _svc##f(os_svc##f,a1,a2,a3,a4); \
|
|
|
+}
|
|
|
+
|
|
|
+#else // !defined(__CC_ARM)
|
|
|
+
|
|
|
#if ((__ARM_ARCH_7M__ == 1U) || \
|
|
|
(__ARM_ARCH_7EM__ == 1U) || \
|
|
|
(__ARM_ARCH_8M_MAIN__ == 1U))
|
|
|
@@ -205,6 +278,8 @@ __STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
|
|
|
return (t) __r0; \
|
|
|
}
|
|
|
|
|
|
+#endif // !defined(__CC_ARM)
|
|
|
+
|
|
|
|
|
|
// ==== Core Peripherals functions ====
|
|
|
|
|
|
@@ -359,6 +434,18 @@ __STATIC_INLINE void os_SetPendFlags (uint8_t flags) {
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \param[in] val Value to write
|
|
|
/// \return Previous value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint8_t os_exc_wr8 (uint8_t *mem, uint8_t val) {
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrexb r0,[r2]
|
|
|
+ strexb r3,r1,[r2]
|
|
|
+ cbz r3,%F2
|
|
|
+ b %B1
|
|
|
+2
|
|
|
+ bx lr
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint8_t os_exc_wr8 (uint8_t *mem, uint8_t val) {
|
|
|
register uint32_t res;
|
|
|
register uint8_t ret;
|
|
|
@@ -380,11 +467,25 @@ __STATIC_INLINE uint8_t os_exc_wr8 (uint8_t *mem, uint8_t val) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Set bits (32-bit)
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \param[in] bits Bit mask
|
|
|
/// \return New value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint32_t os_exc_set32 (uint32_t *mem, uint32_t bits) {
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrex r0,[r2]
|
|
|
+ orr r0,r0,r1
|
|
|
+ strex r3,r0,[r2]
|
|
|
+ cbz r3,%F2
|
|
|
+ b %B1
|
|
|
+2
|
|
|
+ bx lr
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint32_t os_exc_set32 (uint32_t *mem, uint32_t bits) {
|
|
|
register uint32_t val, res;
|
|
|
register uint32_t ret;
|
|
|
@@ -417,11 +518,26 @@ __STATIC_INLINE uint32_t os_exc_set32 (uint32_t *mem, uint32_t bits) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Clear bits (32-bit)
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \param[in] bits Bit mask
|
|
|
/// \return Previous value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint32_t os_exc_clr32 (uint32_t *mem, uint32_t bits) {
|
|
|
+ push {r4,lr}
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrex r0,[r2]
|
|
|
+ bic r4,r0,r1
|
|
|
+ strex r3,r4,[r2]
|
|
|
+ cbz r3,%F2
|
|
|
+ b %B1
|
|
|
+2
|
|
|
+ pop {r4,pc}
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint32_t os_exc_clr32 (uint32_t *mem, uint32_t bits) {
|
|
|
register uint32_t val, res;
|
|
|
register uint32_t ret;
|
|
|
@@ -454,11 +570,33 @@ __STATIC_INLINE uint32_t os_exc_clr32 (uint32_t *mem, uint32_t bits) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// 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
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint32_t os_exc_chk32_all (uint32_t *mem, uint32_t bits) {
|
|
|
+ push {r4,lr}
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrex r0,[r2]
|
|
|
+ and r4,r0,r1
|
|
|
+ cmp r4,r1
|
|
|
+ beq %F2
|
|
|
+ clrex
|
|
|
+ movs r0,#0
|
|
|
+ pop {r4,pc}
|
|
|
+2
|
|
|
+ bic r4,r0,r1
|
|
|
+ strex r3,r4,[r2]
|
|
|
+ cbz r3,%F3
|
|
|
+ b %B1
|
|
|
+3
|
|
|
+ pop {r4,pc}
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint32_t os_exc_chk32_all (uint32_t *mem, uint32_t bits) {
|
|
|
register uint32_t val, res;
|
|
|
register uint32_t ret;
|
|
|
@@ -499,11 +637,32 @@ __STATIC_INLINE uint32_t os_exc_chk32_all (uint32_t *mem, uint32_t bits) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// 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
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint32_t os_exc_chk32_any (uint32_t *mem, uint32_t bits) {
|
|
|
+ push {r4,lr}
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrex r0,[r2]
|
|
|
+ tst r0,r1
|
|
|
+ bne %F2
|
|
|
+ clrex
|
|
|
+ movs r0,#0
|
|
|
+ pop {r4,pc}
|
|
|
+2
|
|
|
+ bic r4,r0,r1
|
|
|
+ strex r3,r4,[r2]
|
|
|
+ cbz r3,%F3
|
|
|
+ b %B1
|
|
|
+3
|
|
|
+ pop {r4,pc}
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint32_t os_exc_chk32_any (uint32_t *mem, uint32_t bits) {
|
|
|
register uint32_t val, res;
|
|
|
register uint32_t ret;
|
|
|
@@ -538,10 +697,24 @@ __STATIC_INLINE uint32_t os_exc_chk32_any (uint32_t *mem, uint32_t bits) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Increment (32-bit)
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \return Previous value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint32_t os_exc_inc32 (uint32_t *mem) {
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrex r0,[r2]
|
|
|
+ adds r1,r0,#1
|
|
|
+ strex r3,r1,[r2]
|
|
|
+ cbz r3,%F2
|
|
|
+ b %B1
|
|
|
+2
|
|
|
+ bx lr
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint32_t os_exc_inc32 (uint32_t *mem) {
|
|
|
register uint32_t val, res;
|
|
|
register uint32_t ret;
|
|
|
@@ -564,11 +737,31 @@ __STATIC_INLINE uint32_t os_exc_inc32 (uint32_t *mem) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Increment (32-bit) if Less Than
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \param[in] max Maximum value
|
|
|
/// \return Previous value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint32_t os_exc_inc32_lt (uint32_t *mem, uint32_t max) {
|
|
|
+ push {r4,lr}
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrex r0,[r2]
|
|
|
+ cmp r1,r0
|
|
|
+ bhi %F2
|
|
|
+ clrex
|
|
|
+ pop {r4,pc}
|
|
|
+2
|
|
|
+ adds r4,r0,#1
|
|
|
+ strex r3,r4,[r2]
|
|
|
+ cbz r3,%F3
|
|
|
+ b %B1
|
|
|
+3
|
|
|
+ pop {r4,pc}
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint32_t os_exc_inc32_lt (uint32_t *mem, uint32_t max) {
|
|
|
register uint32_t val, res;
|
|
|
register uint32_t ret;
|
|
|
@@ -597,11 +790,31 @@ __STATIC_INLINE uint32_t os_exc_inc32_lt (uint32_t *mem, uint32_t max) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Increment (16-bit) if Less Than
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \param[in] max Maximum value
|
|
|
/// \return Previous value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint16_t os_exc_inc16_lt (uint16_t *mem, uint16_t max) {
|
|
|
+ push {r4,lr}
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrexh r0,[r2]
|
|
|
+ cmp r1,r0
|
|
|
+ bhi %F2
|
|
|
+ clrex
|
|
|
+ pop {r4,pc}
|
|
|
+2
|
|
|
+ adds r4,r0,#1
|
|
|
+ strexh r3,r4,[r2]
|
|
|
+ cbz r3,%F3
|
|
|
+ b %B1
|
|
|
+3
|
|
|
+ pop {r4,pc}
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint16_t os_exc_inc16_lt (uint16_t *mem, uint16_t max) {
|
|
|
register uint32_t val, res;
|
|
|
register uint16_t ret;
|
|
|
@@ -630,11 +843,30 @@ __STATIC_INLINE uint16_t os_exc_inc16_lt (uint16_t *mem, uint16_t max) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Increment (16-bit) and clear on Limit
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \param[in] max Maximum value
|
|
|
/// \return Previous value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint16_t os_exc_inc16_lim (uint16_t *mem, uint16_t lim) {
|
|
|
+ push {r4,lr}
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrexh r0,[r2]
|
|
|
+ adds r4,r0,#1
|
|
|
+ cmp r1,r4
|
|
|
+ bhi %F2
|
|
|
+ movs r4,#0
|
|
|
+2
|
|
|
+ strexh r3,r4,[r2]
|
|
|
+ cbz r3,%F3
|
|
|
+ b %B1
|
|
|
+3
|
|
|
+ pop {r4,pc}
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint16_t os_exc_inc16_lim (uint16_t *mem, uint16_t lim) {
|
|
|
register uint32_t val, res;
|
|
|
register uint16_t ret;
|
|
|
@@ -662,10 +894,28 @@ __STATIC_INLINE uint16_t os_exc_inc16_lim (uint16_t *mem, uint16_t lim) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Decrement (32-bit) if Not Zero
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \return Previous value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint32_t os_exc_dec32_nz (uint32_t *mem) {
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrex r0,[r2]
|
|
|
+ cbnz r0,%F2
|
|
|
+ clrex
|
|
|
+ bx lr
|
|
|
+2
|
|
|
+ subs r1,r0,#1
|
|
|
+ strex r3,r1,[r2]
|
|
|
+ cbz r3,%F3
|
|
|
+ b %B1
|
|
|
+3
|
|
|
+ bx lr
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint32_t os_exc_dec32_nz (uint32_t *mem) {
|
|
|
register uint32_t val, res;
|
|
|
register uint32_t ret;
|
|
|
@@ -692,10 +942,28 @@ __STATIC_INLINE uint32_t os_exc_dec32_nz (uint32_t *mem) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Decrement (16-bit) if Not Zero
|
|
|
/// \param[in] mem Memory address
|
|
|
/// \return Previous value
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm uint16_t os_exc_dec16_nz (uint16_t *mem) {
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrexh r0,[r2]
|
|
|
+ cbnz r0,%F2
|
|
|
+ clrex
|
|
|
+ bx lr
|
|
|
+2
|
|
|
+ subs r1,r0,#1
|
|
|
+ strexh r3,r1,[r2]
|
|
|
+ cbz r3,%F3
|
|
|
+ b %B1
|
|
|
+3
|
|
|
+ bx lr
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE uint16_t os_exc_dec16_nz (uint16_t *mem) {
|
|
|
register uint32_t val, res;
|
|
|
register uint16_t ret;
|
|
|
@@ -722,10 +990,28 @@ __STATIC_INLINE uint16_t os_exc_dec16_nz (uint16_t *mem) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Link Get
|
|
|
/// \param[in] root Root address
|
|
|
/// \return Link
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm void *os_exc_link_get (void **root) {
|
|
|
+ mov r2,r0
|
|
|
+1
|
|
|
+ ldrex r0,[r2]
|
|
|
+ cbnz r0,%F2
|
|
|
+ clrex
|
|
|
+ bx lr
|
|
|
+2
|
|
|
+ ldr r1,[r0]
|
|
|
+ strex r3,r1,[r2]
|
|
|
+ cbz r3,%F3
|
|
|
+ b %B1
|
|
|
+3
|
|
|
+ bx lr
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE void *os_exc_link_get (void **root) {
|
|
|
register uint32_t val, res;
|
|
|
register void *ret;
|
|
|
@@ -752,10 +1038,28 @@ __STATIC_INLINE void *os_exc_link_get (void **root) {
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
/// Exclusive Access Operation: Link Put
|
|
|
/// \param[in] root Root address
|
|
|
/// \param[in] lnk Link
|
|
|
+#if defined(__CC_ARM)
|
|
|
+static __asm void os_exc_link_put (void **root, void *link) {
|
|
|
+1
|
|
|
+ ldr r2,[r0]
|
|
|
+ str r2,[r1]
|
|
|
+ dmb
|
|
|
+ ldrex r2,[r0]
|
|
|
+ ldr r3,[r1]
|
|
|
+ cmp r3,r2
|
|
|
+ bne %B1
|
|
|
+ strex r3,r1,[r0]
|
|
|
+ cbz r3,%F2
|
|
|
+ b %B1
|
|
|
+2
|
|
|
+ bx lr
|
|
|
+}
|
|
|
+#else
|
|
|
__STATIC_INLINE void os_exc_link_put (void **root, void *link) {
|
|
|
register uint32_t val1, val2, res;
|
|
|
|
|
|
@@ -781,6 +1085,7 @@ __STATIC_INLINE void os_exc_link_put (void **root, void *link) {
|
|
|
: "cc", "memory"
|
|
|
);
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
#endif // (__EXCLUSIVE_ACCESS == 1U)
|
|
|
|