【发布时间】:2022-11-27 04:26:48
【问题描述】:
我一直在尝试编写一个函数来解码 C 中的 CAN 字节,同时考虑到传入值的字节序和系统的字节序。现在,它适用于无符号值,但对有符号值很糟糕。
我有一种感觉,我深深地误解了 C 中签名表示的工作方式——我假设 MSB 是签名数据的符号标志(即 Little Endian 的最后一个字节,Big Endian 的第一个字节)。谁能看看我下面的功能,让我知道我做错了什么?
/**
* @brief can_interact_decode - converts array of length x containing hex bytes into a uint64
* @param[in] const uint8_t* - const array of hex bytes
* @param[in] const size_t - length of hex bytes array
* @param[in] const enum can_interact_signedness - whether the bytes are storing a signed value or not. SIGNED_VAL indicates signed, UNSIGNED_VAL indicates unsigned
* @param[in] const enum can_interact_endianness - endianess. LITTLE_ENDIAN_VAL is little, BIG_ENDIAN_VAL is big
* @return[out] uint64_t - interpreted value as unsigned int from hex bytes, taking other params into account
*/
uint64_t can_interact_decode(const uint8_t *payload, const size_t data_len, const enum can_interact_signedness is_signed, const enum can_interact_endianness byte_order)
{
uint64_t result; /* [0,0,0,0,0,0,0,0] */
uint8_t* blocks; /* array of 8 */
result = 0;
blocks = (uint8_t*)(&result);
if(byte_order == LITTLE_ENDIAN_VAL) {
memcpy(blocks, payload, (is_signed ? data_len - 1 : data_len));
blocks[7] = is_signed ? payload[data_len - 1] : blocks[7];
result = le64toh(result); /* little endian->host byte order */
} else if(byte_order == BIG_ENDIAN_VAL) {
memcpy(blocks + (8 - data_len) + (is_signed ? 1 : 0), (is_signed ? payload + 1 : payload), (is_signed ? data_len - 1 : data_len));
blocks[0] = is_signed ? payload[0] : blocks[0];
result = be64toh(result); /* big endian->host byte order */
}
return result;
}
【问题讨论】:
-
"Little Endian 的最后一个字节,Big Endian 的第一个字节" --> 符号少量, 不是字节, 是那些字节的一部分。
-
data_len是否大于 8?还是小于 1? -
不,不是。我将添加 ifs 等检查此类内容。为其他功能编写一个库,实际上我已经把所有的东西都写在那里了,但此时只是想专注于基本功能 @chux-ReinstateMonica
-
啊。我看到我的错误。如果你这么好心,你会如何提取最重要的少量从一个字节?我猜想与 << 或 >> 运营商有关? @chux-恢复莫妮卡
-
你是说
(int8_t) payload[data_len - 1] < 0?
标签: c hex endianness can-bus