硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3424|回复: 3
收起左侧

[ThreadX全家桶] ThreadX内核这波操作可以,开关中断已经增加basepri方式

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115896
QQ
发表于 2021-6-8 10:44:57 | 显示全部楼层 |阅读模式

新的V6.1.7已经增加basepri开关中断方式:

Basepri寄存器做全局开关中断的方案,这样可以让高优先级中断不受ThreadX管控,实现零中断延迟

见tx_port.h
  1. #ifndef TX_DISABLE_INLINE

  2. /* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */
  3. #ifdef __ICCARM__       /* IAR Compiler */
  4. #define TX_LOWEST_SET_BIT_CALCULATE(m, b)       (b) = (UINT) __CLZ(__RBIT((m)));
  5. #elif defined(__CC_ARM) /* AC5 Compiler */
  6. #define TX_LOWEST_SET_BIT_CALCULATE(m, b)       (b) = (UINT) __clz(__rbit((m)));
  7. #elif defined(__GNUC__) /* GCC and AC6 Compiler */
  8. #define TX_LOWEST_SET_BIT_CALCULATE(m, b)       __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \
  9.                                                 __asm__ volatile (" CLZ  %0,%1 ": "=r" (b) : "r" (m) );
  10. #endif



  11. /* Define the interrupt disable/restore macros for each compiler. */

  12. #if defined(__GNUC__) || defined(__ICCARM__)

  13. /*** GCC/AC6 and IAR ***/

  14. __attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void)
  15. {
  16. unsigned int posture;
  17. #ifdef TX_PORT_USE_BASEPRI
  18.     __asm__ volatile ("MRS  %0, BASEPRI ": "=r" (posture));
  19. #else
  20.     __asm__ volatile ("MRS  %0, PRIMASK ": "=r" (posture));
  21. #endif
  22.     return(posture);
  23. }

  24. #ifdef TX_PORT_USE_BASEPRI
  25. __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value)
  26. {
  27.     __asm__ volatile ("MSR  BASEPRI,%0 ": : "r" (basepri_value));
  28. }
  29. #else
  30. __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
  31. {
  32.     __asm__ volatile ("CPSIE  i": : : "memory");
  33. }
  34. #endif

  35. __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture)
  36. {
  37. #ifdef TX_PORT_USE_BASEPRI
  38.     __set_basepri_value(int_posture);
  39.     //__asm__ volatile ("MSR  BASEPRI,%0": : "r" (int_posture): "memory");
  40. #else
  41.     __asm__ volatile ("MSR  PRIMASK,%0": : "r" (int_posture): "memory");
  42. #endif
  43. }

  44. __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void)
  45. {
  46. unsigned int int_posture;

  47.     int_posture = __get_interrupt_posture();

  48. #ifdef TX_PORT_USE_BASEPRI
  49.     __set_basepri_value(TX_PORT_BASEPRI);
  50. #else
  51.     __asm__ volatile ("CPSID i" : : : "memory");
  52. #endif
  53.     return(int_posture);
  54. }

  55. __attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
  56. {
  57. unsigned int interrupt_save;

  58.     /* Set PendSV to invoke ThreadX scheduler.  */
  59.     *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
  60.     if (__get_ipsr_value() == 0)
  61.     {
  62.         interrupt_save = __get_interrupt_posture();
  63. #ifdef TX_PORT_USE_BASEPRI
  64.         __set_basepri_value(0);
  65. #else
  66.         __enable_interrupts();
  67. #endif
  68.         __restore_interrupt(interrupt_save);
  69.     }
  70. }

  71. #define TX_INTERRUPT_SAVE_AREA                  unsigned int interrupt_save;
  72. #define TX_DISABLE                              interrupt_save =  __disable_interrupts();
  73. #define TX_RESTORE                              __restore_interrupt(interrupt_save);

  74. /*** End GCC/AC6 and IAR ***/

  75. #elif defined(__CC_ARM)

  76. /*** AC5 ***/

  77. static __inline unsigned int __get_interrupt_posture(void)
  78. {
  79. unsigned int posture;
  80. #ifdef TX_PORT_USE_BASEPRI
  81.     __asm__ volatile ("MRS  #posture, BASEPRI");
  82. #else
  83.     __asm__ volatile ("MRS  #posture, PRIMASK");
  84. #endif
  85.     return(posture);
  86. }

  87. #ifdef TX_PORT_USE_BASEPRI
  88. static __inline void __set_basepri_value(unsigned int basepri_value)
  89. {
  90.     __asm__ volatile ("MSR  BASEPRI, #basepri_value");
  91. }
  92. #endif

  93. static __inline unsigned int __disable_interrupts(void)
  94. {
  95. unsigned int int_posture;

  96.     int_posture = __get_interrupt_posture();

  97. #ifdef TX_PORT_USE_BASEPRI
  98.     __set_basepri_value(TX_PORT_BASEPRI);
  99. #else
  100.     __asm__ volatile ("CPSID i");
  101. #endif
  102.     return(int_posture);
  103. }

  104. static __inline void __restore_interrupt(unsigned int int_posture)
  105. {
  106. #ifdef TX_PORT_USE_BASEPRI
  107.     __set_basepri_value(int_posture);
  108. #else
  109.     __asm__ volatile ("MSR  PRIMASK, #int_posture");
  110. #endif
  111. }

  112. static void _tx_thread_system_return_inline(void)
  113. {
  114. unsigned int interrupt_save;

  115.     /* Set PendSV to invoke ThreadX scheduler.  */
  116.     *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
  117.     if (_ipsr == 0)
  118.     {
  119. #ifdef TX_PORT_USE_BASEPRI
  120.         interrupt_save = __get_interrupt_posture();
  121.         __set_basepri_value(0);
  122.         __set_basepri_value(interrupt_save);
  123. #else
  124.         interrupt_save = __disable_irq();
  125.         __enable_irq();
  126.         if (interrupt_save != 0)
  127.             __disable_irq();
  128. #endif
  129.     }
  130. }


  131. #define TX_INTERRUPT_SAVE_AREA                  unsigned int interrupt_save;
  132. #define TX_DISABLE                              interrupt_save = __disable_interrupts();
  133. #define TX_RESTORE                              __restore_interrupt(interrupt_save);

  134. /*** End AC5 ***/

  135. #endif  /* Interrupt disable/restore macros for each compiler. */

  136. /* Redefine _tx_thread_system_return for improved performance.  */

  137. #define _tx_thread_system_return                _tx_thread_system_return_inline


  138. #else   /* TX_DISABLE_INLINE is defined */

  139. UINT                                            _tx_thread_interrupt_disable(VOID);
  140. VOID                                            _tx_thread_interrupt_restore(UINT previous_posture);

  141. #define TX_INTERRUPT_SAVE_AREA                  register UINT interrupt_save;

  142. #define TX_DISABLE                              interrupt_save = _tx_thread_interrupt_disable();
  143. #define TX_RESTORE                              _tx_thread_interrupt_restore(interrupt_save);
  144. #endif  /* TX_DISABLE_INLINE */
复制代码


回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115896
QQ
 楼主| 发表于 2021-6-8 10:45:44 | 显示全部楼层
下面这个是我之前自己做的:

ThreadX内核的开关中断使用BasePri实现方法,支持AC5,AC6,MDK和GCC
http://www.armbbs.cn/forum.php?m ... 6733&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

48

主题

376

回帖

520

积分

金牌会员

积分
520
发表于 2024-6-28 13:51:08 | 显示全部楼层
硬汉你好,这个特性如何理解,是不是不受ThreadX管理的中断处理函数,不再进行退出时自动调度吗?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115896
QQ
 楼主| 发表于 2024-6-29 08:36:00 | 显示全部楼层
wanglehui_12 发表于 2024-6-28 13:51
硬汉你好,这个特性如何理解,是不是不受ThreadX管理的中断处理函数,不再进行退出时自动调度吗?

OS内核里面有些临界的地方有开关全局中断的处理,使用了BASEPRI后,内核里面开关全局中断的地方,就不会关闭不受ThreadX控制的更高优先级中断,从而让这些中断实现零中断延迟。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-25 14:30 , Processed in 0.291934 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表