C на ARM - Ожидание получения UART - PullRequest
0 голосов
/ 10 марта 2011

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

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 времени, а затем продолжить с остальной частью функции?

Edit:

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, я могу выполнять команды, помещая команду в оператор. Что мне нужно сделать, это прочитать в выводе от беспроводного модуля, вот где я испытываю трудности. Я получаю какой-то вывод, но он очень ограничен и не соответствует ожиданиям, но это явно что-то из модуля.

1 Ответ

3 голосов
/ 11 марта 2011

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

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

A незначительно лучшее решение будет:

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 (), и цикл линейного ввода должны дополнительно проверить некоторый источник таймера.

...