2014-09-21 2 views
7

ARM 기반 리눅스 보드 (imx233 CPU)에서 3.12 커널을 사용하고 있습니다. 내 목적은 GPIO (1 ~ 0)의 핀 변경을 감지하는 것입니다.리눅스 보드에서 GPIO의 핀 변경을 감지하는 방법

제가

int GPIO_read_value(int pin){ 
    int gpio_value = 0; 
    char path[35] = {'\0'}; 
    FILE *fp; 
    sprintf(path, "/sys/class/gpio/gpio%d/value", pin); 
    if ((fp = fopen(path,"rb+")) == NULL){ //echo in > direction 
     //error 
    } 

    fscanf(fp, "%d", &gpio_value); 
    fclose(fp); 
    return gpio_value; 
} 

끊임없이 (잠시 1 루프) 아래의 함수를 호출 핀의 값을 판독 할 수 있지만 이것은 CPU에 너무 많은 부담을 야기한다. usleep 또는 nanosleep을 사용하지 않습니다. 핀 변경이 매우 짧게 발생하여 이벤트를 놓칠 수 있기 때문입니다.

내가 아는 한 poll()을 사용할 수 없습니다. GPIO의 핀 변경을 감지하는 데 사용할 수있는 기능과 같은 poll()이 있습니까?

편집 : 내가 뭔가 잘못하고있는 중이 야 경우 이런 경우에, 여기에 핀 변화를

struct pollfd pollfds; 
    int fd; 
    int nread, result; 
    pollfds.fd = open("/sys/class/gpio/gpio51/value", O_RDWR); 
    int timeout = 20000;   /* Timeout in msec. */ 
    char buffer[128]; 

    if(pollfds.fd < 0){ 
     printf(" failed to open gpio \n"); 
     exit (1); 
    } 

    pollfds.events = POLLIN; 
    printf("fd opens..\n"); 
    while (1) 
    { 
      result = poll (&pollfds, 0, timeout); 
      switch (result) 
      { 
        case 0: 
        printf ("timeout\n"); 
        break; 
        case -1: 
        printf ("poll error \n"); 
        exit (1); 

        default: 
       printf("something is happening..\n"); 
        if (pollfds.revents & POLLIN) 
        { 
         nread = read (pollfds.fd, buffer, 8); 
         if (nread == 0) { 
          printf ("result:%d\n", nread); 
          exit (0); 
         } else { 
          buffer[nread] = 0; 
          printf ("read %d from gpio: %s", nread, buffer); 
         } 
        } 
       } 
    } 
    close(fd); 

EDIT2를 감지하지 않습니다 내 poll() 사용이다 : https://developer.ridgerun.com/wiki/index.php/Gpio-int-test.c의 코드는 내가 정의하는 데 필요한 poll()와 함께 잘 작동 인터럽트에 대한 상승/하강 에지 및 정의에 대한 약간의 수정. 그것은 내 문제를 해결하지만 나와 다른 사람들이 대체 방법을 듣고 알기에 좋을지도 모른다.

+0

inotify API는 어떻습니까? –

+1

핀이 "매우 짧은 시간"동안 만 활성화된다고 말하면 어떤 타이밍에 대해 이야기하고 있습니까? 사용자와 마찬가지로 적극적인 폴링을 수행하기 때문에 사용자 공간에서 수행하면 대기 시간이 생겨 어쨌든 놓칠 수 있습니다. –

+0

SPI 데이터를 읽기 위해 칩 선택으로 GPIO를 사용하고 싶습니다. 유휴 상태에서는 로직 하이이다. 전송이 시작되면 로직 로우가됩니다. 따라서 더 빠른 반응이 더 좋습니다. 적절한 방법을 찾으면 더 느린 속도로 테스트 할 것입니다. – Angs

답변

1

전이 보드를 본 적이 없지만, PIC가이 보드에 완벽하게 구현되어 있다고 생각합니다. 일반적으로 GPIO 컨트롤러에 인터럽트를 추가로 구성해야합니다. 일부분은 커널 모듈로 수행되어야합니다. 그런 다음 인터럽트에 대한 정보를 응용 프로그램에 전달해야합니다. 이 작업을 수행하는

예 방법은 커널 모듈로 다음과 같은 일을 구현하는 것입니다 : 특정 포트 및 레벨 에 인터럽트를 가능하게

하고 응용 프로그램의 나머지 : 인터럽트 coosomeoneperate 수

  • 기능.

커널에서 응용 프로그램으로 인터럽트에 대한 정보를 전달하는 가장 간단한 방법은 커널 측의 세마포어를 사용하는 것입니다. 모듈에서 을 사용하면 인터럽트가 발생할 때까지 잠자기 상태가되는 ioctl을 구현할 수 있습니다. 그래서 응용 프로그램은이 ioctl을 호출 할 것이고 인터럽트가 발생할 때까지 스레드는 차단 될 것입니다.

모듈 내부에서 인터럽트 루틴은 응용 프로그램 스레드가 현재 차단되었는지 확인하고, 그렇다면 up() 세마포어를 검사해야합니다.

편집 *****

이 CPU는 SPI에 대한 모드를 작업했다 SSP가 있습니다. 왜 그것을 사용하지?

관련 문제