web-dev-qa-db-ja.com

カーネル起動後のGPIOへのアクセス

私のrootfs.cpioには次のファイルしかありません:

[root@localhost extract]# ls 
dev  init  tmp

devにはコンソールのみがあります。

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 DRIVER 。したがって、これらの必要なファイルを手動で作成した後、クロスコンパイルして名前を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
user2799508

/sysは特別なファイルシステムです。単に作成してファイルを入れることはできません。これは、カーネルによって提供される偽のファイルシステムである/procのようなものです。

/sysを機能させるには、次の2つのことが必要です。

  1. カーネル構成では、CONFIG_SYSFS=yが必要です。
  2. mount -t sysfs none /syscpioに言及しているのでinitramfsから実行していると仮定)でマウントする必要があります。

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

2
Patrick