硬汉嵌入式论坛

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

[ThreadX全家桶] 关于ThreadX临界区嵌套的疑问

[复制链接]

2

主题

4

回帖

10

积分

新手上路

积分
10
发表于 2021-8-24 15:33:55 | 显示全部楼层 |阅读模式
最近在研究使用Cube MX(版本6.3.0)生成ThreadX(版本6.1.7)代码,毕竟对于ST的片子来说,Cube MX绝对是个神器。结合硬汉写的ThreadX教程,收获颇丰,但还是有几个问题没整明白,特发帖请教下大佬:
1.ThreadX 进入临界区使用TX_DISABLE,默认关全部中断。追进去看了下源码,这个不像Free ROTS那样支持临界区嵌套。如果用户代码里有嵌套的情况如果解决?还是说ThreadX本身就不允许临界区嵌套使用?
2.没有找到专门的开关调度器的API,内核里好像用的是_tx_thread_preempt_disable++/--,不是知道用户代码里直接这么用有没有什么风险?
3.ThreadX 中没有空闲任务,如果用户也没有创建,那系统在空闲时执行什么代码呢?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115812
QQ
发表于 2021-8-24 16:22:25 | 显示全部楼层
1、支持嵌套。
#define TX_INTERRUPT_SAVE_AREA unsigned int was_masked;
#define TX_DISABLE was_masked = __disable_irq();
#define TX_RESTORE if (was_masked == 0) __enable_irq();

2、ThreadX特有的调度阀值就可以方便实现。
3、创建不创建都行,创建的话,里面整个while(1){} 即可,什么都不用做。
回复

使用道具 举报

2

主题

4

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2021-8-24 17:29:58 | 显示全部楼层
本帖最后由 wJw 于 2021-8-24 18:38 编辑
eric2013 发表于 2021-8-24 16:22
1、支持嵌套。
#define TX_INTERRUPT_SAVE_AREA unsigned int was_masked;
#define TX_DISABLE was_maske ...

感谢硬哥,我看了下6.1.7内核改了。。。至少CubeMX生成的代码里是这样的,
源码:
  1. #define TX_INTERRUPT_SAVE_AREA                  unsigned int interrupt_save;
  2. #define TX_DISABLE                              interrupt_save =  __disable_interrupts();
  3. #define TX_RESTORE                              __restore_interrupt(interrupt_save);
复制代码

自己画了下调用图: ThreadX临界区.png

啃了半天汇编,大体明白了套路:
1.调用TX_DISABLE 的时候,会先读取当前PRIMASK的状态并保存,然后用CPSID指令关中断;
2.等调用TX_RESTORE  的时候,会直接恢复之前保存的PRIMASK。也就是说如果关中断前PRIMASK就是1了,无论调用多少次TX_RESTORE,都无法将PRIMASK置0,也就无法开中断!
3.最终开中断的地方,是在调用阻塞代码时,从_tx_thread_system_return_inline里用CPSIE开的中断。
我实际测了下,确实是这样的。而Free RTOS是用uxCriticalNesting变量,支持多级嵌套,这个和那个不一样,不改源码的话,用起来无从下手了。。。不知道新版本为什么这么改,没道理啊!
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115812
QQ
发表于 2021-8-25 10:02:16 | 显示全部楼层
wJw 发表于 2021-8-24 17:29
感谢硬哥,我看了下6.1.7内核改了。。。至少CubeMX生成的代码里是这样的,
源码:

你的测试或者说你的理解有偏差。

这种嵌套方式的关键就是 TX_INTERRUPT_SAVE_AREA 这个变量,灵活性更强。每对开关中断都会定义这么一个变量,而不是共用这一个变量。所以多少级嵌套都不会有问题的。
回复

使用道具 举报

2

主题

4

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2021-8-25 15:25:12 | 显示全部楼层
eric2013 发表于 2021-8-25 10:02
你的测试或者说你的理解有偏差。

这种嵌套方式的关键就是 TX_INTERRUPT_SAVE_AREA 这个变量,灵活性更 ...

也就是说,TX_DISABLE /TX_RESTORE  必须成对使用,在一个TX_INTERRUPT_SAVE_AREA 下,不可以连续调用两次TX_DISABLE 。如果有函数调用,在子函数里再定义一个TX_INTERRUPT_SAVE_AREA 这样嵌套下去,这么理解对吧?可能是Free RTOS用久了,感觉还是那种的嵌套方式习惯些。。。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115812
QQ
发表于 2021-8-26 08:03:48 | 显示全部楼层
wJw 发表于 2021-8-25 15:25
也就是说,TX_DISABLE /TX_RESTORE  必须成对使用,在一个TX_INTERRUPT_SAVE_AREA 下,不可以连续调用两 ...

ThreadX和uCOS-III的玩法是一样的。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-21 01:11 , Processed in 0.324249 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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