gpt4 book ai didi

c - 何时在驱动程序代码中使用 stdint.h 的标量

转载 作者:太空狗 更新时间:2023-10-29 11:03:37 55 4
gpt4 key购买 nike

我注意到,在使用 native 标量类型(整数、短整型、字符)或 stdint 提供的标量类型时似乎没有一致性或最佳实践:uint32_t uint16_t uint8_t。

这让我很烦恼,因为驱动程序是内核的重要组成部分,需要可维护、一致、稳定和良好。

这是 gcc 中的一个说明性示例(用于树莓派的业余项目):

// using native scalars
struct fbinfo {
unsigned width, height;
unsigned vwidth, vheight;
unsigned pitch, bits;
int x, y;
void *ptr;
unsigned size;
} __attribute__((aligned(16)));

// using stdint scalars
struct fbinfo {
uint32_t width, height;
uint32_t vwidth, vheight;
uint32_t pitch, bits;
int32_t x, y;
uint32_t ptr; // convert to void* in order to use it
uint32_t size;
} __attribute__((aligned(16)));

对我来说,第一个例子似乎更符合逻辑,因为这段代码仅适用于在树莓派上运行。跑是没有意义的这在其他硬件上。

第二个例子看起来更实用,因为它看起来更描述性的,因为 C 不能保证整数的大小。它可能是 16 位或其他。 uint32_t、uint_fast32_t 和变体保证了精确或近似的大小:例如至少或最多 X 字节。

操作系统开发社区倾向于使用 stdint 类型,而 linux 内核使用多种不同的技术:u32、__u32 和 endian 特定的东西,如 __le32。

何时选择标量类型以及何时使用 typedef 的标量类型应考虑哪些因素?在提供的示例中使用 native 标量类型还是使用 stdint.h 更好?

最佳答案

1。修复与基本类型

固定宽度的字体有时很难使用。例如。 int32_tprintf() 说明符是 PRIi32 并且需要拆分格式字符串:

printk("foo=" PRIi32 ", bar=" PRIi32 "\n", foo, bar);

当直接访问硬件时,应该/必须使用固定宽度的类型;例如写 DMA 描述符时。但是对于简单的寄存器访问,可以使用 writel()readl() 函数来处理基本类型。

根据经验,当假定某种内存布局时(如示例中的 __attribute__((__aligned__(16))),应使用固定宽度类型。

带符号的固定宽度类型(在您的示例中为 int32_t x,y)可能需要仔细检查它们的表示是否符合硬件预期。

注意在您的示例中,第二个结构是架构相关的,因为

    uint32_t ptr; // convert to void* in order to use it

在普通 C 中写这样的东西是 uintptr_t ptr 并且在内核中它是常见的写

    unsigned long ptr;

或者,dma_addr_t 可能是更好的类型。

2。 uint32_t__u32

10 多年前,Linus Torvalds 反对 uint32_t,因为当时非 C99 编译器很普遍,在(导出的)linux 头文件中使用此类类型会污染命名空间。

但是现在,uint32_t 和类似的类型随处可见(您不能使用非 C99 编译器编译内核)并且内核头文件导出已得到显着改进,因此这些参数已消失。

使用标准类型还是使用 typedef 变体(依赖于框架并且它们之间存在差异)是个人偏好问题。

3。 uint_fastX_t 和变体

它们不在内核中使用,我会避免使用它们。它们结合了 uint32_t(难以使用)和 int(可变宽度)的缺点。

4。 __le32__u32

在规范明确要求时使用字节序类型(例如在网络协议(protocol)实现中)。这使得检测错误用法变得容易(例如,endian_variable = native_variable 之类的赋值)。

不要使用它们,例如用于填充处理器结构(例如 DMA 描述符);一些处理器可以在小端模式和大端模式下运行,并且 native 数据类型通常是编写此类信息的正确方式。

关于c - 何时在驱动程序代码中使用 stdint.h 的标量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39417675/

55 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com