【发布时间】:2018-05-28 09:25:31
【问题描述】:
如何改进以下代码,即使用 Linux 内核 API 中的函数和宏使其在类型安全和字节序方面更加健壮?例如,在以下示例中,src_data 是一个由两个 16 位有符号整数组成的数组(通常以小端顺序存储),并将通过 UART 以大端字节顺序发送。
s16 src_data[2] = {...}; /* note: this is signed data! */
u8 tx_data[4];
u8* src_data_u8 = (u8*)src_data;
tx_data[0] = src_data_u8[1];
tx_data[1] = src_data_u8[0];
tx_data[2] = src_data_u8[3];
tx_data[3] = src_data_u8[2];
我认为函数cpu_to_be16 和cpu_to_be16p 应该在这种转换中发挥作用。虽然我不确定如何以一种安全且对字节顺序稳健的方式使用它们。
【问题讨论】:
-
您要解决的问题到底是什么,您链接的头文件中的 cmets 对您没有帮助?让您的问题更具体。
-
如果您编写这样的代码,请注意传入协议的反序列化。你不能通过使用指针转换从让我们说
u8 rx_data[4]到s16 [2]- 这将是一个严格的别名违规。您可以在这里逃脱它,因为您从“任何类型”变为字符类型,这是一种特殊的允许情况。 -
@MichaelFoukarakis 头文件中的函数/宏似乎不安全,因为它们只接受无符号参数......此外,我不清楚如何在放置之前安全地存储中间结果转换后的数据到我的
u8 tx_data数组中... -
感谢@0andriy 的输入,协议固定为大端,目标机器(AVR)为小端。据我了解,在实践中,几乎所有基于 Linux 的机器也是小端的,但尽管如此,我想知道如何以一种干净、独立于平台的方式实现这种转换。
-
@0andriy 很明显,您一生中从未编写过一行与硬件相关的编程。抱歉,但 TCP/IP 套接字不是硬件,它是第 3 层和第 4 层左右。我每天都在为嵌入式系统编写驱动程序,并且在过去 15 年中一直这样做,但感谢您分享您从未使用过的东西的智慧。
标签: linux-kernel endianness memory-alignment