CosyOS 发表于 2024-10-26 00:43:15

本帖最后由 CosyOS 于 2024-10-26 00:46 编辑

sdwys 发表于 2024-10-25 22:49
/* 查询标志组 */
#define      sTSV_QueryFlagGroup(group) \
( \

#define sTSV_QueryFlagGroup(group) \
( \
          sizeof(group) == 1 ? *(s_u8_t*)&group ? true : false \
      : sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false \
      : sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false \
      : false \
)

我给你换一种写法来理解它的层次结构:
if(sizeof(group) == 1){
      *(s_u8_t*)&group ? true : false
}
else{
      if(sizeof(group) == 2){
                *(s_u16_t *)&group ? true : false
      }
      else{
                if(sizeof(group) == 4){
                        *(s_u32_t *)&group ? true : false
                }
                else{
                        false
                }
      }
}
这个写法只是为了让你好理解运算优先级、语句结构,实际这样写是非法的。
必须采用全部三目运算的写法,
原因是:
1、需要返回值
2、三目运算可实现常量优化

sizeof()也是常量优化的,所以最终优化后的结果就是:
假设 sizeof(group) 为 2,
sTSV_QueryFlagGroup(group) 被宏替换后为:*(s_u16_t *)&group ? true : false

所以,看似一大堆代码,被编译器优化后仅有一句C代码,其它都被优化掉了。

stb988 发表于 2024-10-26 09:07:14

打卡学习中,

mengzehua 发表于 2024-10-27 10:56:53

请好,我下载附件的例程,用Keil uVision5 C251无法编译,打开实验箱的例程能编译,就这个RTOS不能编译,能告诉我是用什么软件或者哪个版本来打开吗?

CosyOS 发表于 2024-10-27 12:03:19

mengzehua 发表于 2024-10-27 10:56
请好,我下载附件的例程,用Keil uVision5 C251无法编译,打开实验箱的例程能编译,就这个RTOS不能编译,能 ...

看下你下载的是哪个例程?
例程有 STC8H 的,有 STC32G 的,
STC8H 用 Keil uVision5 C51,
STC32G 用 Keil uVision5 C251,
版本应该别太老就行。
例程都是经过实测的,你可能哪里没搞对。

mengzehua 发表于 2024-10-27 21:35:20

好的,谢谢,我找到原因了,我下载的是STC8例程,我没有安装STC8的型号和头文件,所以无法编译,下载STC32G例程,就就可以打开编译了,我先看你的视频和学习,谢谢了

sdwys 发表于 2024-10-27 21:57:02

CosyOS 发表于 2024-10-26 00:43
#define sTSV_QueryFlagGroup(group) \
( \
          sizeof(group) == 1 ? *(s_u8_t*)&group ? true : ...

这种写法我百度查了好久,没找到相关资料,这个是宏预处理器支持的一种写法吗?还请作者解惑。

CosyOS 发表于 2024-10-28 00:06:39

本帖最后由 CosyOS 于 2024-10-28 03:16 编辑

sdwys 发表于 2024-10-27 21:57
这种写法我百度查了好久,没找到相关资料,这个是宏预处理器支持的一种写法吗?还请作者解惑。
...

首先是了解 三目运算。
(条件表达式) ? 表达式1 : 表达式2;
如果条件表达式为真,执行表达式1并返回结果;
否则,执行表达式2并返回结果。
如果 表达式1 或 表达式2 无法返回结果,有些编译器不能支持。
如a > b ? 1 : _nop_();
空操作的执行结果是无值的,无法返回结果,有些编译器不能支持这种写法。


然后是 三目运算 可进行常量优化。
这指的是 三目运算可对条件判断和执行分支进行常量优化。也就是说
在编译时,如果条件表达式能直接确定为真或为假,直接选择表达式1或表达式2,其它全部优化掉。


三是如何理解这种写法的运算优先级或是语句结构。
为了能更好的表述,先做如下处理,加括号是为了便于区分,不用真写:
#define sTSV_QueryFlagGroup(group) \
      (sizeof(group) == 1 ? *(s_u8_t*)&group ? true : false \
      : (sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false \
      : (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false \
      : false)))

由于 == 的优先级高于 三目运算 ? : 的优先级,所以,
sizeof(group) == 1 等,结合到一起;

由于三目运算是从右到左结合,所以从最后向前结合,
                                                                               : false
      : false
两个 : 结合不了,而后,      *(s_u32_t *)&group ? true : false
可结合为一组三目运算;

而后再结合,
       (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
      : false)
可结合为一组三目运算;

而后再结合,
                                                                              : false
      : (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
      : false)
两个 : 结合不了,而后,       *(s_u16_t *)&group ? true : false
可结合为一组三目运算;

而后再结合,
      (sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false
      : (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
      : false))
可结合为一组三目运算;

而后再结合,
                                                                              : false
      : (sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false
      : (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
      : false))
两个 : 结合不了,而后,       *(s_u8_t*)&group ? true : false
可结合为一组三目运算;

而后再结合,
          (sizeof(group) == 1 ? *(s_u8_t*)&group ? true : false
      : (sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false
      : (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
      : false)))
可结合为一组三目运算;

所以,这就是单纯的三目运算,只是如何结合,如何划分语句结构的问题。


-- 全剧终 --


可累   我了。。。

当然,再就是实验验证。
可以不用标志组,分别弄3个全局变量,分别为 u8、u16、u32 的,
然后分别调用,编译,看反汇编到底都做了什么?



Matrix 发表于 2024-10-28 10:58:05

非常不错 ,国产原创 RTOS for 32位8051,STC32G12K128

CosyOS 发表于 2024-10-28 14:15:20

CosyOS 发表于 2024-10-28 00:06
首先是了解 三目运算。
(条件表达式) ? 表达式1 : 表达式2;
如果条件表达式为真,执行表达式1并返回结果 ...

由此,我们可以采用 if else 语句 来理解上述的 三目运算的语句结构,
这样层次结构就会非常清晰,如下:

if(sizeof(group) == 1){
      *(s_u8_t*)&group ? true : false;
}
else{
      if(sizeof(group) == 2){
                *(s_u16_t *)&group ? true : false;
      }
      else{
                if(sizeof(group) == 4){
                        *(s_u32_t *)&group ? true : false;
                }
                else{
                        false;
                }
      }
}

但 if else 语句 只是为了使语句结构清晰起来,能一目了然,
对于 sTSV_QueryFlagGroup(group) 等相关服务的应用,
还必须采用全部三目运算的写法。



DIY365 发表于 2024-10-29 14:41:15

CosyRTOS-STC8H
串口1接收中断没开启吗?
我打印接收数据,显示是串口2接收到的数据
串口1发送,并没有反应
页: 83 84 85 86 87 88 89 90 91 92 [93] 94 95 96 97 98 99 100 101 102
查看完整版本: 全局不关总中断的 RTOS,CosyOS-III-V1.2.0, 送 擎天柱-AI8051U转89C52核心板