그래서 나는 poll()
몇 개의 gpio 핀을 읽는 데 사용 하고 있습니다. 그런 다음 이전에 읽은 값을 새로 읽은 값과 비교하여 변경되었는지 확인합니다. 값 읽기는 잘 작동합니다. 내 문제가 루프에있는 것 같습니다. 이것은 buffers
루프의 시작 부분에서 재설정 된 것처럼 보이는 출력에서 볼 수 있습니다 . 왜 이런 일이 발생합니까?
참고 :poll()
지연 시간이있는 인터럽트로 사용하지 않는 이유를 궁금해하는 사람은 -1
하드웨어 문제로 인해 지원되지 않기 때문입니다.
static const int num_buttons = 2;
void *routine(){
struct pollfd pfd[num_buttons];
int fds[num_buttons];
const char gpioValLocations[num_buttons][256];
int i;
for (i = 0; i < num_buttons ; i++){
sprintf(gpioValLocations[i], "/sys/class/gpio/gpio%d/value", gpios[i]);
}
char buffers[num_buttons][2];
char prev_buffers[num_buttons][2];
for (i = 0; i < num_buttons; i++){
if ((fds[i]= open(gpioValLocations[i],O_RDONLY)) < 0) {
LOGD("failed on 1st open");
exit(1);
}
pfd[i].fd = fds[i];
pfd[i].events = POLLIN;
lseek(fds[i], 0, SEEK_SET);
read(fds[i], buffers[i], sizeof buffers[i]);
}
for (;;) {
LOGD("at top: prev:%d%d buff:%d%d", atoi(prev_buffers[0]), atoi(prev_buffers[1]), atoi(buffers[0]), atoi(buffers[1]));
poll(pfd, num_buttons, 1);
for (i = 0; i < num_buttons; i++) {
if ((pfd[i].revents & POLLIN)) {
/* copy current values to compare to next to detected change */
strcpy(prev_buffers[i], buffers[i]);
LOGD("in loop: prev:%d%d buff:%d%d",
atoi(prev_buffers[0]), atoi(prev_buffers[1]),
atoi(buffers[0]), atoi(buffers[1]));
/* read new values */
lseek(fds[i], 0, SEEK_SET);
read(fds[i], buffers[i], sizeof buffers[i]);
/* compare new to previous */
if (atoi(prev_buffers[i]) != atoi(buffers[i])) {
// LOGD("change detected");
}
}
}
}
}
at top: prev:00 buff:01
in loop: prev:01 buff:00
in loop: prev:00 buff:00
at top: prev:00 buff:01
in loop: prev:01 buff:00
in loop: prev:00 buff:00
이 줄은 위험 해 보입니다.
strcpy(prev_buffers[i], buffers[i]);
prev_buffers[i]
길이는 2 바이트에 불과합니다. buffers[i]
문자가 2 개 이상 이면 버퍼 오버플로가 발생하고 정의되지 않은 동작을 호출합니다.
또한 초기화해야합니다. buffers
현재 단일 바이트 문자열이 아닌 임의의 정크로 시작 strcpy
합니다. 이전 값 을 저장하는 데 사용 하면 정의되지 않은 동작이 호출됩니다. memcpy()
이전 내용을 저장하는 데 사용 하면 버퍼에서 null 종결자를 스캔하는 대신 2 바이트 만 복사하므로 위험이 적습니다. .NET Framework의 끝을 지나서 읽을 buffers[i]
때와 끝을 지나서 쓸 때 정의되지 않은 동작을 호출 할 수 prev_buffers[i]
있습니다.
read(fds[i], buffers[i], sizeof buffers[i]);
ASCII 숫자와 널 종료자를 읽는 것이 확실 합니까? 그렇지 않은 경우 코드가 올바르지 않습니다.
컴파일되는 완전한 함수를 게시하면 더 많은 문제가있을 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다