了解宏行为和原线程
Understanding Macro behavior and protothreads
在此先感谢您的帮助。
首先是前言。我一直在考虑使用 https://github.com/contiki-os/contiki/tree/master/core/net/mac/tsch 中给出的 Contiki TSCH 实现。虽然 运行 Cooja 模拟器中的一个简单示例(我已将一些日志消息添加到基本代码中,以便我可以看到发生了什么),但我注意到 ASN 计数器没有递增其最高有效字节。
具体来说,ASN(TSCH 的绝对时隙号)由结构给出
// data type of absolute slot number
struct tsch_asn_t {
uint32_t ls4b; /* least significant 4 bytes */
uint8_t ms1b; /* most significant 1 byte */
};
and 本质上可以被认为是一个索引值,表示为两个变量,最高有效字节和最低有效 4 字节。以下宏用于按设定数量递增 ASN。
// Here is the macro
#define TSCH_ASN_INC(asn, inc) do { \
printf("TSCH INC1: new UNDEF, old %u, inc %u\n", (asn).ls4b, inc); \
\
uint32_t new_ls4b = (asn).ls4b + (inc); \
\
printf("TSCH INC2: new %u, old %u, inc %u\n",new_ls4b, (asn).ls4b, inc); \
\
if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \
\
printf("TSCH INC3: new %u, old %u, inc %u\n",new_ls4b, (asn).ls4b, inc); \
\
(asn).ls4b = new_ls4b; \
\
printf("TSCH INC4: new %u, old %u, inc %u\n",new_ls4b, (asn).ls4b, inc); \
} while(0);
暂时忽略 printf 语句(我添加这些语句是为了试图理解发生了什么)。据我了解这个宏,发生的是最不重要的字节首先递增。然后,如果最低有效字节环绕最高有效字节则递增。但是,在查看发生的事情的日志时,我注意到当最不重要的字节环绕时,最重要的字节没有增加。
现在回答我的实际问题。为了确定为什么最高有效字节没有递增,我将上面的打印语句添加到宏中,并在实际宏调用的上方和下方添加了打印语句,如下所示(注意 ASN 由 tsch_current_asn 和 timeslot_diff 是我要增加 ASN 的数量)。
printf("TSCH INC BEFORE: ms1b %u, ls4b %u, inc %u\n",tsch_current_asn.ms1b, tsch_current_asn.ls4b, timeslot_diff);
TSCH_ASN_INC(tsch_current_asn, timeslot_diff);
printf("TSCH INC AFTER: ms1b %u, ls4b %u, inc %u\n",tsch_current_asn.ms1b, tsch_current_asn.ls4b, timeslot_diff);
这样做产生了以下日志,这绝对让我难过
// LOG
TIME DEVID LOG MSG
00:28.885 ID:1 TSCH INC BEFORE: ms1b 0, ls4b 1877, inc 0
00:28.888 ID:1 TSCH INC1: new UNDEF, old 1877, inc 0
00:28.891 ID:1 TSCH INC2: new 1878, old 0, inc 1877
00:28.895 ID:1 TSCH INC3: new 1878, old 0, inc 1877
00:28.898 ID:1 TSCH INC4: new 1878, old 0, inc 1878
00:28.901 ID:1 TSCH INC AFTER: ms1b 0, ls4b 1878, inc 0
具体来说,似乎在宏 inc (timeslot_diff) 的第一条和第二条 printf 语句之间从 0 更改为 1877。换句话说,在我看来语句
uint32_t new_ls4b = (asn).ls4b + (inc); \
更改了 inc 的值(timeslot_diff)。此外,在我看来,此声明将 ans.ls4b (tsch_current_asn.ls4b) 从 1877 更改为 0.
关于宏是如何工作的,我是否有一个高级的时刻可以说,或者这是 Contiki 的原线程的影响(即被挂起然后恢复)?
供参考,宏调用的实际代码在第 1035 行给出
https://github.com/contiki-os/contiki/blob/master/core/net/mac/tsch/tsch-slot-operation.c and the macro is given on line 67 of https://github.com/contiki-os/contiki/blob/master/core/net/mac/tsch/tsch-asn.h.
在 16 位体系结构上,printf 说明符和实际参数类型之间似乎不匹配。建议对来自 stdint.h
的所有整数类型使用在 inttypes.h
中定义为格式宏常量的说明符
即当 x
是 uint32_t
类型时,你应该使用
printf("x is %"PRIu32" \n", x);
而不是
printf("x is %u \n", x);
在此先感谢您的帮助。
首先是前言。我一直在考虑使用 https://github.com/contiki-os/contiki/tree/master/core/net/mac/tsch 中给出的 Contiki TSCH 实现。虽然 运行 Cooja 模拟器中的一个简单示例(我已将一些日志消息添加到基本代码中,以便我可以看到发生了什么),但我注意到 ASN 计数器没有递增其最高有效字节。
具体来说,ASN(TSCH 的绝对时隙号)由结构给出
// data type of absolute slot number
struct tsch_asn_t {
uint32_t ls4b; /* least significant 4 bytes */
uint8_t ms1b; /* most significant 1 byte */
};
and 本质上可以被认为是一个索引值,表示为两个变量,最高有效字节和最低有效 4 字节。以下宏用于按设定数量递增 ASN。
// Here is the macro
#define TSCH_ASN_INC(asn, inc) do { \
printf("TSCH INC1: new UNDEF, old %u, inc %u\n", (asn).ls4b, inc); \
\
uint32_t new_ls4b = (asn).ls4b + (inc); \
\
printf("TSCH INC2: new %u, old %u, inc %u\n",new_ls4b, (asn).ls4b, inc); \
\
if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \
\
printf("TSCH INC3: new %u, old %u, inc %u\n",new_ls4b, (asn).ls4b, inc); \
\
(asn).ls4b = new_ls4b; \
\
printf("TSCH INC4: new %u, old %u, inc %u\n",new_ls4b, (asn).ls4b, inc); \
} while(0);
暂时忽略 printf 语句(我添加这些语句是为了试图理解发生了什么)。据我了解这个宏,发生的是最不重要的字节首先递增。然后,如果最低有效字节环绕最高有效字节则递增。但是,在查看发生的事情的日志时,我注意到当最不重要的字节环绕时,最重要的字节没有增加。
现在回答我的实际问题。为了确定为什么最高有效字节没有递增,我将上面的打印语句添加到宏中,并在实际宏调用的上方和下方添加了打印语句,如下所示(注意 ASN 由 tsch_current_asn 和 timeslot_diff 是我要增加 ASN 的数量)。
printf("TSCH INC BEFORE: ms1b %u, ls4b %u, inc %u\n",tsch_current_asn.ms1b, tsch_current_asn.ls4b, timeslot_diff);
TSCH_ASN_INC(tsch_current_asn, timeslot_diff);
printf("TSCH INC AFTER: ms1b %u, ls4b %u, inc %u\n",tsch_current_asn.ms1b, tsch_current_asn.ls4b, timeslot_diff);
这样做产生了以下日志,这绝对让我难过
// LOG
TIME DEVID LOG MSG
00:28.885 ID:1 TSCH INC BEFORE: ms1b 0, ls4b 1877, inc 0
00:28.888 ID:1 TSCH INC1: new UNDEF, old 1877, inc 0
00:28.891 ID:1 TSCH INC2: new 1878, old 0, inc 1877
00:28.895 ID:1 TSCH INC3: new 1878, old 0, inc 1877
00:28.898 ID:1 TSCH INC4: new 1878, old 0, inc 1878
00:28.901 ID:1 TSCH INC AFTER: ms1b 0, ls4b 1878, inc 0
具体来说,似乎在宏 inc (timeslot_diff) 的第一条和第二条 printf 语句之间从 0 更改为 1877。换句话说,在我看来语句
uint32_t new_ls4b = (asn).ls4b + (inc); \
更改了 inc 的值(timeslot_diff)。此外,在我看来,此声明将 ans.ls4b (tsch_current_asn.ls4b) 从 1877 更改为 0.
关于宏是如何工作的,我是否有一个高级的时刻可以说,或者这是 Contiki 的原线程的影响(即被挂起然后恢复)?
供参考,宏调用的实际代码在第 1035 行给出 https://github.com/contiki-os/contiki/blob/master/core/net/mac/tsch/tsch-slot-operation.c and the macro is given on line 67 of https://github.com/contiki-os/contiki/blob/master/core/net/mac/tsch/tsch-asn.h.
在 16 位体系结构上,printf 说明符和实际参数类型之间似乎不匹配。建议对来自 stdint.h
inttypes.h
中定义为格式宏常量的说明符
即当 x
是 uint32_t
类型时,你应该使用
printf("x is %"PRIu32" \n", x);
而不是
printf("x is %u \n", x);