【问题标题】:What static struct in linux kernel code use forlinux内核代码中的静态结构用于什么
【发布时间】:2020-08-23 14:34:41
【问题描述】:

您好,我正在按照 Linux 设备驱动程序开发一书在 Linux 中编写驱动程序。示例代码如下:

struct my_gpios {
    int reset_gpio;
    int led_gpio;
};
static struct my_gpiosneeded_gpios = {
    .reset_gpio = 47;
    .led_gpio = 41;
};

static struct resource needed_resources[] = {
    [0] = { /* The first memory region */
    .start = JZ4740_UDC_BASE_ADDR,
    .end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
    .flags = IORESOURCE_MEM,
    .name = "mem1",
},
    [1] = {
    .start = JZ4740_UDC_BASE_ADDR2,Platform Device Drivers
    [ 126 ]
    .end = JZ4740_UDC_BASE_ADDR2 + 0x10000 -1,
    .flags = IORESOURCE_MEM,
    .name = "mem2",
},
};
static struct platform_devicemy_device = {
    .name = "my-platform-device",
    .id = 0,
    .dev = {
    .platform_data = &needed_gpios,
},
    .resource = needed_resources,
    .num_resources = ARRY_SIZE(needed_resources),
};
platform_device_register(&my_device);

我不明白static struct_gpiosneeded_gpios = {} 的语法含义以及为什么.reset_gpio 中有一个点。语法static struct [] = {[0]={}, [1]={}} 的含义是什么?

能否给我一个关于static struct {.a = VALUE, .b = VALUE,}; 的参考链接或关键字或示例?

【问题讨论】:

  • 它只是为那些命名字段指定初始化值。
  • 如果你还没有 C 的经验,你真的不应该编写设备驱动程序。为了你自己的利益,在开始内核编程之前,先做一些 C 用户空间开发的练习。
  • 谢谢你的解释链接,当我阅读linux的驱动代码时,我看到许多奇怪的语法是“u32”,“__raw”,......我不明白他们为什么命名类型是“u32”或“__raw”的目的是什么。是否有任何标准或规则来命名内核中的变量、宏、类型……?在 linux 驱动程序中编写代码时我必须遵守什么 C 标准?
  • 第 5 行有错字吗?我认为您缺少一个空格,它应该是static struct my_gpios needed_gpios = {。然后它将定义一个名为needed_gpios、类型为struct my_gpios、存储持续时间为static 的对象,并对其进行初始化,这一切都有意义。正如所写,这是一个语法错误。 static struct platform_devicemy_device 也是如此。

标签: c linux struct syntax linux-kernel


【解决方案1】:
static struct something x = {
    .field_one = 123,
    .field_two = 456
};

这是 struct 初始化语法,来自 C99 (see here) 的标准。此示例创建一个名为 x 的类型为 struct something 的变量,其中字段 field_onefield_two 初始化为指定值,任何其他字段初始化为 0static 关键字是存储持续时间说明符 (see here)。


static struct something x[] = {[0]={ ... }, [1]={ ... }};

这是 struct 初始化和数组初始化语法的混合,同样是 C99 的标准 (see here)。这个例子创建了一个包含struct something 类型变量的数组x,索引0 的变量使用{...} 初始化程序的内容进行初始化,索引1 的变量也是如此。由于最大指定索引为1,因此数组大小为2


我不明白为什么他们将类型命名为u32 或者__raw 的目的是什么。

u32 类型只是uint32_t 的简短别名。

我不确定您在哪里看到__raw,因为我似乎在内核源代码中找不到类似的东西。在任何情况下,Linux 内核作为一系列编译时注释用于具有不同用途的变量(__user__rcu 等)。这些不是 C 标准的一部分,通常甚至不是 GCC 扩展。它们主要是供 Linux 内核语义检查器 Sparse 使用的提示。

内核中变量、宏、类型、...的命名有什么标准或规则吗?

有关详细信息,请参阅 Linux kernel coding style 文档页面。我建议您在尝试进行任何类型的内核编程之前阅读全部内容。您阅读的文档页面越多越好。

在 linux 驱动程序中编写代码时我必须遵守哪些 C 标准?

使用 C99 或更高版本的任何东西都可以。 Linux 内核代码不遵循单一的 C 标准,并且代码的各个部分甚至不符合标准,而是使用 GCC 扩展。请参阅here 了解更多信息。

编译的时候一般不用选择标准,内核Makefile会帮你搞定的,应该默认C90。


无论如何,这些都是很多问题。如果您有一个具体的问题,我建议您单独提问,以便人们能够给您一个重点突出和更广泛的答案,因为问得太宽泛或太多问题是题外话。

【讨论】:

  • 对不起“__raw”的错误,它是“__raw_readl”,我知道它是一个用于读取原始数据的函数,但我不明白为什么他们用两个命名它:__之前raw_readl。这里 __ 符号有什么暗示意义吗?
  • @TiếnThànhNguyễn 没有特别的意义。您将使用前导下划线来处理 很多 函数名称。这通常意味着该函数是内部函数,他们可能会添加这些下划线以避免与可能具有相同名称的其他函数发生冲突。
猜你喜欢
  • 2014-05-07
  • 2012-02-08
  • 1970-01-01
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
  • 2018-01-14
相关资源
最近更新 更多