Apparently there is a way to tie a function to hardware VSYNC event. I found it in a closed issue for Raspberry Pi userland: https://github.com/raspberrypi/userland/issues/218
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>
#include "bcm_host.h"
static DISPMANX_DISPLAY_HANDLE_T display;
unsigned long lasttime = 0;
void vsync(DISPMANX_UPDATE_HANDLE_T u, void* arg) {
struct timeval tv;
gettimeofday(&tv, NULL);
unsigned long microseconds = (tv.tv_sec*1000000)+tv.tv_usec;
printf("%lu\tsync %lu\n", microseconds,microseconds-lasttime);
lasttime = microseconds;
}
int main(void)
{
bcm_host_init();
display = vc_dispmanx_display_open( 0 );
vc_dispmanx_vsync_callback(display, vsync, NULL);
sleep(1);
vc_dispmanx_vsync_callback(display, NULL, NULL); // disable callback
vc_dispmanx_display_close( display );
return 0;
}
To compile it you need to add paths to /opt/vc and link with libbcm_host.so, like
gcc test.c -o test -I/opt/vc/include -L/opt/vc/lib -lbcm_host
I have copied this code into my repository https://github.com/ytmytm/rpi-lightpen/blob/master/vsync-rpi.c
That issue is closed and this snippet works for me. The output is about 20000us but not stable at all.
There is a lot of jitter because the time is saved only in the userspace, not as quickly as possible in kernel. Even if I try to tie my routine somewhere in the kernel, I don't know how much time is needed to service these events. This is some kind of message queue between CPU and GPU. Unfortunately it's not as simple as a direct IRQ.
So it's a good way to wait until VSYNC but it's not precise enough for lightpen needs.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.