Low Latency IO GPIO interrupt

What kind of latency can be expected on a GPIO interrupt? What is the way to get minimum latency between pin change and running the ISR? I couldn’t even find a way to write one in C but I assume there is.

Additionally, how would I share data between the ISR and the executable program?

you may see-also Jetson Nano 2GB dev kit GPIO toggle speed from Python? - #7 by JerryChang

A potential way of doing this is by using the linux driver plus ioctl(), just going to paste some piece of code that works for me just to point you on the right direction -only the relevant parts, there is more to it but at least you will hopefully get the idea, you can get the interrupt plus the epoch timestamp in nanoseconds :

 ISRFunc *int_struct = (ISRFunc *) arg;
    int edge = int_struct->edge;
    unsigned gpio_offset = int_struct->gpio_offset;
    uint64_t *timestamp =  int_struct->timestamp;
    *timestamp = 0;
    unsigned debounce = int_struct->debounce;
    int fd;
	int ret;
    struct gpioevent_request req;
    struct gpioevent_data event;
    
    fd = open("/dev/gpiochip0", 0);
    if (fd < 0) {
        printf( "bad handle (%d)\n", fd);
        pthread_exit(NULL);	
    }

    req.lineoffset = gpio_offset;
    req.handleflags = GPIOHANDLE_REQUEST_INPUT;
    req.eventflags = edge;
    //strncpy(req.consumer_label, "gpio_event", sizeof(req.consumer_label) - 1);
    
    ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
        if (ret == -1) {
                ret = -errno;
                printf("Failed to issue GET EVENT ""IOCTL (%d)\n",ret);
                close(fd);
                pthread_exit(NULL);
        }
    close(fd);
    while (global_int){
        ret = read(req.fd, &event, sizeof(event));
        if ((ret == -1) || (ret != sizeof(event))) {
            ret = -errno;
            printf("Failed to read event (%d)\n", ret);
            break;
        }
        
        if ((event.timestamp - *timestamp) > (debounce*100)){
            *timestamp = event.timestamp;
        }
        else{
            event.id = 0x00;
        }
        
        switch (event.id) {
        case GPIOEVENT_EVENT_RISING_EDGE:
            int_struct->f();
            break;
        case GPIOEVENT_EVENT_FALLING_EDGE:
            int_struct->f();
            break;
        default:
            //Do nothing
            break;
        }
    }

2 Likes

@lowellm about the numbers, I was curious myself so I ran some tests yesterday, you can check the results here

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.