Fujitsu Softune 中的奇怪问题 IDE - 11 位 CAN ID 计算错误
Weird problem in Fujitsu Softune IDE - wrong calculation of 11 bit CAN ID
下面的代码是我在 Rx 回调中读取 CAN ID 的代码的一部分:
tmpp = (((0x07 << 0x1D)|(0x368 << 0x12)) & 0x1FFC0000); //unsigned long long int tmpp - equal to 0xDA00000
if (CAN0_IF2ARB0_ID == tmpp) {
//do some action
}
问题在于,虽然 29 位 CAN ID 是 0xDA00000,但条件不成立。但是当我直接设置tmpp为tmpp = 0xDA00000
时,程序成功进入了循环。其实计算tmpp = (((0x07 << 0x1D)|(0x368 << 0x12)) & 0x1FFC0000);
好像有点问题(数值是0xDA00000,但是在Softune中,计算不正确)。如果您能帮助我找到问题所在,我将不胜感激。谢谢
0x07
是一个 int
- 甚至可能是一个 16 位 int
。至少使用 unsigned long
个常量来将值转换为 32 位值。
// tmpp = (((0x07 << 0x1D)|(0x368 << 0x12)) & 0x1FFC0000);
tmpp = ((0x07ul << 0x1D) | (0x368ul << 0x12)) & 0x1FFC0000u;
Left-shifting 像 1
这样的整数常量几乎总是一个错误,因为 C 中的整数常量和变量一样有类型,在大多数情况下它是 int
。现在,由于 int
是有符号类型,我们不能将数据左移到符号位,否则我们会调用未定义的行为。 0x07 << 0x1D
正是这样做的,它将数据移入位 31(符号位)、30 和 29。
通过始终为所有整数常量添加 u
后缀来解决此问题。
此外,您不应该使用“幻数”,而应该使用命名常量。如果您打算移动 29 位,请使用十进制表示法 29
因为那是 self-documenting 代码。
您的固定代码应如下所示(用有意义的内容替换“MASKn”):
#define MASK1 (0x07u << 29)
#define MASK2 (0x368u << 18)
#define MASK3 (MASK1 | MASK2)
#define MASK4 0x1FFC0000u
if (CAN0_IF2ARB0_ID == (MASK3 & MASK4))
另外,扩展 CAN 标识符不使用 31、30、29 位...所以我什至不知道您在这里做什么。如果你想为 CAN 接受过滤等计算一些值,那么你似乎已经设法通过最初使用十六进制常量进行移位来混淆自己。
下面的代码是我在 Rx 回调中读取 CAN ID 的代码的一部分:
tmpp = (((0x07 << 0x1D)|(0x368 << 0x12)) & 0x1FFC0000); //unsigned long long int tmpp - equal to 0xDA00000
if (CAN0_IF2ARB0_ID == tmpp) {
//do some action
}
问题在于,虽然 29 位 CAN ID 是 0xDA00000,但条件不成立。但是当我直接设置tmpp为tmpp = 0xDA00000
时,程序成功进入了循环。其实计算tmpp = (((0x07 << 0x1D)|(0x368 << 0x12)) & 0x1FFC0000);
好像有点问题(数值是0xDA00000,但是在Softune中,计算不正确)。如果您能帮助我找到问题所在,我将不胜感激。谢谢
0x07
是一个 int
- 甚至可能是一个 16 位 int
。至少使用 unsigned long
个常量来将值转换为 32 位值。
// tmpp = (((0x07 << 0x1D)|(0x368 << 0x12)) & 0x1FFC0000);
tmpp = ((0x07ul << 0x1D) | (0x368ul << 0x12)) & 0x1FFC0000u;
Left-shifting 像 1
这样的整数常量几乎总是一个错误,因为 C 中的整数常量和变量一样有类型,在大多数情况下它是 int
。现在,由于 int
是有符号类型,我们不能将数据左移到符号位,否则我们会调用未定义的行为。 0x07 << 0x1D
正是这样做的,它将数据移入位 31(符号位)、30 和 29。
通过始终为所有整数常量添加 u
后缀来解决此问题。
此外,您不应该使用“幻数”,而应该使用命名常量。如果您打算移动 29 位,请使用十进制表示法 29
因为那是 self-documenting 代码。
您的固定代码应如下所示(用有意义的内容替换“MASKn”):
#define MASK1 (0x07u << 29)
#define MASK2 (0x368u << 18)
#define MASK3 (MASK1 | MASK2)
#define MASK4 0x1FFC0000u
if (CAN0_IF2ARB0_ID == (MASK3 & MASK4))
另外,扩展 CAN 标识符不使用 31、30、29 位...所以我什至不知道您在这里做什么。如果你想为 CAN 接受过滤等计算一些值,那么你似乎已经设法通过最初使用十六进制常量进行移位来混淆自己。