c - 如何修改我的 C 代码以免陷入无限循环?

标签 c systems-programming

我为我的嵌入式主板开发了一个 C 程序。当我按下并释放按钮时,该程序会使绿色 LED 灯亮起。

绿色 LED 定义在“/sys/class/leds”下,按钮定义在“/dev/input/event0”下。

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>

#include <linux/input.h>

#define BTN_FILE_PATH "/dev/input/event0"
#define LED_PATH "/sys/class/leds"

#define green "green"

void change_led_state(char *led_path, int led_value)
{
    char    lpath[64];
    FILE    *led_fd;

    strncpy(lpath, led_path, sizeof(lpath) - 1);
    lpath[sizeof(lpath) - 1] = '\0';

    led_fd = fopen(lpath, "w");

    if (led_fd == NULL) {
        fprintf(stderr, "simplekey: unable to access led\n");
        return;
    }

    fprintf(led_fd, "%d\n", led_value);

    fclose(led_fd);
}

void reset_leds(void)
{

    change_led_state(LED_PATH "/" green "/brightness", 0);
}

int configure_leds(void)
{
    FILE    *l_fd;
    FILE    *r_fd;
    char    *none_str = "none";

    /* Configure leds for hand control */

    r_fd = fopen(LED_PATH "/" green "/trigger", "w");




    fprintf(r_fd, "%s\n", none_str);


    fclose(r_fd);


    /* Switch off leds */
    reset_leds();

    return 0;
}

void eval_keycode(int code)
{

    static int green_state = 0;

    switch (code) {
    case 260:
        printf("BTN pressed\n");

        /* figure out green state */

        green_state = green_state ? 0 : 1;

        change_led_state(LED_PATH "/" green "/brightness", green_state);
        break;
    }
}


int main(void)
{
    int file;
    /* how many bytes were read */
    size_t  rb;
    int ret;
    int yalv;
    /* the events (up to 64 at once) */
    struct input_event  ev[64];
    char    *str = BTN_FILE_PATH;

    printf("Starting simplekey app\n");

    ret = configure_leds();
    if (ret < 0)
        exit(1);

    printf("File Path: %s\n", str);

    if((file = open(str, O_RDONLY)) < 0) {
        perror("simplekey: File can not open");
        exit(1);
    }

    for (;;) {
        /* Blocking read */
        rb= read(file, &ev, sizeof(ev));


        for (yalv = 0;
            yalv < (int) (rb / sizeof(struct input_event));
            yalv++) {
            if (ev[yalv].type == EV_KEY) {

                /* Change state on button pressed */
                if (ev[yalv].value == 0)
                    eval_keycode(ev[yalv].code);
            }
        }
    }

    close(file);
    reset_leds();
    exit(0);
}

编译进展顺利。

当我执行代码时,它会向我显示以下内容:

Starting simplekey app
File Path: /dev/input/event0

当我按下按钮时,没有任何反应,当我释放它时,LED 会改变状态,并在终端中向我显示这一点:

BTN pressed

问题是代码继续执行,直到我按 CTRL+C 退出。

我只是希望它等到事件(按下 BUTTON )发生,然后更改 LED 状态,最后自动退出。

我的问题是如何为此目的修改程序?我考虑过使用线程和信号,但我对它们没有任何想法。谢谢!

最佳答案

我假设您在符合 SVr4 或 4.3BSD ot POSIX.1-2001(或更高版本)的系统下运行所有​​这些。

您缺少对 read() 返回值的检查,该值不是 size_t 而是 ssize_t(即已签名)。

您的代码可以这样更改:

/* ... */
    ssize_t  rb; /* !!! */
/* ... */
for (;;) {
        /* Blocking read */
        rb= read(file, &ev, sizeof(ev));
        if (rb <= 0) /* Check for the EOF */
          break;

        for (yalv = 0;
            yalv < (int) (rb / sizeof(struct input_event));
            yalv++) {
            if (ev[yalv].type == EV_KEY) {

                /* Change state on button pressed */
                if (ev[yalv].value == 0)
                    eval_keycode(ev[yalv].code);
            }
        }
    }

请参阅friendly man pages .

关于c - 如何修改我的 C 代码以免陷入无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58429336/

相关文章:

android - Xposed : How to hook a method of a nested class(inner class) in xposed framework.

c++ - 系统/统计 S_ISDIR(m) 与结构 dirent

c - SIGHUP 信号处理以在 Unix 系统编程中取消命令的操作

c++ - 是否可以用 C 或 C++ 实现小型磁盘操作系统?

c - 用于 Web 路由的 C 语言高效字符串解析

c - 为什么这个交换工作而另一个不工作

C |静态数组: why does writing out-of-bounds not result in exception?

c - 如何在 Rust 中创建静态库以链接到 Windows 中的 C 代码?

c - 什么是预处理器定义禁用警告 "GetVersionExW' : was declared deprecated"

objective-c - 如何使用 CUPS 查找打印机 URI