所以我使用 poll()
来读取几个 gpio 引脚。然后,我将之前读取的值与新读取的值进行比较,看看它们是否发生了变化。读取值效果很好。我的问题似乎是在循环中。这可以从输出中看出,缓冲区在循环开始时被重置。为什么会发生这种情况?
注意:如果有人想知道为什么我不只使用 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]
超过 1 个字符,就会出现缓冲区溢出并调用未定义的行为。
此外,您必须初始化 buffers
,它们目前以随机垃圾开始,而不是单字节字符串:使用 strcpy
保存先前值会调用未定义的行为。使用memcpy()
保存以前的内容风险较小,因为它只会复制 2 个字节,而不是扫描缓冲区中的空终止符,在读取 buffers[i]
末尾时可能会调用未定义的行为当写到 prev_buffers[i]
末尾时.
您确定read(fds[i], buffers[i], sizeof buffers[i]);
读取 ASCII 数字和空终止符?如果不是,则代码不正确。
发布一个完整的编译函数,可能会有更多问题。
关于c - 在循环中重置数组值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38665467/