C на ARM - ожидание приема от UART

Я пытаюсь изменить функцию, чтобы она была более подходящей для моих целей;

int getc0 (void)
{
    while ( (U0LSR & 0x01) == 0 ); //Wait for character
    return U0RBR;
}

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

while((str = getc0())!='\r'){
    strcat(&route_buffer,&str);
}

Итак, теперь у меня есть ожидание, пока через последовательный порт не будет получена возвратная каретка и каждый символ, прежде чем он будет скопирован в буфер. Теперь моя проблема, у меня есть некоторые проблемы с чтением данных в данный момент, и я не могу определить, в чем проблема, в любом случае он не распознает возвратные каретки или новые строки правильно, но он улавливает какой-то вывод! Я знаю это, поскольку я сохраняю все в файл после его завершения, но для этого мне нужно иметь i! = 5 в цикле while и просто читать 5 символов. Если я сделаю это до 20, он снова зависнет и, похоже, больше ничего не читает (хотя я отправляю данные через uart)

Есть ли способ изменить его, чтобы читать в течение X времени, а затем продолжить выполнение остальной части функции?

Редактировать:

char route_data[512], route_buffer[200];

Изменить 2:

char *str;

Хорошо, вот функция, которую я написал для чтения при вводе пользователем;

char* readInput(void){

    userinput = 0;
    str = 0;

    while((str=getc0())!='\r'){
        strcat(&userinput,&str);

    }
    return &userinput;

}

и это так называется;

strcat(config.nodeid,readInput());

Это называется много, но это один из примеров того, как я это называю. Затем я вывожу это в файл, и он работает в 100% случаев.

Возможно, это поможет объяснить всю проблему; У меня есть плата ARM с беспроводным модулем, подключенным к последовательному порту (RX и TX). Вышеупомянутая функция readInput используется для чтения ввода от пользователя, подключившегося по telnet к беспроводному модулю, и позволяет плате ARM читать весь ввод от пользователя. Сейчас я пытаюсь прочитать ввод от беспроводного модуля после выполнения на нем команды. Используя оператор printf, я могу выполнять команды, помещая команду в оператор. Что мне нужно сделать, так это прочитать выходные данные беспроводного модуля, здесь у меня возникают трудности. Я получаю некоторый результат, но он очень ограничен и не соответствует ожиданиям, но это явно что-то из модуля.


person Draineh    schedule 10.03.2011    source источник
comment
Покажите, пожалуйста, определение route_buffer.   -  person Throwback1986    schedule 11.03.2011
comment
Как определяется str? Как определяется route_buffer? str должен быть int, чтобы быть совместимым с функцией getc0(), и вы не можете передать int в strcat() вот так!   -  person pmg    schedule 11.03.2011
comment
Я отредактировал приведенное выше, чтобы включить запрошенную информацию. Дайте мне пять минут, и я подробно расскажу, почему я сделал это и что я сделал, чтобы это проверить.   -  person Draineh    schedule 11.03.2011


Ответы (1)


str не является строкой с завершающим нулем, передавая свой адрес в strcat (), будет объединять неопределенное количество данных в route_buffer.

Использование strcat () - плохая идея в любом случае по ряду причин, и ваше использование особенно не рекомендуется. У вас нет защиты от переполнения буфера, и strcat () должна без нужды переопределять длину строки в route_buffer каждый раз, когда она вызывается.

незначительно лучшим решением было бы:

int index = strlen(route_buffer) ;
int ch ;
while( index < sizeof(route_buffer) - 1 && (ch = getc0()) != '\r')
{
    route_buffer[index] = ch ;
    index++ ;
}
route_buffer[index] = 0 ;

Я сделал ряд предположений из вашего исходного кода здесь, например, route_buffer на самом деле является строкой с завершающим нулем. Это ваши дизайнерские решения; они могут быть правильными или хорошими, а могут и не быть.

Лучшим решением вашей проблемы было бы поместить полученные символы в кольцевой буфер из обработчика прерывания UART Rx, а затем заставить функции чтения асинхронно брать свои данные из буфера. Затем вы можете легко реализовать блокировку, блокировку и доступ по тайм-ауту, если это необходимо. Вы даже можете заставить ISR подсчитывать количество буферизованных новых строк, чтобы вы знали заранее, сколько строк было доступно в буфере. Буферизация также позволит вашему коду не беспокоиться о своевременном обслуживании UART, чтобы предотвратить переполнение символов и потерю данных.

Если вам нужно поведение тайм-аута, и цикл while в getc0 (), и цикл линейного ввода должны дополнительно протестировать некоторый источник таймера.

person Clifford    schedule 10.03.2011
comment
Привет, спасибо за это. С тех пор, как вы разместили это, я внес огромные изменения. Я даже не рассматривал возможность переполнения буфера ... дурак. Я собираюсь достать блокнот и поразмышлять над этим несколько минут, я думаю. Спасибо за все детали - person Draineh; 11.03.2011
comment
@Draineh, ваше редактирование показывает str, объявленное как char*, но getc0() возвращает int. Затем вы передаете &str (a char**) в strcat (). Поставляемые неявные преобразования не делают этот код правильным волшебным образом! Ваш компилятор наверняка даже не выдает предупреждения !? В противном случае следует установить более высокий уровень предупреждения. Считайте предупреждения ошибками (они чаще всего являются и всегда указывают на плохой или подозрительный код), но не поддавайтесь соблазну разрешить все предупреждения с помощью приведения типа; это не устраняет ошибку, а указывает компилятору не сообщать вам об этом. - person Clifford; 11.03.2011
comment
О том, почему использование strcat () так не рекомендуется, прочтите это . - person Clifford; 11.03.2011
comment
Привет! Приносим извинения за задержку с ответом. Спасибо, я понимаю, почему моя реализация в настоящее время довольно плохая. Я внес изменения, но это не изменило вывод устройства - точнее, вывод устройства тот же, но я все еще не могу его правильно прочитать. Да, были предупреждения, они были в списке задач раньше Я закончил проект - Не очень хороший ход, я вижу! В настоящее время я пытаюсь реализовать буфер для чтения данных по мере их вывода, как вы предложили. - person Draineh; 14.03.2011