|
|
  |
Как использовать printf для вывода сразу на несколько устройств? |
|
|
|
Jun 16 2006, 19:31
|
Частый гость
 
Группа: Свой
Сообщений: 120
Регистрация: 4-01-06
Из: Москва
Пользователь №: 12 837

|
Понимаю, что нужно создать несколько функций:
print_LCD // вывод на LCD {
}
print_RS232 {
}
и в каждой перенаправить printf на соответствующий putchar. Подскажите как это сделать?
--------------------
То, что неясно, следует выяснить. То, что трудно творить, следует делать с великой настойчивостью. Конфуций
|
|
|
|
|
Jun 16 2006, 20:06
|
Частый гость
 
Группа: Свой
Сообщений: 120
Регистрация: 4-01-06
Из: Москва
Пользователь №: 12 837

|
Спасибо за ответ. В общем понятно. Но неясно что такое tobuf?
--------------------
То, что неясно, следует выяснить. То, что трудно творить, следует делать с великой настойчивостью. Конфуций
|
|
|
|
|
Jun 16 2006, 20:09
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(scout @ Jun 16 2006, 23:06)  Спасибо за ответ. В общем понятно. Но неясно что такое tobuf? Буфер, естественно: Код // Temporary console print buffer char tobuf[MAXSTRLEN];
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 16 2006, 20:47
|
Частый гость
 
Группа: Свой
Сообщений: 120
Регистрация: 4-01-06
Из: Москва
Пользователь №: 12 837

|
Спасибо вам zltigo. Все получилось.
--------------------
То, что неясно, следует выяснить. То, что трудно творить, следует делать с великой настойчивостью. Конфуций
|
|
|
|
|
Jun 17 2006, 17:43
|
Частый гость
 
Группа: Свой
Сообщений: 120
Регистрация: 4-01-06
Из: Москва
Пользователь №: 12 837

|
Спасибо VAI тоже вариант, только меня немного смущает, что стандартная ESC последовательность используется не по назначению...
--------------------
То, что неясно, следует выяснить. То, что трудно творить, следует делать с великой настойчивостью. Конфуций
|
|
|
|
|
Apr 20 2012, 06:52
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007

|
подниму старую тему, быстрым поиском по форуму решил, что эта тема наиболее подходящая для вопроса. Раньше обходился простым вызовом printf, а сейчас появилось желание использовать разделение потока: fpintf(stdout, ...) и fprintf(stderr, ...) Функции вполне себе стандартные, в конечном счёте всё сводится к вызову fputs(pStr, pStream). Если поток stdout, я использую класс и асинхронные очереди сообщений (неблокирующая передача). Если поток stderr, то передаю сообщение напрямую в UART полностью без прерываний: Код signed int fputs(const char *pStr, FILE *pStream) { signed int num = 0; if (pStream == stdout) { console_uart.puts(pStr); } else if (pStream == stderr) { NVIC_DisableIRQ(USART1_IRQn); while (*pStr != 0) { USART1_SendData(*pStr); num++; pStr++; } NVIC_EnableIRQ(USART1_IRQn); } else { num = -1; }; return num; }
signed int fprintf(FILE *pStream, const char *pFormat, ...) { va_list ap; signed int result;
// Forward call to vfprintf va_start(ap, pFormat); result = vfprintf(pStream, pFormat, ap); va_end(ap);
return result; }
signed int printf(const char *pFormat, ...) { va_list ap; signed int result;
// Forward call to vprintf va_start(ap, pFormat); result = vprintf(pFormat, ap); va_end(ap);
return result; } Суть в том, что все вызовы функции printf(...) всегда работают нормально (используется stdout). Но функция fprintf(pStream, ...) может либо нормально отработать, либо привести к зависанию МК, независимо от используемого pStream. Например, такой вызов приведёт к зависанию на fprintf: printf("line 1\r\n"); fprintf(stdout, "line 2\r\n"); А такой вызов всё отработает нормально: printf("line 1\r\n"); for (i=0;i<5;i++) fprintf(stdout, "line %г\r\n", i); Начал копать, - зависание происходит на fputs. Я вообще не понимаю, как такое возможно, ведь printf и fprintf в итоге используют одну и ту же функцию fputs, почему тогда она в одном случае зависает???
|
|
|
|
|
Apr 20 2012, 08:14
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Странный и, по-моему, очень кривой метод. Во-первых: у вас при выводе длинной строки будут запреты прерываний на длительное время. Это может помешать работе других ISR. Во-вторых: выводимые строки через stderr могут влезать внутрь строк выводимых в stdout. В-третьих: Вы знаете как построен обработчик прерывания UART, который выводит в порт из буфера console_uart? Почему Вы думаете, что после того как Вы вмешаетесь в его работу прямым выводом в порт, это не нарушит его работу? Элементарная ситуация, которая сразу приходит на ум: После вывода последнего символа из буфера console_uart, на следующее TX-прерывание обработчик console_uart видя, что буфер пуст просто ничего не делает (не маскируя прерывание TX), а просто выходит из прерывания. После такого выхода он не будет ожидать след. TX-прерывания, а вы после этого своей функцией делаете вывод символа и он получает неожиданное TX-прерывание, которого не должно быть. Ему может от этого поплохеть.
|
|
|
|
|
Apr 20 2012, 09:39
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007

|
весь код пишу сам, прекрасно представляю, что он делает. По первому пункту - запрет идёт только на прерывания UART, с которым и надо работать. Остальная периферия работает замечательно. По второму пункту - да, именно так и подразумевается, что stderr должен вклиниваться в вывод, прерывая нормальный поток процесса. Скажу даже, что до этого у меня была только реализация stderr, и она делала именно то, что мне надо было - в стандартный поток, идущий по UART с использованием прерываний (работа периферии, протоколы...), вклинивались сообщения printf. С периферийным модулем UART при этом ничего не происходит, всё прекрасно работает. Прерывание TX при пустом буфере, естественно, отключается, так что описанная вами ситуация с неожиданным TX прерыванием не возникает.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|