#ifndef INCLUDED_CPU_H #define INCLUDED_CPU_H #ifndef INCLUDED_CMSIS_H #include #endif /*INCLUDED_CMSIS_H*/ #ifndef INCLUDED_OS_TYPES_H #include #endif /*INCLUDED_OS_TYPES_H*/ #ifndef INCLUDED_OS_COMPILER_H #include #endif /*INCLUDED_OS_COMPILER_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #define os_port_disable_irq CMSIS_disable_irq #define os_port_enable_irq CMSIS_enable_irq #define os_port_save_disable_irq cpu_save_disable_irq #define os_port_restore_irq cpu_restore_irq #define os_port_save_disable_irq_in_isr cpu_save_disable_irq_in_isr #define os_port_restore_irq_in_isr cpu_restore_irq_in_isr /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #define CPU_SYSCALL_ID 0x00 #define CPU_SYSCALL_OP_SAVE_DISABLE_IRQ 0x00 #define CPU_SYSCALL_OP_RESTORE_IRQ 0x01 #define CPU_SYSCALL_OP_SCHED 0x02 /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #if defined(__CC_ARM) /* armcc (AC5) */ #define SVC_CALL_ARGS0(num, type, name) \ __svc(num) type name(void); #define SVC_CALL_ARGS1(num, type, name, a0) \ __svc(num) type name(os_uintptr_t a0); #define SVC_CALL_ARGS2(num, type, name, a0, a1) \ __svc(num) type name(os_uintptr_t a0, os_uintptr_t a1); #define SVC_CALL_ARGS3(num, type, name, a0, a1, a2) \ __svc(num) type name(os_uintptr_t a0, os_uintptr_t a1, os_uintptr_t a2); #define SVC_CALL_ARGS4(num, type, name, a0, a1, a2, a3) \ __svc(num) type name(os_uintptr_t a0, os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3); #elif defined(__GNUC__) /* gcc */ #define SVC_CALL_ARGS0(num, type, name) \ static type name(void) { \ register os_uintptr_t r0 __asm__("r0")=0; \ __asm__ volatile ("svc " #num : : : "memory"); \ return (type)r0; \ } #define SVC_CALL_ARGS1(num, type, name, a1) \ OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1) { \ register os_uintptr_t r0 __asm__("r0") = a1; \ __asm__ volatile ("svc " #num :"=r"(r0):"r"(r0) : "memory"); \ return (type)r0; \ } #define SVC_CALL_ARGS2(num, type, name, a1, a2) \ OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2) { \ register os_uintptr_t r0 __asm__("r0") = a1;\ register os_uintptr_t r1 __asm__("r1") = a2;\ __asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1) : "memory"); \ return (type)r0; \ } #define SVC_CALL_ARGS3(num, type, name, a1, a2, a3) \ OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3) { \ register os_uintptr_t r0 __asm__("r0") = a1; \ register os_uintptr_t r1 __asm__("r1") = a2; \ register os_uintptr_t r2 __asm__("r2") = a3; \ __asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1), "r"(r2) : "memory"); \ return (type)r0; \ } #define SVC_CALL_ARGS4(num, type, name, a1, a2, a3, a4) \ OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3, os_uintptr_t a4) { \ register os_uintptr_t r0 __asm__("r0") = a1; \ register os_uintptr_t r1 __asm__("r1") = a2; \ register os_uintptr_t r2 __asm__("r2") = a3; \ register os_uintptr_t r3 __asm__("r3") = a4; \ __asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1), "r"(r2), "r"(r3) : "memory"); \ return (type)r0; \ } #endif SVC_CALL_ARGS1(0, os_uint_t, cpu_svc0_args1, a1) SVC_CALL_ARGS2(0, void, cpu_svc0_args2, a1, a2) OS_STATIC_FORCE_INLINE os_uint_t cpu_save_disable_irq_in_svc(void){ return cpu_svc0_args1(CPU_SYSCALL_OP_SAVE_DISABLE_IRQ); } OS_STATIC_FORCE_INLINE void cpu_restore_irq_in_svc(os_uint_t level){ cpu_svc0_args2(CPU_SYSCALL_OP_RESTORE_IRQ, level); } OS_STATIC_FORCE_INLINE void cpu_sched_in_svc(void){ cpu_svc0_args1(CPU_SYSCALL_OP_SCHED); } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ OS_STATIC_FORCE_INLINE int is_cpu_in_privilege(void){ // 1. 检查是否在中断/异常中 (IPSR != 0 表示 Handler 模式) if ( CMSIS_get_IPSR() != 0) { return 1; } // 2. 如果在 Thread 模式,检查 CONTROL 寄存器 return ((CMSIS_get_CONTROL() & 0x01) == 0)?1:0; } OS_STATIC_FORCE_INLINE os_uint_t cpu_save_disable_irq_in_isr(void){ os_uint_t level = CMSIS_get_BASEPRI(); CMSIS_set_BASEPRI((OS_CFG_SYSCALL_PRIORITY+1) << 4); return level; } OS_STATIC_FORCE_INLINE void cpu_restore_irq_in_isr(os_uint_t value){ CMSIS_set_BASEPRI(value); } OS_STATIC_FORCE_INLINE os_uint_t cpu_save_disable_irq(void){ if(is_cpu_in_privilege()){ return cpu_save_disable_irq_in_isr(); }else{ return cpu_save_disable_irq_in_svc(); } } OS_STATIC_FORCE_INLINE void cpu_restore_irq(os_uint_t value){ if(is_cpu_in_privilege()){ cpu_restore_irq_in_isr(value); }else{ cpu_restore_irq_in_svc(value); } } #endif /*INCLUDED_CPU_H*/