I have build custom image for Raspberry Pi 4 using Yocto. I connected microswitch to GPIO17 and I want to read its state in user space application. The event occures when I press switch, which I'm 100% sure because I patched gpio-keys driver adding custom log messages:
[ 185.053346] <gpio_keys_gpio_isr>
[ 185.076626] <gpio_keys_gpio_report_event> type: 1 | code: 777 | state: 0
[ 185.265685] <gpio_keys_gpio_isr>
[ 185.268975] <gpio_keys_gpio_isr>
[ 185.292253] <gpio_keys_gpio_report_event> type: 1 | code: 777 | state: 1
But for some reason I cannot read button state from user space application:
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <string.h>
#define DP_EVENT_INPUT "/dev/input/event0"
int main(int argc, char **argv) {
unsigned int key_states[2];
struct input_event evt;
int fd;
memset(key_states, 0, sizeof(key_states));
if ((fd = open(DP_EVENT_INPUT, O_RDONLY)) < 0)
{
if (errno == EACCES && getuid() != 0) {
fprintf(stderr, "You do not have access to %s. Try "
"running as root instead.\n",
DP_EVENT_INPUT);
exit(EXIT_FAILURE);
}
}
while(1) {
ioctl(fd, EVIOCGKEYCODE, key_states);
if(read(fd, &evt, sizeof(struct input_event)) > 0) {
if(evt.type == EV_KEY) {
printf("EVENT type: EV_KEY\n");
}
else {
printf("No event!\n");
}
}
}
}
Application hangs on read() call... From here I read that to read button state I need to use ioctl with EVIOCG* value so I used EVIOCGKEYCODE which means: "get keycode". Bellow I attaching my device tree overlay:
/dts-v1/;
/plugin/;
#include <dt-bindings/pinctrl/bcm2835.h>
#include <dt-bindings/gpio/gpio.h>
#include "dt-bindings/input/linux-event-codes.h"
/ {
compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
fragment@0 {
target = <&gpio>;
__overlay__ {
// Configure the gpio pin controller
buttonpin: button-gpio {
brcm,pins = <17>;
brcm,function = <BCM2835_FSEL_GPIO_IN>;
brcm,pull = <BCM2835_PUD_UP>;
};
};
};
fragment@1 {
target-path = "/";
__overlay__ {
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&buttonpin>;
status = "okay";
sw1 {
label = "GPIO Key USER1";
linux,code = <777>;
linux,input-type = <EV_KEY>;
debounce-interval = <20>;
gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
};
};
};
};
};
Can anyone tell me what I'm doing wrong?
Thanks