为#Define指针地址创建绑定



借助《瓦拉手册》作为我的指南,创建一些自定义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文件中派生Vala类型时,我应该遵循哪些条件?

update :当我继续从事我的valaiot项目时,下面提到的VAPIS保持在 https://gitlab.com/gpaslanis/valaiot/valaiot/tree/master/master/master/vapis 。请在网站上发布建议/更正。希望您发现它们有帮助。

好问题!该代码看起来像是直接访问GPIO内存地址,并且似乎来自RPI GPIO代码样本 - 直接注册访问。C前处理器正在使用&=操作员将INP_GPIO(g)交换为表达式。该表达式在运算符的左侧计算的内存位置进行了位操作。

所有Vala都需要做的就是确保INP_GPIO(g)写入C文件,然后C前处理器进行交换。因此,正确的绑定将是:

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

vala中的委托是C中的函数指针,代码不会调用内存地址,而是为其写一个值。这不是C中的功能指针,因此不应以Vala的代表为由。

使用GPIO是Vala的绝佳用例。您可能需要考虑使用Linux内核用户空间API。最近,Linux 4.8更改了,不在Vala linux.vapi中。因此,欢迎使用linux/include/ups/uapi/linux/gpio.h与vala一起使用一个补丁。从本质上讲,它是与/dev/gpiochipx的文件接口,并具有各种IOCTL来操纵它。有关更多详细信息,请参见这些幻灯片。如果您了解GmainContext和Gsource,我认为可以使用g_source_add_unix_fd编写vala gsource。当GPIO行发生更改时,这将触发GmainContext中的事件。事件只是回调的另一个名称。这将是对GPIO线上的输入来实施更高级别的应用程序代码的好方法。使用gmainloop或gapplication时,在幕后创建了gmaincontext。瓦拉的文档需要完成。

还有libgpiod提供了一个用户空间库来与内核字符设备接口接口。对于瓦拉,这意味着要写一个libgpiod.vapi使用gpiod.h。libgpiod还具有命令行工具,本文给出了这些命令行工具。

最新更新