This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software:
Hi,
I can set the direction of a GPIO in the terminal by directly writing to the GPIO_DIRXX register:
# set direction of GPIO0_15, 17, 19, 21 to output root@j722s-evm:~# devmem2 0x00600010 w 0xFFD757FF /dev/mem opened. Memory mapped at address 0xffffaa850000. Read at address 0x00600010 (0xffffaa850010): 0xFFFFFFFF Write at address 0x00600010 (0xffffaa850010): 0xFFD757FF, readback 0xFFD757FF
In the sysfs interface, I can do that in an application by writing to the direction directory.
... snprintf(buffer, sizeof(buffer), "/sys/class/gpio/gpio%d/direction", gpio); gpioSysDir = open(buffer, O_WRONLY); write(gpioSysDir, "out", strlen("out")); ...
How can I do the same (writing to GPIO_DIRXX, GPIO_SET_FAL_TRIGXX, etc..), in an application using the chardev interface?
Thank you,
Jin
Hi Jin,
We do not have expertise in that. I recommend checking with
Thanks,
Keerthy
Hi Keerthy,
It seems like that the included gpio-utils library can be used with the kernel interrupt. Tested with the included gpio-hammer example.
Tested on SK-TDA4VM example:
#include <stdio.h> #include <fcntl.h> #include <linux/gpio.h> #include <sys/ioctl.h> #include <unistd.h> #include <string.h> #include <errno.h> #include "gpio-utils.h" #define GPIO_CHIP "gpiochip0" #define GPIO_LINE_NUMBER 52 int main() { /* int fd, ret; unsigned int lines[1] = {GPIO_LINE_NUMBER}; struct gpio_v2_line_request req; struct gpio_v2_line_values values; fd = open(GPIO_CHIP, O_RDWR); if (fd < 0) { perror("Failed to open GPIO chip"); return -1; } printf("Debug: fd after open(): %d\n",fd); memset(&req, 0, sizeof(req)); req.offsets[0] = GPIO_LINE_NUMBER; req.config.flags = GPIO_V2_LINE_FLAG_OUTPUT; strcpy(req.consumer, "gpio_test"); req.num_lines = 1; ret = ioctl(fd, GPIO_V2_GET_LINE_IOCTL, &req); if (ret < 0) perror("Failed to request GPIO line"); printf("Debug: fd after get_line: %d\n", fd); printf("Debug: Offsets: %d\n", req.offsets[0]); memset(&values, 0, sizeof(values)); values.mask = 0; values.bits = 0; printf("Debug: Mask: %llu\n", values.mask); printf("Debug: Bits: %llu\n", values.bits); ret = ioctl(fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &values); if (ret < 0) perror("Failed to set GPIO line low"); sleep(1); values.bits |= _BITULL(0); printf("Debug: Bits: %llu\n", values.bits); ret = ioctl(fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &values); if (ret < 0) perror("Failed to set GPIO line high"); */ /* Using gpio-utils */ struct gpio_v2_line_values values; struct gpio_v2_line_config config; unsigned int lines[1] = {GPIO_LINE_NUMBER}; int fd; int ret; memset(&config, 0, sizeof(config)); //config.flags = GPIO_V2_LINE_FLAG_INPUT | GPIO_V2_LINE_FLAG_EDGE_RISING; config.flags = GPIO_V2_LINE_FLAG_OUTPUT; ret = gpiotools_request_line(GPIO_CHIP, lines, 1, &config, "gpio-test"); if (ret < 0) perror("Unable to request GPIO line"); else fd = ret; values.mask = 0; values.bits = 0; gpiotools_set_bit(&values.mask, 0); ret = gpiotools_get_values(fd, &values); if (ret < 0) perror("Unable to get GPIO line values"); gpiotools_set_bit(&values.bits, 0); gpiotools_set_values(fd, &values); if (ret < 0) perror("Unable to set GPIO line high"); }
Terminal:
# Open WKUP_GPIO0_52 from userspace and toggle high root@tda4vm-sk:/# ./gpio_test [ 21.678862] test_irq: irq 275, val=0 # check direction root@tda4vm-sk:/# devmem2 0x42110038 /dev/mem opened. Memory mapped at address 0xffff83fb7000. Read at address 0x42110038 (0xffff83fb7038): 0xFFEFFFFF # check rising edge trigger root@tda4vm-sk:/# devmem2 0x4211004C /dev/mem opened. Memory mapped at address 0xffffafc4c000. Read at address 0x4211004C (0xffffafc4c04c): 0x00100000 # check GPIO0_52 state root@tda4vm-sk:/# devmem2 0x4211003C /dev/mem opened. Memory mapped at address 0xffffa1b96000. Read at address 0x4211003C (0xffffa1b9603c): 0x00100000
Is there any issue with opening and configuring a GPIO line from userspace as such, and using a kernel interrupt?
Thank you,
Jin
You should be able to control the states of the gpio from user space while the kernel is responsible for handling the interrupt.
Best regards,
Keerthy