我应该在使用由 `gpio_to_desc` 返回的 `gpio_desc` 之前使用 `gpio_free` 吗?
Should I use `gpio_free` before using `gpio_desc` which is returned by `gpio_to_desc`?
2020/10/31更新
感谢 0andriy asking the question on mailing list. And Alexandre Courbot aka Gunurou 我的问题!
再次感谢0andriy!你才是这个问题背后真正的英雄。
老问题:
这个问题似乎是文档中的错字,但我想仔细检查一下。
我的问题是GPIO Descriptor Consumer Interface最后一节的最后两段。
the following two functions allow you to convert
a GPIO descriptor into the GPIO integer namespace and vice-versa:
int desc_to_gpio(const struct gpio_desc *desc)
struct gpio_desc *gpio_to_desc(unsigned gpio)
The GPIO number returned by desc_to_gpio() can be safely used as long
as the GPIO descriptor has not been freed. All the same, a GPIO number
passed to gpio_to_desc() must have been properly acquired, and usage
of the returned GPIO descriptor is only possible after the GPIO number
has been released.
Freeing a GPIO obtained by one API with the other API is forbidden and
an unchecked error.
我对每句话的理解
The GPIO number returned by desc_to_gpio() can be safely used as long as the GPIO descriptor has not been freed.
在 gpiod_put()
释放描述符之前可以使用任何 GPIO 引脚。以下是我理解的伪代码。
struct gpio_desc desc = gpiod_get(...);
gpio pin = desc_to_gpio(desc);
// operation here
gpiod_put(desc);
All the same, a GPIO number passed to gpio_to_desc() must have been properly acquired, and usage of the returned GPIO descriptor is only possible after the GPIO number has been released.
我对 "All the same"
和 "usage of the returned GPIO descriptor is only possible after the GPIO number has been released"
感到困惑。
如果 "All the same"
适用,我认为 gpio_desc
可以在 gpio_free()
之前使用。但是“只有在 GPIO 编号被释放后才能使用 returned GPIO 描述符”让我觉得我必须 gpio_free()
在使用 gpio_desc
returned 来自 gpio_to_desc()
.
为了重申我的问题,以下哪个代码片段应该是 gpio_to_desc()
的正确用法?
我假设 "usage of the returned GPIO descriptor"
表示来自 gpio_to_desc()
.
的 gpio_desc
return
我认为第二个应该是不正确的,但我想通过任何文档或示例对其进行确认。
- 免费前使用
gpio_desc
。
gpio pin = gpio_request( ... );
struct gpio_desc desc = gpio_to_desc(pin);
// gpiod operation here, before free
gpio_free(gpio_desc)
- 免费后使用
gpio_desc
。
gpio pin = gpio_request( ... );
struct gpio_desc desc = gpio_to_desc(pin);
gpio_free(gpio_desc)
// gpiod operation here, after free
也就是说,应该
“只有在释放 GPIO 编号后才能使用 returned GPIO 描述符”
改为
“只有在 GPIO 编号被释放之前 才能使用 returned GPIO 描述符”?
附带问题
根据这句话。
Freeing a GPIO obtained by one API with the other API is forbidden and an unchecked error.
我不应该发布由 gpio_to_desc()
编辑 gpiod_put()
return 的 gpio_desc
吗?
Google 上的关键字。
gpio_to_desc()
必须先 gpio_free()
没有官方文章提及它。
gpio_to_desc()
gpiod_put()
我找到了 header files。然而它并没有解释它。
All the same, a GPIO number passed to gpio_to_desc() must have been properly acquired, and usage of the returned GPIO descriptor is only possible after the GPIO number has been released.
after不应该改成before吗?
可能两者都不是。我猜这句话想表达的是不要混合遗留 gpio_XXX
和现代 gpiod_XXX
API。例如。在使用 gpiod
个资源之前释放 gpio
个资源。
你是对的,使用gpio_free()
之后的描述符是错误的。
在实践中,内核违反了陈述句本身,因为几乎每个 gpio
操作都使用 gpio_to_desc()
。例如
void gpio_free(unsigned gpio)
{
gpiod_free(gpio_to_desc(gpio));
}
或
static inline void __gpio_set_value(unsigned gpio, int value)
{
return gpiod_set_raw_value(gpio_to_desc(gpio), value);
}
gpio_to_desc()
和desc_to_gpio()
都不获取资源,但return指向现有对象的指针:
struct gpio_desc *gpio_to_desc(unsigned gpio)
{
...
return &gdev->descs[gpio - gdev->base];
}
int desc_to_gpio(const struct gpio_desc *desc)
{
return desc->gdev->base + (desc - &desc->gdev->descs[0]);
}
这个问题的简短回答是永远不要调用这些函数。它们自 2014 年以来就已过时,新代码应该没有理由使用它们。新代码应该只依赖于 gpiod_*()
系列函数,并且永远不要使用 GPIO 数字。
如果您处理旧代码,最安全的做法是首先将其转换为使用 gpiod 接口。
现在,如果您绝对需要使用这些功能,我的回忆是以下用法是有效的(从您的问题中复制):
struct gpio_desc desc = gpiod_get(...);
gpio pin = desc_to_gpio(desc);
// operation here
gpiod_put(desc);
gpio pin = gpio_request( ... );
struct gpio_desc desc = gpio_to_desc(pin);
// gpiod operation here, before free
gpio_free(gpio_desc)
这是因为 gpio_*()
系列函数构建在 gpiod 接口之上,如您在 drivers/gpio/gpiolib-legacy.c 中所见。因此,与您请求的 GPIO 编号对应的描述符将已被 gpiod_request()
获取,因此保证在 gpio_free()
之前一直有效(实际上只是调用 gpiod_free()
被调用。
关于你的附带问题:
Should I NOT release the gpio_desc with gpiod_put() returned by gpio_to_desc()?
没错,你永远不应该那样做。目前 API 的构建方式使得这样做 可能 有效,但不能保证它们将来不会分歧。此外,如果您获得了一个描述符,则没有理由不保留它以使用正确的 API.
释放它。
但同样,最好的做法是假设这些函数不存在,并尽可能使用 gpiod。
2020/10/31更新
感谢 0andriy asking the question on mailing list. And Alexandre Courbot aka Gunurou
再次感谢0andriy!你才是这个问题背后真正的英雄。
老问题:
这个问题似乎是文档中的错字,但我想仔细检查一下。
我的问题是GPIO Descriptor Consumer Interface最后一节的最后两段。
the following two functions allow you to convert a GPIO descriptor into the GPIO integer namespace and vice-versa:
int desc_to_gpio(const struct gpio_desc *desc) struct gpio_desc *gpio_to_desc(unsigned gpio)
The GPIO number returned by desc_to_gpio() can be safely used as long as the GPIO descriptor has not been freed. All the same, a GPIO number passed to gpio_to_desc() must have been properly acquired, and usage of the returned GPIO descriptor is only possible after the GPIO number has been released.
Freeing a GPIO obtained by one API with the other API is forbidden and an unchecked error.
我对每句话的理解
The GPIO number returned by desc_to_gpio() can be safely used as long as the GPIO descriptor has not been freed.
在 gpiod_put()
释放描述符之前可以使用任何 GPIO 引脚。以下是我理解的伪代码。
struct gpio_desc desc = gpiod_get(...);
gpio pin = desc_to_gpio(desc);
// operation here
gpiod_put(desc);
All the same, a GPIO number passed to gpio_to_desc() must have been properly acquired, and usage of the returned GPIO descriptor is only possible after the GPIO number has been released.
我对 "All the same"
和 "usage of the returned GPIO descriptor is only possible after the GPIO number has been released"
感到困惑。
如果 "All the same"
适用,我认为 gpio_desc
可以在 gpio_free()
之前使用。但是“只有在 GPIO 编号被释放后才能使用 returned GPIO 描述符”让我觉得我必须 gpio_free()
在使用 gpio_desc
returned 来自 gpio_to_desc()
.
为了重申我的问题,以下哪个代码片段应该是 gpio_to_desc()
的正确用法?
我假设 "usage of the returned GPIO descriptor"
表示来自 gpio_to_desc()
.
gpio_desc
return
我认为第二个应该是不正确的,但我想通过任何文档或示例对其进行确认。
- 免费前使用
gpio_desc
。
gpio pin = gpio_request( ... );
struct gpio_desc desc = gpio_to_desc(pin);
// gpiod operation here, before free
gpio_free(gpio_desc)
- 免费后使用
gpio_desc
。
gpio pin = gpio_request( ... );
struct gpio_desc desc = gpio_to_desc(pin);
gpio_free(gpio_desc)
// gpiod operation here, after free
也就是说,应该
“只有在释放 GPIO 编号后才能使用 returned GPIO 描述符”
改为
“只有在 GPIO 编号被释放之前 才能使用 returned GPIO 描述符”?
附带问题
根据这句话。
Freeing a GPIO obtained by one API with the other API is forbidden and an unchecked error.
我不应该发布由 gpio_to_desc()
编辑 gpiod_put()
return 的 gpio_desc
吗?
Google 上的关键字。
gpio_to_desc()
必须先gpio_free()
没有官方文章提及它。
gpio_to_desc()
gpiod_put()
我找到了 header files。然而它并没有解释它。
All the same, a GPIO number passed to gpio_to_desc() must have been properly acquired, and usage of the returned GPIO descriptor is only possible after the GPIO number has been released.
after不应该改成before吗?
可能两者都不是。我猜这句话想表达的是不要混合遗留 gpio_XXX
和现代 gpiod_XXX
API。例如。在使用 gpiod
个资源之前释放 gpio
个资源。
你是对的,使用gpio_free()
之后的描述符是错误的。
在实践中,内核违反了陈述句本身,因为几乎每个 gpio
操作都使用 gpio_to_desc()
。例如
void gpio_free(unsigned gpio)
{
gpiod_free(gpio_to_desc(gpio));
}
或
static inline void __gpio_set_value(unsigned gpio, int value)
{
return gpiod_set_raw_value(gpio_to_desc(gpio), value);
}
gpio_to_desc()
和desc_to_gpio()
都不获取资源,但return指向现有对象的指针:
struct gpio_desc *gpio_to_desc(unsigned gpio)
{
...
return &gdev->descs[gpio - gdev->base];
}
int desc_to_gpio(const struct gpio_desc *desc)
{
return desc->gdev->base + (desc - &desc->gdev->descs[0]);
}
这个问题的简短回答是永远不要调用这些函数。它们自 2014 年以来就已过时,新代码应该没有理由使用它们。新代码应该只依赖于 gpiod_*()
系列函数,并且永远不要使用 GPIO 数字。
如果您处理旧代码,最安全的做法是首先将其转换为使用 gpiod 接口。
现在,如果您绝对需要使用这些功能,我的回忆是以下用法是有效的(从您的问题中复制):
struct gpio_desc desc = gpiod_get(...);
gpio pin = desc_to_gpio(desc);
// operation here
gpiod_put(desc);
gpio pin = gpio_request( ... );
struct gpio_desc desc = gpio_to_desc(pin);
// gpiod operation here, before free
gpio_free(gpio_desc)
这是因为 gpio_*()
系列函数构建在 gpiod 接口之上,如您在 drivers/gpio/gpiolib-legacy.c 中所见。因此,与您请求的 GPIO 编号对应的描述符将已被 gpiod_request()
获取,因此保证在 gpio_free()
之前一直有效(实际上只是调用 gpiod_free()
被调用。
关于你的附带问题:
Should I NOT release the gpio_desc with gpiod_put() returned by gpio_to_desc()?
没错,你永远不应该那样做。目前 API 的构建方式使得这样做 可能 有效,但不能保证它们将来不会分歧。此外,如果您获得了一个描述符,则没有理由不保留它以使用正确的 API.
释放它。但同样,最好的做法是假设这些函数不存在,并尽可能使用 gpiod。