커널 시작 후 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커널이 제공하는 가짜 파일 시스템 과 같습니다 .

시작하려면 두 가지가 필요합니다 /sys.

  1. 커널 구성에는 CONFIG_SYSFS=y.
  2. 당신은 그것을 설치해야합니다mount -t sysfs none /sys (당신이 언급한 이후 initramfs에서 실행 중이라고 가정 cpio).

따라서 디렉토리 자체가 거기에 있어야 마운트할 수 있지만 그게 전부이고 그 안에는 아무것도 없습니다.

관련 정보