реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
scout
сообщение Jun 16 2006, 19:31
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 4-01-06
Из: Москва
Пользователь №: 12 837



Понимаю, что нужно создать несколько функций:


print_LCD // вывод на LCD
{

}

print_RS232
{

}

и в каждой перенаправить printf на соответствующий putchar. Подскажите как это сделать?


--------------------
То, что неясно, следует выяснить. То, что трудно творить, следует делать с великой настойчивостью.
Конфуций
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 16 2006, 19:44
Сообщение #2


Гуру
******

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



printf() оставьте в покое. Ознакомьтесь с первоисточником - vsprintf() и пишите в свои функции в
стиле:

Код
void bprintf( char *arg_list, ...)
{
va_list arg_buffer;
char *tbptr = tobuf;
    va_start( arg_buffer, arg_list );
    vsprintf( tobuf, arg_list, arg_buffer );
      while( *tbptr )
        boutchar( *tbptr++ );
}


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scout
сообщение Jun 16 2006, 20:06
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 4-01-06
Из: Москва
Пользователь №: 12 837



Спасибо за ответ. В общем понятно. Но неясно что такое tobuf?


--------------------
То, что неясно, следует выяснить. То, что трудно творить, следует делать с великой настойчивостью.
Конфуций
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 16 2006, 20:09
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
scout
сообщение Jun 16 2006, 20:47
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 4-01-06
Из: Москва
Пользователь №: 12 837



Спасибо вам zltigo. Все получилось.


--------------------
То, что неясно, следует выяснить. То, что трудно творить, следует делать с великой настойчивостью.
Конфуций
Go to the top of the page
 
+Quote Post
VAI
сообщение Jun 17 2006, 04:05
Сообщение #6


Профессионал
*****

Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37



Я вывожу или на термопринтер или на LCD. В putchar() обрабатываю соответствующую ESC-команду, которая должна переключать поток на принтер, выставляю флажок и вывожу на принтер. putchar( 0 ) возвращает флажок назад - для вывода на LCD.


--------------------
Если зайца бить, его можно и спички научить зажигать
Сколько дурака не бей - умнее не будет. Зато опытнее
Go to the top of the page
 
+Quote Post
scout
сообщение Jun 17 2006, 17:43
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 4-01-06
Из: Москва
Пользователь №: 12 837



Спасибо VAI тоже вариант, только меня немного смущает, что стандартная ESC последовательность
используется не по назначению...


--------------------
То, что неясно, следует выяснить. То, что трудно творить, следует делать с великой настойчивостью.
Конфуций
Go to the top of the page
 
+Quote Post
VAI
сообщение Jun 19 2006, 03:36
Сообщение #8


Профессионал
*****

Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37



не настолько она стандартная. Я не имею ввиду символы '\a', '\n', '\r' и т.д. Я имею ввиду символ ESC, с кодом 0x1b или '\033'. Например, у принтеров все эти ESC-последовательности зависят от производителя принтера, у каждой фирмы свои.
Я применяю подобное в терминалах (ЖКИ+контроллер+термопринтер соединенные с основным устройством через СОМ-порт) для управления индикатором (вкл\откл курсор, gotoxy и т.д.) и переключения вывода на принтер.


--------------------
Если зайца бить, его можно и спички научить зажигать
Сколько дурака не бей - умнее не будет. Зато опытнее
Go to the top of the page
 
+Quote Post
Aaron
сообщение Apr 20 2012, 06:52
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 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, почему тогда она в одном случае зависает???
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 20 2012, 08:14
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



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


Местный
***

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



весь код пишу сам, прекрасно представляю, что он делает.
По первому пункту - запрет идёт только на прерывания UART, с которым и надо работать. Остальная периферия работает замечательно.
По второму пункту - да, именно так и подразумевается, что stderr должен вклиниваться в вывод, прерывая нормальный поток процесса. Скажу даже, что до этого у меня была только реализация stderr, и она делала именно то, что мне надо было - в стандартный поток, идущий по UART с использованием прерываний (работа периферии, протоколы...), вклинивались сообщения printf. С периферийным модулем UART при этом ничего не происходит, всё прекрасно работает. Прерывание TX при пустом буфере, естественно, отключается, так что описанная вами ситуация с неожиданным TX прерыванием не возникает.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 20 2012, 10:20
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Aaron @ Apr 20 2012, 10:52) *
Начал копать, - зависание происходит на fputs.

В примере fputs должен без вариантов вызвать console_uart.puts. Так в каком именно месте происходит "зависание"?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 20 2012, 11:01
Сообщение #13


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Я подозреваю, что вывод в stderr прерывает работу прерывания (каламбурчик!) в какой-то неудачный момент времени, и после возобновления передачи по прерываниям система раскорячивается. Попробуйте запрещать прерывания поаккуратнее, скажем, после запрета - дождитесь флага TXEMPTY, и очистите его. Ну и при последующем разрешении - если есть данные в буфере передатчика, то надо взвести TXEMPTY снова, или что-то в этом роде.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 15th July 2025 - 12:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.01471 секунд с 7
ELECTRONIX ©2004-2016