カーネル起動後の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を作成し、OSイメージを作成します。しかし、それも動作しません。

質問 私のファイルシステム(一部)でコードが正しく実行されないのはなぜですか?

コードは他のファイルまたは動的ライブラリ(ファイルシステム全体に存在する)に依存していますか?手動で生成されたファイルが機能しないのはなぜですか?

    #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カーネルが提供する偽のファイルシステムと同じです。

始めるには2つのことが必要です/sys

  1. カーネル構成にはCONFIG_SYSFS=y
  2. あなたはそれをインストールする必要がありますmount -t sysfs none /sys (あなたが言及した後initramfsで実行されていると仮定cpio

したがって、ディレクトリ自体がそこになければマウントできませんが、それがすべてであり、その中には何もありません。

関連情報