通用输入/输出(GPIO)是集成电路上的通用输入或输出引脚,其行为在运行时可由用户控制。
您可以使用标准GPIO用于以下目的:
从开关读取。
读取传感器,如红外或液位。
写入输出到led状态,继电器等。
ConnectCore平台有几个GPIO接口。你可以在硬件参考手册和通用输入/输出(GPIO).
Digi向Linux添加了一个API来管理这些GPIO接口。要使用这个API,需要包含以下头文件:
# include< libdigiapix / gpio.h >
您可以配置它们,读取和设置值,并侦听状态更改。
请求一个GPIO
在使用GPIO之前,必须请求该引脚以确保它在系统上可用。您可以请求具有以下功能之一的GPIO:
函数 | 描述 |
---|---|
|
使用libgpiod通过控制器名称或标签和行号请求GPIO,并将其配置为指定的工作模式。 返回一个指针 |
|
通过内核号请求GPIO,并将其配置为分配的工作模式。 返回一个指针 |
|
通过别名请求GPIO,并将其配置为指定的工作模式。中定义GPIO别名映射 返回一个指针 |
一旦不再需要请求的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工作模式:
它返回 |
Int ldx_gpio_set_mode(gpio_t *gpio, gpio_mode_t mode) |
配置提供的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
文件:
添加一个名为[GPIO]的部分,如果它还不存在的话。
在节名下面,使用以下格式添加映射的gpio列表:
= , 地点:
是GPIO的可读名称 为GPIO控制器名称或标签 是GPIO线路号
(GPIO)#用户主导USER_LED=gpio1, 23岁# user按钮USER_BUTTON=mca-gpio 1
例如,使用上面的配置,您可以使用API请求GPIOUSER_LED或USER_BUTTON别名,而不是控制器标签和行。看到请求一个GPIO.
您可以使用以下函数获取与别名关联的控制器标签和行号:
intldx_gpio_get_controller(常量字符*常量gpio_alias,字符*常量控制器)intldx_gpio_get_line (常量字符*常量gpio_alias);
使用Linux id的GPIO别名。
将分配的内核号映射到文件中的名称/etc/libdigiapix.conf
文件:
添加一个名为[GPIO]的部分,如果它还不存在的话。
在节名下面,使用以下格式添加映射的gpio列表:
= 地点:
是GPIO的可读名称 为GPIO Linux ID
(GPIO)# user led - gpio1 io23USER_LED=488#用户按钮- McA_io1USER_BUTTON=505
例如,使用上面的配置,您可以使用API请求GPIOUSER_LED或USER_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_t*led = ...; [...]/*当GPIO不再需要时释放它*/ldx_gpio_free(领导);[…]
读取并设置GPIO值
您可以读取和设置GPIO值:
函数 | 描述 |
---|---|
|
获取GPIO的值; 该功能仅在GPIO配置为:
为 |
|
设置GPIO值。它返回 此功能仅在GPIO配置为:
如果GPIO配置为输入或具有任何中断模式,则此函数返回 |
GPIO值是枚举类型gpio_value_t:
GPIO_LOW
: GPIO值低。GPIO_HIGH
: 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 ()
功能:
函数 | 描述 |
---|---|
|
改变给定GPIO的活动模式:
它返回 |
|
获取给定GPIO的活动模式:
|
GPIO活动模式是枚举类型gpio_active_mode_t:
GPIO_ACTIVE_HIGH
为一个活动的高GPIO。GPIO_ACTIVE_LOW
用于激活低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_RISING
,GPIO_IRQ_EDGE_FALLING
或GPIO_IRQ_EDGE_BOTH
,您可以同步或异步等待值更改通知。
函数 | 描述 |
---|---|
|
阻塞的最大时间为超时(以毫秒为单位)等待在指定的GPIO上发生中断。值-1指示系统无限期等待。 |
|
在指定的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查看应用程序源代码。