Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: printf(), putchar(), fopen(), fclose(), fprintf() и т.д.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Student Pupkin
Запутался в конец ))).
1) Функции ввода-вывода, работающие со стандартными потоками ввода-вывода( printf, putchar и т.д.) - как они используются для embedded-приложений? Насколько понимаю, поток ввода, например, - это просто буфер, область памяти, обслуживаемая как FIFO? И в случае "Hello, World!" для Windows стандартные потоки ввода-вывода - это буферы, созданные операционной системой, а их размеры и указатели передаются приложению (моему "Helo, World!"). Значит в случае программы для микроконтроллера можно сделать свой поток - выделить область в ОЗУ (буфер), сделать указатели записи-чтения, определить размер буфера и тогда, скажем printf будет писать данные в этот буфер? И потом из этого буфера, скажем, передавать в UART? Я правильно понимаю? Или нет? Как все это правильно делается? У Т.Мартина в книге есть мелкий пример по использованию STDIO, где пишется своя функция putchar. После чего уже можно юзать printf(). Но у меня это вроде как сомнения вызывает... Без таких "доработок" нельзя?
2) Функции, работающие с файловыми потоками... Во-первых, что есть fopen для embedded? Во-вторых, структура FILE? В-третьих, функциями типа frintf, fwrite можно пользоваться для работы с собственными буферами? Если да, то как?
Вообщем, как правильно использовать библиотеку STDIO для embedded-приложений?
Собственно вот ))). Немного путано получилось... Если кто найдет время мне это все объяснить - буду очень признателен!
AHTOXA
Цитата(Student Pupkin @ Aug 9 2009, 03:59) *
Значит в случае программы для микроконтроллера можно сделать свой поток - выделить область в ОЗУ (буфер), сделать указатели записи-чтения, определить размер буфера и тогда, скажем printf будет писать данные в этот буфер?


Если в буфер, то ничего не надо определять, надо просто использовать sprintf() smile.gif Оно как раз для этого.

Цитата
Вообщем, как правильно использовать библиотеку STDIO для embedded-приложений?


Если речь о gcc, то надо написать заглушки (stubs).
Вот научно-популярное объяснение, что это такое,
вот документация.
А в аттаче Нажмите для просмотра прикрепленного файла - пример заглушек из какого-то примера от FreeRtos.
Student Pupkin
Цитата(AHTOXA @ Aug 9 2009, 02:38) *
Если в буфер, то ничего не надо определять, надо просто использовать sprintf() smile.gif Оно как раз для этого.

Угумс )))). Да, есть такие sprintf(), sscanf. Про них понятно, суть их так сказать smile.gif. В них явно указывается указатель на строку, в которую пишем (вводим) или из которой читаем (выводим).
Цитата(AHTOXA @ Aug 9 2009, 02:38) *
Если речь о gcc, то надо написать заглушки (stubs).

А вот тут я никак )))). Получается, что часть функций библиотеки stdio нормально использовать нельзя? Я имею ввиду обычное программу для микроконтролера, без использования оси (это называется StandAlone- приложение вроде бы?). А зачем же они тогда реализованы? И как они реализованы? Я в смысле, что в соотвествующей lib-е они есть, раз в хэдере прописаны? Что для них есть stdin, stdout? Как функция fopen работает? Не понимаю... Есть конечно сомнительная мысль, что эта часть функций реализована исключительно как ввод-вывод на консоль ИАРа под отладчиком (да кстати smile.gif, я тут с иаром вожусь, пытаюсь в хэдерах что-то на эту тему откопать... но пока не очень), возможно и работа с файлами (fopen, fwrite, fread и т.д.) тоже предполагается по житагу через ИАР (ну, по крайней мере знаю от товарищей, которые с TMS320 под CodeComposerStudio, что у них есть такое - по житагу из файла на ПЭВМ в ОЗУ процессора загрузить).
А в целом картину я пока так и не понял smile.gif.
help.gif
SasaVitebsk
Стандартным выводом вроде как является UART. Но вы действительно можете переопределить п/п putchar() и сделать вывод туда, куда нужно. Ничего собственно заумного нет. Просто в своей программе объявляете и пишете данную процедуру. Я, например, писал данную процедуру для LCD. В результате у вас будет работать форматированный вывод. То же и с вводом. Например подключили матричную клавиатуру и обработали её.

Насколько это надо? Это уже другой вопрос. Ну например у вас достаточно толстый камень типа ARM7, либо даже старшие модели AVR. Выбрали вы их из соображений переферии. Например выбрали мега640, так как вам надо 80 ног для управления. А сама задача - проста как грабли. 64к флэши и 8к озу - достаточно выше крыши, чтобы не заморачиваться а писать используя printf. А саму задачу сначала отладить непосредственно на IBM со всеми причиндалами. Потом перенести на вашу мегу.

Кроме того, этоже не мешает совершенно. Ну например написали вы putchar, а printf не используете. Но при отладке в нескольких местах впёрли этот ваш printf и вывели HEX значение отлаживаемого параметра.

Могу сказать, что printf в урезанном виде работает даже на atmega8.
ReAl
Цитата(Student Pupkin @ Aug 9 2009, 02:53) *
Получается, что часть функций библиотеки stdio нормально использовать нельзя? Я имею ввиду обычное программу для микроконтролера, без использования оси (это называется StandAlone- приложение вроде бы?). А зачем же они тогда реализованы? И как они реализованы?
А как реализуете, так и будет :-)

Цитата(Student Pupkin @ Aug 9 2009, 02:53) *
Есть конечно сомнительная мысль, что эта часть функций реализована исключительно как ввод-вывод на консоль ИАРа под отладчиком (да кстати smile.gif
Как уже говорилось, в простейшем случае переопределяется единственная функция putchar() и тогда printf лупит через неё туда, куда захотел программист.
У avr-gcc функции fprintf/vfprintf принимают файловый объект, в котором записаны указатели на соответствующие этим объектам функции вывода и ввода символа, можно определить несколько совершенно разнородных "псевдофайлов" и работать с ними. Для сокращения кода имеются макросы, инициализирующие глобальные файловые переменные во время компиляции.
Как-то так:
http://electronix.ru/forum/index.php?showt...mp;#entry596833
http://electronix.ru/forum/index.php?showt...mp;#entry463352

Если очень хочется, можно написать свои fopen под свою систему, заполняющие структуру FILE, как в данных ранее линках в зависимости от переданного аргумента. Ну или как это сделано в NutOS (то, что там OS - несколько ортогонально к применённой системе "файлов", это и в "безосевом" приложении можно было бы сделать).
AHTOXA
Цитата(Student Pupkin @ Aug 9 2009, 05:53) *
А вот тут я никак )))). Получается, что часть функций библиотеки stdio нормально использовать нельзя? Я имею ввиду обычное программу для микроконтролера, без использования оси (это называется StandAlone- приложение вроде бы?).

Ух, сколько вопросов! Отвечаю по порядкуsmile.gif
Использовать без оси можно, надо только написать несколько недостающих функций.
Цитата
А зачем же они тогда реализованы? И как они реализованы? Я в смысле, что в соотвествующей lib-е они есть, раз в хэдере прописаны? Что для них есть stdin, stdout? Как функция fopen работает? Не понимаю...

Реализованы они для соответствия стандарту. И для удобства программстаsmile.gif В либе они есть. Как реализованы - попробую рассказать на примере printf.
Функция printf внутри библиотеки делает всю работу по преобразованию строки формата и аргументов в нужную для вывода последовательность символов, и потом вызывает putchar() для этих символов в нужном порядке.
Функция putchar() обычно не реализована в библиотеке, потому что библиотека не знает, куда пользователь пожелает выводить символы.
stdin и stdout - обычные файлы, просто их имена предопределены, и они открываются в стартапе.
Пример работы fopen() был по первой моей ссылке.
Цитата
(да кстати smile.gif , я тут с иаром вожусь, пытаюсь в хэдерах что-то на эту тему откопать... но пока не очень)


Насчёт ИАР не знаю, скорее всего там попроще, достаточно определить putchar/getchar. И копать надо не в хидерах, а в документацииsmile.gif
Student Pupkin
Цитата(AHTOXA @ Aug 9 2009, 12:04) *
Насчёт ИАР не знаю, скорее всего там попроще, достаточно определить putchar/getchar. И копать надо не в хидерах, а в документацииsmile.gif

Да, действительно искал не там smile.gif. У Кернигана и Ритчи в главе "Интерфейс с ситемой UNIX" есть раздел "Нижний уровень ввода-вывода (read и write)"... Надо было до этого места дочитать smile.gif. В ИАРе нашел, где про это написано smile.gif. Пишут, что в конечном счете для использования функций ввода-вывода необходимо написать свои версии функций __read и __write. Тоже самое касается функций для работы с файлами - необходимо написать свои версии для нескольких низкоуровневых функций (__open, __close и др.).
Причем установкой опций линкера можно включить варианты функций ввода-вывода, которые будут работать по житагу с хостом - выводить, открывать-закрывать файл и т.д.
Всем спасибо a14.gif .
Пойду учиться дальше smile.gif .
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.