为#define 指针地址创建绑定

Create binding for #define pointer address

the Vala manual 中的优秀文章的帮助下创建一些自定义 vapi def 作为我的指南。但我不确定如何翻译像这样的 C 函数式宏:

// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
#define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
#define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
#define GPIO_PULL *(gpio+37) // Pull up/pull down
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock

C 代码这样声明 gpio

// I/O access
volatile unsigned *gpio;

我是否应该将宏 INP_GPIO(g) 声明为 void 函数,即

[CCode (cname = "INP_GPIO")]
public void inp_gpio(int val);

或作为代表,如下所示?

public delegate void inp_gpio(int val);

VAPI文件的C代码推导Vala类型需要遵循什么条件?

更新:随着我继续进行我的valaIOT项目,下面提到的vapis维护在https://gitlab.com/gpaslanis/valaiot/tree/master/vapis。请postrecommendations/corrections在现场。希望它们对您有所帮助。

好问题!代码看起来是直接访问GPIO内存地址,好像来自RPi GPIO Code Samples - Direct register access。 C pre-processor 正在使用 &= 运算符将 INP_GPIO(g) 交换为表达式。该表达式对运算符左侧计算的内存位置进行按位运算。

Vala 需要做的就是确保将 INP_GPIO(g) 写入 C 文件,然后 C pre-processor 进行交换。所以正确的绑定应该是这样的:

[CCode (cname = "INP_GPIO")]
public void inp_gpio(int pin);

Vala 中的委托是 C 中的函数指针,代码不会调用内存地址,而是向其中写入一个值。它不是 C 中的函数指针,因此不应在 Vala 中绑定为委托。

使用 GPIO 是 Vala 的一个很好的用例。您可能需要考虑改用 Linux 内核用户 space API。这最近在 Linux 4.8 中发生了变化,并且不在 Vala linux.vapi 中。因此,欢迎使用 linux/include/uapi/linux/gpio.h with Vala. It's essentially a file interface to /dev/gpiochipx with various IOCTLs to manipulate it. For more details see these slides. If you understand GMainContext and GSource I think it would be possible to write a Vala GSource with g_source_add_unix_fd 的补丁。当 GPIO 线路发生变化时,这将在 GMainContext 中触发一个事件。事件只是回调的另一个名称。这将是响应 GPIO 线路上的输入而实现更高级别应用程序代码的好方法。 GMainContext 在使用 GMainLoop 或 GApplication 时在幕后创建。 Vala 的文档需要完成。

还有libgpiod that provides a user space library to interface with the kernel character device interface. For Vala this would mean writing a libgpiod.vapi to use gpiod.h. libgpiod also has command line tools and this article对这些进行了很好的总结。