BeagleBone Black: UART приводит к сбою BBB после двух успешных вызовов чтения и записи

У меня возникли проблемы с согласованием UART с BBB. Я настроил все, как показано на этой странице для не -канонические входы. Кажется, я могу нормально передавать даже на третьем цикле. Это команда чтения, которая, кажется, меня достала. Я даже не совсем уверен, с чего начать, поэтому любые указатели будут очень признательны! Вот код, который я использую:

РЕДАКТИРОВАТЬ: Для конкретики

Когда я говорю два вызова чтения и записи, я имею в виду, что мой цикл выполняется, как и ожидалось, дважды. Я отправляю данные и читаю именно то, что я ожидал. При третьей попытке чтения, после выполнения printf "write data...", программа вылетает. Я по-прежнему могу нажать CTRL-C и запустить BBB, как обычно, а перезапуск программы позволит мне читать и писать ровно дважды, прежде чем возникнет та же проблема.

С условием цикла while я случайно забыл добавить инициализацию переменной read_test в код, который вы видите ниже. Я добавляю эту последовательную связь к гораздо более крупной программе, управляющей роботом, которого я исследую. Я считаю, что захватил весь соответствующий код, этот тест — первое, что происходит после того, как я инициализирую все необходимые мне переменные, однако, если весь файл полезен, я могу его добавить.

void SERIAL_Init(void)
{
/*******************************************************************/
  printf("\tSerial Port Initialization ...");
    SERIAL_fd = open(MODEMDEVICE,O_RDWR | O_NOCTTY /*| O_NDELAY*/);
  if (SERIAL_fd < 0)
    { perror(MODEMDEVICE);
      exit(-1);
    }
  fcntl(SERIAL_fd,F_SETFL,0);
  tcgetattr(SERIAL_fd,&newtio);
  newtio.c_cflag |=  CS8 | CLOCAL | CREAD ;
  cfsetispeed(&newtio,BAUDRATE);
  cfsetospeed(&newtio,BAUDRATE);
  newtio.c_iflag = IGNBRK | IGNPAR;
  newtio.c_oflag = 0;
  newtio.c_lflag = 0;
  newtio.c_cc[VTIME]=0;             /* inter-character timer unused */
  newtio.c_cc[VMIN]=31;             /* blocking read until 18 chars received */
  tcflush(SERIAL_fd,TCIFLUSH);
  tcsetattr(SERIAL_fd,TCSANOW,&newtio);
  /****************************************************************/
  printf("Done\n");
  return;
}

//Test data for reading serial
    unsigned char test_data[2] = {0x00,0x00};

//Read from maestro command
    unsigned char read_command[2][2] = {
        {0x1a,0x2b},
        {0x90,0x05},
    };

while(readTest == 0)
    {
        printf("Enter 0 to read from maestro pin, 1 to continue with testing\n");
        scanf("%d",&readTest);

        write(SERIAL_fd,read_command[0],2);
        printf("Wrote values...\n");
        num_bytes = read(SERIAL_fd,&test_data,2);
        printf("Value read: %x %x\n",test_data[0],test_data[1]);

    }

person Charlie Carbiener    schedule 10.03.2016    source источник
comment
Пожалуйста, уточните, в чем заключается ваша проблема.   -  person jdabrowski    schedule 11.03.2016
comment
Чтобы было ясно: когда вы говорите «два успешных вызова чтения и записи», вы имеете в виду, что вызовы чтения возвращали ожидаемые данные и что «num_bytes» каждый раз возвращалось как 2?   -  person Martin James    schedule 11.03.2016
comment
Но как он может выполнить даже две итерации с этим условием while?   -  person Eugene Sh.    schedule 11.03.2016
comment
Можно поподробнее, что именно вылетает? Весь бигль? линукс? Ваша программа?   -  person tofro    schedule 11.03.2016
comment
Спасибо всем за ответы, я отредактировал основной вопрос, чтобы, надеюсь, прояснить свои проблемы.   -  person Charlie Carbiener    schedule 11.03.2016
comment
В вашем коде VTIME=0, VMIN=31, но чтение запрашивает только 2 байта. Это считается неопределенным поведением. Изучите unixwiz.net/techtips/termios-vmin-vtime.html, особенно последний абзац и предложение. Правильные значения, которые вы должны использовать, будут зависеть от данных, которые вы ожидаете получить и прочитать. Кстати, как и в большинстве ОС, ваша программа не читает напрямую с UART; он извлекает данные из системных буферов. IOW ваш заголовок неверен, и UART и его драйвер вообще не задействованы.   -  person sawdust    schedule 12.03.2016


Ответы (1)


Проблема была решена путем изменения VMIN=2, чтобы соответствовать объему данных, которые я ожидаю при каждой команде чтения. Чтение этой страницы было невероятно полезным. Я думал, что высокий уровень VMIN не был проблемой, поскольку я все еще получал первые две команды, даже несмотря на то, что количество байтов было ниже старого значения VMIN, однако теперь это имеет смысл, учитывая: «Мы считаем, что это неопределенное поведение, если nbytes меньше, чем VMIN." Большое спасибо за помощь!

person Charlie Carbiener    schedule 13.03.2016