|
新的V6.1.7已经增加basepri开关中断方式:
Basepri寄存器做全局开关中断的方案,这样可以让高优先级中断不受ThreadX管控,实现零中断延迟
见tx_port.h
- #ifndef TX_DISABLE_INLINE
- /* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */
- #ifdef __ICCARM__ /* IAR Compiler */
- #define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m)));
- #elif defined(__CC_ARM) /* AC5 Compiler */
- #define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m)));
- #elif defined(__GNUC__) /* GCC and AC6 Compiler */
- #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \
- __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) );
- #endif
- /* Define the interrupt disable/restore macros for each compiler. */
- #if defined(__GNUC__) || defined(__ICCARM__)
- /*** GCC/AC6 and IAR ***/
- __attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void)
- {
- unsigned int posture;
- #ifdef TX_PORT_USE_BASEPRI
- __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
- #else
- __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
- #endif
- return(posture);
- }
- #ifdef TX_PORT_USE_BASEPRI
- __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value)
- {
- __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
- }
- #else
- __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
- {
- __asm__ volatile ("CPSIE i": : : "memory");
- }
- #endif
- __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture)
- {
- #ifdef TX_PORT_USE_BASEPRI
- __set_basepri_value(int_posture);
- //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory");
- #else
- __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
- #endif
- }
- __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void)
- {
- unsigned int int_posture;
- int_posture = __get_interrupt_posture();
- #ifdef TX_PORT_USE_BASEPRI
- __set_basepri_value(TX_PORT_BASEPRI);
- #else
- __asm__ volatile ("CPSID i" : : : "memory");
- #endif
- return(int_posture);
- }
- __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
- {
- unsigned int interrupt_save;
- /* Set PendSV to invoke ThreadX scheduler. */
- *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (__get_ipsr_value() == 0)
- {
- interrupt_save = __get_interrupt_posture();
- #ifdef TX_PORT_USE_BASEPRI
- __set_basepri_value(0);
- #else
- __enable_interrupts();
- #endif
- __restore_interrupt(interrupt_save);
- }
- }
- #define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
- #define TX_DISABLE interrupt_save = __disable_interrupts();
- #define TX_RESTORE __restore_interrupt(interrupt_save);
- /*** End GCC/AC6 and IAR ***/
- #elif defined(__CC_ARM)
- /*** AC5 ***/
- static __inline unsigned int __get_interrupt_posture(void)
- {
- unsigned int posture;
- #ifdef TX_PORT_USE_BASEPRI
- __asm__ volatile ("MRS #posture, BASEPRI");
- #else
- __asm__ volatile ("MRS #posture, PRIMASK");
- #endif
- return(posture);
- }
- #ifdef TX_PORT_USE_BASEPRI
- static __inline void __set_basepri_value(unsigned int basepri_value)
- {
- __asm__ volatile ("MSR BASEPRI, #basepri_value");
- }
- #endif
- static __inline unsigned int __disable_interrupts(void)
- {
- unsigned int int_posture;
- int_posture = __get_interrupt_posture();
- #ifdef TX_PORT_USE_BASEPRI
- __set_basepri_value(TX_PORT_BASEPRI);
- #else
- __asm__ volatile ("CPSID i");
- #endif
- return(int_posture);
- }
- static __inline void __restore_interrupt(unsigned int int_posture)
- {
- #ifdef TX_PORT_USE_BASEPRI
- __set_basepri_value(int_posture);
- #else
- __asm__ volatile ("MSR PRIMASK, #int_posture");
- #endif
- }
- static void _tx_thread_system_return_inline(void)
- {
- unsigned int interrupt_save;
- /* Set PendSV to invoke ThreadX scheduler. */
- *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (_ipsr == 0)
- {
- #ifdef TX_PORT_USE_BASEPRI
- interrupt_save = __get_interrupt_posture();
- __set_basepri_value(0);
- __set_basepri_value(interrupt_save);
- #else
- interrupt_save = __disable_irq();
- __enable_irq();
- if (interrupt_save != 0)
- __disable_irq();
- #endif
- }
- }
- #define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
- #define TX_DISABLE interrupt_save = __disable_interrupts();
- #define TX_RESTORE __restore_interrupt(interrupt_save);
- /*** End AC5 ***/
- #endif /* Interrupt disable/restore macros for each compiler. */
- /* Redefine _tx_thread_system_return for improved performance. */
- #define _tx_thread_system_return _tx_thread_system_return_inline
- #else /* TX_DISABLE_INLINE is defined */
- UINT _tx_thread_interrupt_disable(VOID);
- VOID _tx_thread_interrupt_restore(UINT previous_posture);
- #define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
- #define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
- #define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
- #endif /* TX_DISABLE_INLINE */
复制代码
|
|