Я пытаюсь поймать прерывание на GPIO через sysfs
, используя poll()
. У меня есть -1 в третьей позиции, поэтому он может блокироваться, но, похоже, он всегда возвращается. Я проверил некоторые подобные сообщения на SO. В частности, this (1), this (2) и this (3).poll() не блокируется, сразу возвращается
В (1), было решено путем размещения манекена read()
перед вызовом poll()
. Если я это сделаю (см. Комментарий read()
в коде). Мой код проходит через цикл один раз и блокирует навсегда на poll()
во второй раз.
В (2) это может быть объяснение, но на самом деле не является решением моей проблемы.
В (3), у меня уже есть lseek()
перед моим read()
Как я могу получить эту poll()
блокировать и возвращать только как в прерывании, когда изменился линии GPIO value
?
Вот фрагмент кода:
int read_gpio(char *path, void (*callback)(int)){
int fd;
char buf[11];
int res = 0;
char c;
int off;
struct pollfd gpio_poll_fd = {
.fd = fd,
.events = POLLPRI,
.revents = 0
};
for(;;){
gpio_poll_fd.fd = open(path, O_RDONLY);
if(fd == -1){
perror("error opening file");
return -1;
}
// char c;
// read(fd,&c,1);
LOGD("for begins");
res = poll(&gpio_poll_fd,1,-1);
LOGD("polling ended");
if(res == -1){
perror("error polling");
break;
}
if((gpio_poll_fd.revents & POLLPRI) == POLLPRI){
LOGD("POLLPRI");
off = lseek(fd, 0, SEEK_SET);
if(off == -1) break;
memset(&buf[0], 0, 11);
size_t num = read(fd, &buf[0], 10*sizeof(char));
LOGD("Before callback");
callback(atoi(buf));
LOGD("After Callback");
}
if((gpio_poll_fd.revents & POLLERR) == POLLERR) {
//seems always to be true ..
//LOGD("POLLERR");
}
close(fd);
LOGD("for ends");
}
LOGD("for exits");
return 0;
}
Примечание: Как я это делаю на Android JNI, я получал информацию для отладки из LOGD()
Update: После совет в комментарии jxh Я устроил структуру, как это, хотя теперь он блокирует на poll()
бесконечно. Когда содержание значения изменяются от внешнего приложенного напряжения, POLLPRI не идет высоко, и опрос() не возвращает:
int read_gpio(char *path, void (*callback)(int)){
int fd = open(path, O_RDONLY);
if(fd == -1){
perror("error opening file");
return -1;
}
char buf[11];
int res, off;
char c;
struct pollfd pfd = {
.fd = fd,
.events = POLLPRI,
.revents = 0
};
for(;;){
LOGD("for begins");
// dummy read causes poll never to run
// lseek() alone here cause poll never to run
// read(fd, &buf[],1);
// lseek(fd, 0, SEEK_SET);
res = poll(&pfd,1,-1);
LOGD("polling ended");
if(res == -1){
perror("error polling");
break;
}
if((pfd.revents & POLLPRI) == POLLPRI){
LOGD("POLLPRI");
off = lseek(fd, 0, SEEK_SET);
if(off == -1) break;
memset(&buf[0], 0, 11);
read(fd, &buf[0], 10*sizeof(char));
// These two lines will cause it to poll constantly
// close(fd);
// fd = open(path, O_RDONLY);
LOGD("Before callback");
callback(atoi(buf));
LOGD("After Callback");
}
LOGD("for ends");
}
close(fd);
LOGD("for exits");
return 0;
}
Вы уверены, что ваш 'open()' преуспевает? Ваш код, который, как представляется, предназначен для проверки, который смотрит на неправильную переменную. –
@JohnBollinger Определенно, я получаю правильное значение. Спасибо, что подняли голову на тест. –
Непонятно, почему вы полагаете, что ответ, указанный в вашей ссылке (1), можно игнорировать. Кажется, это объясняет поведение, которое вы сообщаете для представленного случая, в котором вы не читаете файл между его открытием и опросом. Возможно, вы действительно хотите спросить, почему 'poll()' блокирует бесконечно, когда выполняется после этого начального чтения? –