通用输入/输出(GPIO)是集成电路上的通用输入或输出引脚,其行为在运行时可由用户控制。

您可以使用标准GPIO用于以下目的:

  • 从开关读取。

  • 读取传感器,如红外或液位。

  • 写入输出到led状态,继电器等。

ConnectCore平台有几个GPIO接口。你可以在硬件参考手册通用输入/输出(GPIO)

Digi向Linux添加了一个API来管理这些GPIO接口。要使用这个API,需要包含以下头文件:

# include< libdigiapix / gpio.h >

您可以配置它们,读取和设置值,并侦听状态更改。

请求一个GPIO

在使用GPIO之前,必须请求该引脚以确保它在系统上可用。您可以请求具有以下功能之一的GPIO:

函数 描述

Gpio_t *ldx_gpio_request_by_controller(const char * const controller, const unsigned char line_num, gpio_mode_t mode)

使用libgpiod通过控制器名称或标签和行号请求GPIO,并将其配置为指定的工作模式。

返回一个指针gpio_t成功,在错误。

Gpio_t *ldx_gpio_request(unsigned int kernel_number, gpio_mode_t mode, request_mode_t request_mode)

通过内核号请求GPIO,并将其配置为分配的工作模式。

返回一个指针gpio_t成功,在错误。

Gpio_t *ldx_gpio_request_by_alias(const char * const gpio_alias, gpio_mode_t mode, request_mode_t request_mode)

通过别名请求GPIO,并将其配置为指定的工作模式。中定义GPIO别名映射/etc/libdigiapix.conf[GPIO]节下的文件。看到建立GPIO别名

返回一个指针gpio_t成功,在错误。

一旦不再需要请求的GPIO,就必须释放它。看到释放一个GPIO

函数返回对于以下故障:

  • 不能导出Linux ID、指定别名关联的ID、控制器/线。

  • API在分配内存初始化GPIO时遇到问题。您的系统可能已经耗尽了资源。2022世界杯G组

  • 无法配置GPIO。

  • 请求模式配置为REQUEST_WEAK并且GPIO已经导出。

请求操作还使用所提供的gpio_mode_t工作模式:

  • GPIO_INPUT: GPIO作为输入;它的值是可以读取的。

  • GPIO_OUTPUT_LOW: GPIO作为输出设置为低电平;它的值可以写入。

  • GPIO_OUTPUT_HIGH: GPIO作为输出设高;它的值可以写入。

  • GPIO_IRQ_EDGE_RISING: GPIO作为上升中断;中断触发上升沿,从低到高。

  • GPIO_IRQ_EDGE_FALLING: GPIO在下降时作为中断;中断触发下降沿,从低到高。

  • GPIO_IRQ_EDGE_BOTH: GPIO在两者上作为中断;中断在上升边和下降边触发。

在请求GPIO时,如果使用sysfs请求方法,可以从下面选择请求方式request_mode_t价值观:

  • REQUEST_SHARED:如果GPIO已经被导出,它将不会被取消导出。如果未导出,则免费取消导出。

  • REQUEST_GREEDY: GPIO在free时总是不被导出。

  • REQUEST_WEAK:如果GPIO已经导出,则请求失败。它将永远是未导出的。

请求GPIO后,您可以使用以下功能读取或设置其工作模式:

函数 描述

gpio_mod_t ldx_gpio_get_mode(gpio_t *gpio)

获取给定的GPIO工作模式:

  • 一个输入:GPIO_INPUT

  • 输出:GPIO_OUTPUT_LOWGPIO_OUTPUT_HIGH

  • 或者中断生成:GPIO_IRQ_EDGE_RISINGGPIO_IRQ_EDGE_FALLING,或GPIO_IRQ_EDGE_BOTH

它返回GPIO_MODE_ERROR如果无法检索。

Int ldx_gpio_set_mode(gpio_t *gpio, gpio_mode_t mode)

配置提供的GPIO的工作模式:

  • 读取其值的输入:GPIO_INPUT

  • 设置其值的输出:GPIO_OUTPUT_LOWGPIO_OUTPUT_HIGH

  • 当有一个值改变时,中断触发器:GPIO_IRQ_EDGE_RISINGGPIO_IRQ_EDGE_FALLING,或GPIO_IRQ_EDGE_BOTH

它返回EXIT_SUCCESS成功,EXIT_FAILURE否则。

请求一个GPIO
[…]/*请求一个GPIO作为输入使用它的控制器标签和行号*/Gpio_t *button1 = ldx_gpio_request_by_controller(“mca-gpio”12, GPIO_INPUT);/*使用别名*/请求输出GPIO(默认为low)Gpio_t *led = ldx_gpio_request_by_alias(“USER_LED”, gpio_output_low, request_shared);/*请求GPIO作为上升沿中断,使用内核号*/Gpio_t *button2 = ldx_gpio_request(505, gpio_irq_edge_rising, request_shared);printf (按钮1 GPIO %s %d配置为%d\ n, button1->gpio_controller, button1->gpio_line, ldx_gpio_get_mode(button1));printf ("LED GPIO %d配置为%d\ n, ldx_gpio_get_mode(led));printf (按钮2 GPIO %d配置为%d\ n, button2->, ldx_gpio_get_mode(button2);[…]

建立GPIO别名

为了帮助您识别设计中的gpio,您可以使用以下格式之一为gpio分配别名:

使用控制器标签和线路的GPIO别名

将分配的控制器名称或标签和行号映射到控件中的名称/etc/libdigiapix.conf文件:

  1. 添加一个名为[GPIO]的部分,如果它还不存在的话。

  2. 在节名下面,使用以下格式添加映射的gpio列表:

     = 

    地点:

    • 是GPIO的可读名称

    • 为GPIO控制器名称或标签

    • 是GPIO线路号

示例GPIO部分
(GPIO)#用户主导USER_LED=gpio1, 23岁# user按钮USER_BUTTON=mca-gpio 1

例如,使用上面的配置,您可以使用API请求GPIOUSER_LEDUSER_BUTTON别名,而不是控制器标签和行。看到请求一个GPIO

您可以使用以下函数获取与别名关联的控制器标签和行号:

intldx_gpio_get_controller常量字符*常量gpio_alias,字符*常量控制器)intldx_gpio_get_line (常量字符*常量gpio_alias);

使用Linux id的GPIO别名。

将分配的内核号映射到文件中的名称/etc/libdigiapix.conf文件:

  1. 添加一个名为[GPIO]的部分,如果它还不存在的话。

  2. 在节名下面,使用以下格式添加映射的gpio列表:

     = 

    地点:

    • 是GPIO的可读名称

    • 为GPIO Linux ID

示例GPIO部分
(GPIO)# user led - gpio1 io23USER_LED=488#用户按钮- McA_io1USER_BUTTON=505

例如,使用上面的配置,您可以使用API请求GPIOUSER_LEDUSER_BUTTON别名,而不是内核号。看到请求一个GPIO

您可以使用以下函数获取与别名关联的Linux ID或内核号:

intldx_gpio_get_kernel_number (常量字符*常量gpio_alias)
有关下列资料的资料libdigiapix.conf在您的Digi Embedded Yocto图像中,请参见定义接口别名

释放一个GPIO

当不再需要请求的GPIO时,必须释放它。要做到这一点,使用ldx_gpio_free ()函数。

intldx_gpio_free (gpio_t * gpio)
释放请求的GPIO
[…]gpio_t*led = ...; [...]/*当GPIO不再需要时释放它*/ldx_gpio_free(领导);[…]

读取并设置GPIO值

您可以读取和设置GPIO值:

函数 描述

Gpio_value_t ldx_gpio_get_value(gpio_t *gpio)

获取GPIO的值;GPIO_HIGHGPIO_LOW.如果出现错误,GPIO_VALUE_ERROR返回。

该功能仅在GPIO配置为:

  • GPIO_INPUT

  • GPIO_IRQ_EDGE_RISING

  • GPIO_IRQ_EDGE_FALLING

  • GPIO_IRQ_EDGE_BOTH

GPIO_OUTPUT_LOWGPIO_OUTPUT_HIGH;这个函数总是返回GPIO_LOW.看到请求一个GPIO

Int ldx_gpio_set_value(gpio_t *gpio, gpio_value_t value)

设置GPIO值。它返回EXIT_SUCCESS成功,EXIT_FAILURE否则。

此功能仅在GPIO配置为:

  • GPIO_OUTPUT_LOW

  • GPIO_OUTPUT_HIGH

如果GPIO配置为输入或具有任何中断模式,则此函数返回EXIT_FAILURE.看到请求一个GPIO

GPIO值是枚举类型gpio_value_t

  • GPIO_LOW: GPIO值低。

  • GPIO_HIGH: GPIO值高。

读取和设置GPIO值
[…]Gpio_t *led = ldx_gpio_request_by_alias(“USER_LED”, gpio_output_low, request_shared);Gpio_t *button = ldx_gpio_request_by_controller(“mca-gpio”12, GPIO_INPUT);/*读取按钮GPIO的值*/Gpio_value_t value = ldx_gpio_get_value(按钮);printf (按钮GPIO值为%d\ n、价值);/*将LED GPIO设置为HIGH */ldx_gpio_set_value (led, GPIO_HIGH);[…]

配置GPIO主模式

假设GPIO在信号值为1(高)时处于活动状态,在信号值为0(低)时处于非活动状态,这是很自然的。然而,连接到GPIO的设备可能对active的含义有不同的约定:

  • Active high: GPIO高电平时,设备被激活;也就是说,1表示活跃。

  • 低电平激活:GPIO低电平时,设备被激活;也就是说,0表示活动。

属性定义GPIO的活动属性ldx_gpio_set_active_mode ()功能:

函数 描述

Int ldx_gpio_set_active_mode(gpio_t *gpio, gpio_active_mode_t value)

改变给定GPIO的活动模式:

  • GPIO_ACTIVE_HIGH积极的高行为。

  • GPIO_ACTIVE_LOW对于主动的低行为。

它返回EXIT_SUCCESS成功,EXIT_FAILURE否则。

gpio_active_mod_t ldx_gpio_get_active_mode(gpio_t *gpio)

获取给定GPIO的活动模式:

  • GPIO_ACTIVE_HIGH积极的高行为。

  • GPIO_ACTIVE_LOW对于主动的低行为。

  • GPIO_ACTIVE_MODE_ERROR在错误。

GPIO活动模式是枚举类型gpio_active_mode_t

  • GPIO_ACTIVE_HIGH为一个活动的高GPIO。

  • GPIO_ACTIVE_LOW用于激活低GPIO。

配置并获得GPIO活动模式
[…]gpio_t*gpio=...;ldx_gpio_set_active_mode (gpio GPIO_ACTIVE_HIGH);[…]开关(ldx_gpio_get_active_mode (gpio)) {情况下GPIO_ACTIVE_HIGH: printf ("GPIO %s %d处于高激活状态\ n, gpio->gpio_controller, gpio->gpio_line);打破;情况下GPIO_ACTIVE_LOW: printf ("GPIO %s %d处于低激活状态\ n, gpio->gpio_controller, gpio->gpio_line);打破;默认的: printf ("进入GPIO %s %d活动模式时出错\ n, gpio->gpio_controller, gpio->gpio_line);打破;}[…]

检测GPIO中断

当一个GPIO被配置为使用GPIO_IRQ_EDGE_RISINGGPIO_IRQ_EDGE_FALLINGGPIO_IRQ_EDGE_BOTH,您可以同步或异步等待值更改通知。

函数 描述

Gpio_irq_error_t ldx_gpio_wait_interrupt(gpio_t *gpio, int timeout)

阻塞的最大时间为超时(以毫秒为单位)等待在指定的GPIO上发生中断。值-1指示系统无限期等待。

Int ldx_gpio_start_wait_interrupt(gpio_t *gpio, const ldx_gpio_interrupt, void *arg)

在指定的GPIO上设置一个中断处理程序。

Int ldx_gpio_stop_wait_interrupt(gpio_t *gpio)

移除指定GPIO上的中断检测。

同步中断检测

ldx_gpio_wait_interrupt ()是一个阻塞函数,用于等待给定GPIO上发生中断。

Gpio_irq_error_t ldx_gpio_wait_interrupt(gpio_t *gpio)int超时)

此功能最大阻断时间为超时(以毫秒为单位)等待在指定的GPIO上发生中断。值-1指示系统无限期等待。它返回:

  • GPIO_IRQ_ERROR_NONE当中断被捕获时。

  • GPIO_IRQ_ERROR_TIMEOUT如果在指定的超时时间内没有触发中断。

  • GPIO_IRQ_ERROR错误:

    • 如果timeout小于-1。

    • 如果GPIO没有配置为中断。看到请求一个GPIO

    • 如果无法监控GPIO。

同步中断检测
[…]Gpio_t *led = ldx_gpio_request_by_alias(“USER_LED”, gpio_output_low, request_shared);Gpio_t *button = ldx_gpio_request_by_controller(“mca-gpio”12, GPIO_IRQ_EDGE_RISING);[…]gpio_value_tled_state = ldx_gpio_get_value(led);(运行){/*等待5秒,按钮GPIO发生上升中断*/Gpio_irq_error_t ret = ldx_gpio_wait_interrupt(按钮,5000);开关(ret) {情况下GPIO_IRQ_ERROR_NONE/*更改LED值*/led_state = (led_state == GPIO_HIGH ?GPIO_LOW: GPIO_HIGH);ldx_gpio_set_value (led, led_state);usleep (500000);打破;情况下GPIO_IRQ_ERROR_TIMEOUT: printf (“在过去5秒内没有捕获到中断。”\ n);打破;情况下GPIO_IRQ_ERROR: printf ("等待中断时出错。\ n);打破;默认的: running =0;打破;}睡眠(5);}[…]

异步中断检测

ldx_gpio_start_wait_interrupt ()是一个非阻塞函数,用于等待指定GPIO上发生的中断。

intldx_gpio_start_wait_interrupt (gpio_t * gpio,常量ldx_gpio_interrupt_cb_t interrupt_cb,无效*参数)

当检测到中断时,该函数触发指定的回调处理程序。之后,它继续等待新的中断。

参数的唯一参数传递ldx_gpio_interrupt_cb_t回调。

ldx_gpio_start_wait_interrupt ()返回:

  • EXIT_SUCCESS在成功。

  • EXIT_FAILURE当失败:

    • 如果GPIO没有配置为中断。看到请求一个GPIO

    • 如果无法监控GPIO。

回调必须遵循这个原型:

类型定义int(* ldx_gpio_interrupt_cb_t) (无效*参数)
如果一个中断在回调函数执行时到达,那么它将被排队,因此如果它们发生得太快,可能会错过一些中断。

停止侦听中断,使用ldx_gpio_stop_wait_interrupt ()

intldx_gpio_stop_wait_interrupt (gpio_t * gpio)
异步中断检测
/*中断回调*/静态intcounter_cb无效* arg) {int* tmp_count = (int*)参数;*tmp_count = *tmp_count +1;返回EXIT_SUCCESS;}[…]intinterrupt_count =0;Gpio_t *led = ldx_gpio_request_by_alias(“USER_LED”, gpio_output_low, request_shared);Gpio_t *button = ldx_gpio_request_by_controller(“mca-gpio”12, GPIO_IRQ_EDGE_RISING);[…]/*开始捕获中断*/Ldx_gpio_start_wait_interrupt(按钮,计数器)无效*) &interrupt_count);{printf ("Caught %d中断\ n, interrupt_count”);睡眠(1):}(interrupt_count <10);[…]/*停止捕获中断*/ldx_gpio_stop_wait_interrupt(按钮);[…]

配置防反跳

弹跳是指由于机械原因,在很短的时间间隔内快速拉高/拉低线路的效果,例如当连接到按钮或开关时。具有irq功能的MCA gpio可以配置一个debounce filter来消除反弹效果。

intldx_gpio_set_debounce (gpio_t * gpio,无符号int美国铀浓缩公司)

这个函数创建一个脱波过滤器。gpiogpio_t是否需要配置和购买是在过滤器中设置的以微秒为单位的时间。

剥离时间的下限和上限没有由APIX库定义。库将值传递给GPIO驱动程序,如果它支持脱脱,则该驱动程序定义有效的脱脱值。

对于MCA GPIO,允许的最大脱扣时间为12.75 s。

debounce功能只适用于上升边或下降边,但不能同时适用于两者。只有那些支持irq的引脚才支持脱扣功能。有关MCA GPIO脱扣功能的其他信息,请参见通用输入/输出(GPIO)

GPIO的例子

在本例中,一个GPIO配置为输出,另一个配置为输入。按下与输入GPIO相连的按钮,将与输出GPIO相关的LED开关打开或关闭。

您可以使用Digi Embedded Yocto插件在Eclipse中导入示例。有关更多信息,请参见创建一个新的DEY样例项目.这个例子包含在Digi Embedded Yocto中。去GitHub查看应用程序源代码。