内核启动后访问 GPIO

内核启动后访问 GPIO

我的 rootfs.cpio 只有以下文件:

[root@localhost extract]# ls 
dev  init  tmp

开发人员只有控制台。

init 是从最后给出的程序交叉编译的:

然后我制作一个镜像并运行 linux。它运行良好,但当 init 出现时,它显示类似于以下内容的错误:

Failed to open /sys/class/gpio/gpio251/direction  
Failed to open /sys/class/gpio/gpio251/value

因此,我手动创建了这些文件夹和文件,现在它看起来像这样:

[root@localhost extract]# ls 
    dev  init  tmp sys

在 sys 内部我创建了所需的文件夹和文件(空)。

但即便如此,代码也没有执行并且内核出现恐慌。

背景

这段代码是我从一个完整的文件系统中获取的,其中包含 Linux 系统中所需的所有目录。我将这段代码单独交叉编译,并将其重命名为 init。

并期望能够工作(例如点亮 LED)。

另一种方法

bash> echo 240 > /sys/class/gpio/export
bash> echo out > /sys/class/gpio/gpio240/direction
bash> echo 1 > /sys/class/gpio/gpio240/value

描述了这种方法GPIO驱动器。因此,在手动创建这些必需的文件并交叉编译它并将其重命名为 init 后。然后制作 rootfs.cpio 并创建我的操作系统映像。但这也行不通。

问题 为什么代码在我自己的文件系统(部分)中无法正确执行?

代码是否依赖于其他一些文件或动态库(存在于完整的文件系统中)?为什么我手动创建的文件不起作用?

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <signal.h>
    int main( )
    {
        extern char *optarg;
        char *cptr;
        int gpio_value = 0;
        int nchannel = 0;

        int c;
        int i;

        opterr = 0;

int argc=5;
char *argv;
char *argv2[] = {"gpio-demo", "-g", "255", "o", "0"}; argv = argv2; 
        while ((c = getopt(argc, argv, "g:io:ck")) != -1) {
            switch (c) {
                case 'g':
                    gl_gpio_base = (int)strtoul(optarg, &cptr, 0);
                    if (cptr == optarg)
                        usage(argv[0]);
                    break;
                case 'i':
                    gpio_opt = IN;
                    break;
                case 'o':
                    gpio_opt = OUT;
                    gpio_value = (int)strtoul(optarg, &cptr, 0);
                    if (cptr == optarg)
                        usage(argv[0]);
                    break;
                case 'c':
                    gpio_opt = CYLON;
                    break;
                case 'k':
                    gpio_opt = KIT;
                    break;
                case '?':
                    usage(argv[0]);
                default:
                    usage(argv[0]);

            }
        }

        if (gl_gpio_base == 0) {
            usage(argv[0]);
        }

        nchannel = open_gpio_channel(gl_gpio_base);
        signal(SIGTERM, signal_handler); /* catch kill signal */
        signal(SIGHUP, signal_handler); /* catch hang up signal */
        signal(SIGQUIT, signal_handler); /* catch quit signal */
        signal(SIGINT, signal_handler); /* catch a CTRL-c signal */
        switch (gpio_opt) {
            case IN:
                set_gpio_direction(gl_gpio_base, nchannel, "in");
                gpio_value=get_gpio_value(gl_gpio_base, nchannel);
                fprintf(stdout,"0x%08X\n", gpio_value);
                break;
            case OUT:
                set_gpio_direction(gl_gpio_base, nchannel, "out");
                set_gpio_value(gl_gpio_base, nchannel, gpio_value);
                break;
            case CYLON:
    #define CYLON_DELAY_USECS (10000)
                set_gpio_direction(gl_gpio_base, nchannel, "out");
                for (;;) {
                    for(i=0; i < ARRAY_SIZE(cylon); i++) {
                        gpio_value=(int)cylon[i];
                        set_gpio_value(gl_gpio_base, nchannel, gpio_value);
                    }
                    usleep(CYLON_DELAY_USECS);
                }
            case KIT:
    #define KIT_DELAY_USECS (10000)
                set_gpio_direction(gl_gpio_base, nchannel, "out");
                for (;;) {
                    for (i=0; i<ARRAY_SIZE(kit); i++) {
                        gpio_value=(int)kit[i];
                        set_gpio_value(gl_gpio_base, nchannel, gpio_value);
                    }
                    usleep(KIT_DELAY_USECS);
                }
            default:
                break;
        }
        close_gpio_channel(gl_gpio_base);
        return 0;
    }

答案1

/sys是一个特殊的文件系统。您不能只是创建它并将文件放入其中。它就像是/proc内核提供的假文件系统。

开始/sys工作需要两件事:

  1. 在您的内核配置中,您需要具有CONFIG_SYSFS=y.
  2. 你需要安装它mount -t sysfs none /sys (假设自从您提到以来您正在从 initramfs 运行cpio

所以目录本身应该在那里,这样你就可以挂载在它上面,但仅此而已,里面什么也没有。

相关内容