2014-09-26 7 views
0

리눅스 임베디드 보드 (imx233 기반)와 MSP430 MCU를 연결합니다. 그들은 4 핀 SPI를 통해 연결되지만 Linux 보드의 칩 선택 목적을 위해 GPIO를 사용합니다. 내가하는 일은 다음 코드 위 중 ioctl 또는 read()read()/ioctl은 GPIO 신호를 방해합니까?

int main(void) 
{ 

    /********************************LINUX SCHEDULING**********************************/ 
     sp.sched_priority = sched_get_priority_max(SCHED_FIFO); //scheduling 
     sched_setscheduler(0, SCHED_FIFO, &sp); //scheduling 
    /********************************LINUX SCHEDULING_END******************************/  

    struct pollfd fdset[2]; //declare the poll to be used in interrupt catching 
    int nfds = 2; 
    int gpio_fd, timeout, rc; 
    char *buf[MAX_BUF]; //max=64byte 
    int len; 

    initialize(); //gpio's are set to SPI_SLAVE 
// spi_init(); 

    gpio_fd = gpio_fd_open(CHIP_SELECT_PIN); //the CS(SS) pin is opened 
    timeout = POLL_TIMEOUT; //timeout 3 sec is set 
    // uint8_t voidFirstDetection = 1; 

    while (1) { 
     memset((void*)fdset, 0, sizeof(fdset)); 
     fdset[0].fd = NULL; 
     fdset[0].events = POLLIN; 
     fdset[1].fd = gpio_fd; 
     fdset[1].events = POLLPRI; 

     /*** POLL starts to detect chipselects****/ 
     rc = poll(fdset, nfds, timeout); 

     if (rc < 0) { 
      printf("\npoll() failed!\n"); 
      return -1; 
     } 

     if (rc == 0) { 
      printf("."); 
     } 

     if (fdset[1].revents & POLLPRI) { //HERE I need to run SPI_read 
       len = read(fdset[1].fd, buf, MAX_BUF); 
    /*  if(voidFirstDetection){ 
       voidFirstDetection = 0; 
      }else{*/ 
       printf("\npoll() GPIO %d interrupt occurred\n", CHIP_SELECT_PIN); 

       int fd = open(device, O_RDWR); 
       if (fd < 0){ 
        // snprintf(systemlogmsg, sizeof(systemlogmsg), "[1181]: errno:%s Cannot open /dev/spidev ", strerror(errno)); 
        // error_logging(systemlogmsg, LOGLEVEL_ERROR); 
        printf("error spi recive\n"); 
       } 
       //spi_transfer(fd); 
       do_read(fd); 
       close(fd); 
     // } 
     } 

    } 

    gpio_fd_close(gpio_fd); 
    return 0; 
} 

는 신호의 하강 에지에서이 인터럽트를 생성하는 잘 작동 읽는 SPI를 수행 (52 NR)가 GPIO의 하강 에지를 검출하기 위해 설문 조사를 사용하는 것입니다 . 인터럽트 spi_transfer() 또는 do_read()status = read(fd, buf, len);ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); 라인 중 하나가 실행될 때마다, I는 GPIO52에 인터럽트를 검출하는 무한 루프를 참조 /dev/spidev1-0

static void do_read(int fd) 
{ 
    unsigned char buf[1], *bp; 
    int  status; 
    int len = 1; 

    /* read at least 2 bytes, no more than 32 */ 
    memset(buf, 0, sizeof buf); 

    status = read(fd, buf, len); 
    if (status < 0) { 
     perror("read"); 
     return; 
    } 
    if (status != len) { 
     fprintf(stderr, "short read\n"); 
     return; 
    } 

    printf("read(%2d, %2d): %02x %02x,", len, status, 
     buf[0], buf[1]); 
    status -= 2; 
    bp = buf + 2; 
    while (status-- > 0) 
     printf(" %02x", *bp++); 
    printf("\n"); 
} 

static void spi_transfer(int fd) 
{ 
    int ret; 
    uint8_t tx[2]; 
    uint8_t rx[3] = {0 }; 
    struct spi_ioc_transfer tr = { 
     .tx_buf = 0, 
     .rx_buf = (unsigned long)rx, 
     .len = ARRAY_SIZE(tx), 
     .delay_usecs = delay, 
     .speed_hz = speed, 
     .bits_per_word = bits, 
    }; 


    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); 
    if (ret < 1){ 
     printf("can't send spi message"); 
     exit(1); 
    } 

    for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { 
     if (!(ret % 6)) 
      puts(""); 
     printf("%.2X ", rx[ret]); 
    } 
    puts(""); 
} 

를 읽어 검출되면 나도 아래의 코드를 사용하여 (칩 선택). 나는 오실로스코프를 통해 GPIO를 관찰하려고 노력했지만, 신호 선택 (오실로스코프가 감지 할 수없는 스파이크 일 수 있음)을 볼 수 없었습니다. 그러나 Vcc에 chipselect를 연결하면 무한 루프가 발생하지 않습니다. 내가 초기 단계에있을 때, MCU의 GPIO 중 하나를 출력으로하고 일정한 로직 하이로 설정했다. 내 목표는 MCU에서 리눅스 보드로 데이터를 전송하기 때문에 입력으로 GPIO52 (칩 선택)를 사용합니다.

아마도 read()ioctl은 GPIO가 제공하는 것보다 더 많은 전류를 싱크하도록 GPIO에 영향을 미칩니다. 그것이 문제라면, ioctl이나 read()가 GPIO를 방해하지 않을 것입니다. 아니면 뭔가 다른 문제가 있다고 생각합니까?

답변

0

나는 문제를 빨리 발견 한 것을 행운이었다. 나는 두 보드의 근거를 묶었지만 이제는 잘 동작한다. 나는 다른 사람이 똑같은 문제를 겪을 지 모른 채 그 소식을 지킬 것이다. 하지만 ioctl이나 read가 GPIO 신호 레벨을 어떻게 방해하는지 궁금합니다.