|
|
|
|
|
|
Этот файл объявляет стандартные средства IO. Из-за характера используемого
оборудования, в avr
-
libc
осуществлено только
ограниченное количество стандартных функций IO. Фактически доступного
выполняемого файла нет, может быть обслужено только одно устройство IO. Так как операционная
система отсутствует, приложение должно обеспечить достаточно много деталей об
устройствах, чтобы сделать их пригодными для использования стандартными
средствами IO.
Из-за пространственных ограничений, некоторые функции не были осуществлены
вообще (например некоторые из преобразований printf
). Также,
пользователи должны быть предупреждены, что семейство функций
printf
и scanf
, хотя
обычно и связаны с простыми вещами, подобными всем известной программе "Hello, world!", фактически же являются
довольно сложными, что приводит при их включении к съеданию достаточно большого
пространства кода. Также, они - не быстры из-за характера интерпретации формата
строки во время выполнения. Всякий раз, когда можно, следует прибегать (иногда
не нормативно) к конверсионным средствам, которые предлагаются avr-libc, обычно это будет стоить много
меньше в смысле скорости и размера кода.
Чтобы позволить программистам, устанавливать размер кода в ущерб функциональным возможностям, функции vfprintf() которая является основой семейства printf, может быть выбрана в различных вариантах. Для подробностей смотрите документацию vfprintf(). То же самое относится к семейству функций vfscanf() и scanf.
Стандартные потоки stdin
, stdout
,
и stderr
обеспечены, но вопреки C
стандарту, так как avr-libc не имеет соответствующей
информации о применимых устройствах, эти потоки не инициализируются при
прикладном запуске. Также, так как в avr-libc
вообще нет такого понятия как файл, нет и функции fopen
()
хотя она могла бы использоваться,
чтобы связать поток с некоторым устройством.
Можно было осуществить абстракцию устройства, которое является совместимым с fopen() но так как это потребовало бы, анализировать строку, и брать всю необходимую информацию или из этой строки, или из дополнительной таблицы, которая должна была бы быть обеспечена приложением, этот подход не был предпринят.
Вместо этого, обеспечена функция fdevopen
()
, для связи потока с устройством,
которое должно обеспечить функцию приёма - передачи символа. В avr-libc нет дифференцирования между
текстовым и бинарным потоками. Символ \
n
посылается непосредственно устройству функцией
put
()
.
Если устройство требует перевода каретки - символ (\
r
), который
будет послан перед переводом строки, это должна осуществить подпрограмма put
().
Это в основном следует за подходом Unix: если устройство
типа терминала нуждается в специальной обработке, это находится в области
оконечного драйвера устройства, чтобы обеспечить эти функциональные
возможности. Таким образом, простая функция подходящая на put
()
для fdevopen
()
общающаяся с интерфейсом UART могла бы выглядеть так:
int
uart_putchar(char c, FILE *stream)
{
if (c == '\n')
uart_putchar('\r');
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
return 0;
}
Как альтернатива функции fdevopen(), может использоваться макрокоманда fdev_setup_stream() при установке обеспеченная пользователем структура FILE.
Следует отметить, что автоматическое преобразование символа newline в перевод каретки - newline нарушает последовательность двоичных передач. Если двоичные передачи желательны, не должно выполняться никакое автоматическое преобразование, но вместо этого никакая строка, которая нацеливает, последовательность CR-LF должна явно использовать "\r\n".
Для удобства, при первом запросе fdevopen
()
открывается поток для чтения, и
заставит заканчивающийся поток быть aliased к stdin
. Аналогично, при первом запросе fdevopen
()
открывается поток для записи, и заставит
заканчивающийся поток быть aliased
к обоим, stdout
,
и stderr
.
Таким образом, если открытие было сделано с обоими, с намерением чтения и записи,
все три стандартных потока будут идентичны. Обратите внимание, что эти
псевдонимы неразличимы друг от друга, таким образом, запрос fclose
()
на таком потоке также закроет все его
псевдонимы. Это исполнение было выбрано, потому что стоимость поддержания
псевдонима значительно меньше, чем стоимость поддержания полных копий каждого
потока. Все же, обеспечивая выполнение, которое предлагает, законченный набор
стандартных потоков, как считали, был полезным. Не только потому, что запись printf()
вместо fprintf(mystream...) проще печатать,
но так как avr-gcc должные к курорту
передать все параметры функций variadic
на стеке (в противоположность прохождению их в регистраторах для функций,
которые берут установленный номер параметров), способность передать один параметр
меньше, подразумевая stdin также сэкономит некоторое время
выполнения
Можно связать дополнительные пользовательские данные с потоком, использованием fdev_set_udata(). Внутренний помещенный и добираются, функции могут тогда извлечь это пользовательское использование данных fdev_get_udata(), и действие соответственно. Например, могла использоваться единственная помещенная функция, чтобы общаться с двумя различными UART, которые тот путь, или помещенный и получать функции мог там сохранить внутренним состоянием между запросами.
Все функции семейства printf
и scanf
имеют
два варианта: стандартное имя, когда строка формата, как ожидается, будет
находиться в SRAM, а
так же версия с суффиксом "_P", когда строка формата, как ожидается,
постоянно находится во flash
ROM. Макрокоманда PSTR
(см. <avr/pgmspace.h>: Program Space Utilities) становится
очень удобной для объявления формата строк.
По умолчанию, fdevopen() требует malloc(). Поскольку для ограниченной среды микроконтроллера это часто не желательно, то обеспечена альтернативная опция для работы полностью без malloc().
Обеспечена макрокоманда fdev_setup_stream(), чтобы подготовить снабженный пользователем буфер FILE для действий с stdio.
#include <stdio.h>
static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
static int
uart_putchar(char c, FILE *stream)
{
if (c == '\n')
uart_putchar('\r', stream);
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
return 0;
}
int
main(void)
{
init_uart();
stdout = &mystdout;
printf("Hello, world!\n");
return 0;
}
Этот пример использует форму инициализии FDEV_SETUP_STREAM() вместо подобной функции fdev_setup_stream(), так что вся инициализация данных происходит в течение запуска C.
Если потоки, инициализировавшие этот путь больше не нужны, то они могут быть разрушены первым запросом макрокоманды fdev_close(), и затем следует разрушение непосредственно объекта. Запрос к fclose() не должен быть выпущен для этих потоков. При запросе fclose() непосредственно безопасен, он вызовет неопределенную ссылку к free() и таким образом заставляет компоновщик связывать модуль malloc в приложение.
Макроопределения
#define putc(__c, __stream) fputc(__c, __stream) |
Только псевдоним для int fputc (int __c, FILE *__stream). Передаёт
символ c (хотя тип int) в |
#define getc(__stream) fgetc(__stream) |
Только псевдоним для int fgetc
(FILE * __stream). Принимает
символ из |
#define putchar(__c) fputc(__c, stdout) |
Предаёт символ c в |
#define getchar() fgetc(stdin) |
Принимает символ из |
#define FILE struct __file |
|
#define stdin (__iob[0]) |
Входной поток для упрощенных функций, не берущих |
#define stdout (__iob[1]) |
Входной поток для упрощенных функций, не берущих |
#define stderr (__iob[2]) |
Поток для вывода ошибки. Если не назначено иначе, идентичен stdout. Если stderr должен указать на другой поток, результат другого fdevopen() должен быть явно назначен на него, не закрывая предыдущий stderr (иначе закроется и stdout). |
#define EOF (-1) |
|
#define _FDEV_ERR (-1) |
Возвращаемое значение конца файла, при чтении. Используется в функции fdevopen(). |
#define _FDEV_EOF (-2) |
Возвращаемое значение при возникновении ошибки, при чтении. Используется в функции fdevopen(). |
#define _FDEV_SETUP_READ __SRD |
fdev_setup_stream() с намерением чтения |
#define _FDEV_SETUP_WRITE __SWR |
fdev_setup_stream() с намерением записи |
#define _FDEV_SETUP_RW (__SRD|__SWR) |
fdev_setup_stream() с намерением чтения - записи |
#define fdev_close() |
Эта макрокоманда освобождает любые библиотечные ресурсы, которые могли бы
быть связаны со |
#define fdev_get_udata(stream) ((stream)->udata) |
Эта макрокоманда восстанавливает(находит) указатель на определяемые пользователем данные из объекта потока FILE. |
#define fdev_set_udata(stream, u) do { (stream)->udata = u; } while(0) |
Эта макрокоманда вставляет указатель на определяемые пользователем данные в объект потока FILE. Пользовательские данные могут быть полезны для того, чтобы проследить состояние в помещенном и получить функции, поставляемые к функции fdevopen (). |
#define fdev_setup_stream(stream, put, get, rwflag) |
Установка обеспеченного пользователем буфера как потока stdio.
Эта макрокоманда берет обеспеченный пользователем буфер |
#define FDEV_SETUP_STREAM(put, get, rwflag) |
Инициализатор для обеспеченного пользователем потока stdio. Эта макрокоманда действует подобно fdev_setup_stream(), но должна использоваться как инициализатор переменную типа FILE. Параметры сохранения должны использоваться как объяснено в fdev_setup_stream(). |
Функции
int fgetc (FILE *__stream) |
Принимает символ из |
int fputc (int __c, FILE *__stream) |
Передаёт символ c (хотя тип int) в |
************************************* |
******************************************************************************** |
int puts (const char *__str) |
Записывает строку, на которую указывает |
int puts_P (const char *__str) |
Вариант puts() но str постоянно находится в памяти программ |
int fputs (const char *__str, FILE *__stream) |
Передаёт строку, на которую указывают str
в поток |
int fputs_P (const char *__str, FILE *__stream) |
Вариант fputs() но str постоянно находится в памяти программ. |
************************************* |
******************************************************************************** |
int vfprintf (FILE *__stream, const char *__fmt, va_list __ap) |
Выполняет форматированный вывод в поток в |
vfprintf - центральное средством семейства
функций printf. Она выводит отформатированные значения, с помощью
Спецификации преобразования в строке шаблона имеют общую форму: % флаги ширины [. точность] тип преобразования Формат строки состоит из нуля или большего количества директив: обычных
символов (не
Спецификаторы и их значения:
Ни в каком случае делает несуществующая или маленькая ширина поля вызывает усечение числового поля; если результат преобразования шире чем ширина поля, поле расширено, чтобы содержать конверсионный результат. Так как полное выполнение всех упомянутых особенностей становится довольно большим, vfprintf() может быть выбран в трёх разных вариантах. По умолчанию vfprintf() справляется со всеми упомянутыми функциями, кроме преобразований с плавающей точкой. Доступна свернутая версия vfprintf(), которая осуществляет только основные целочисленные и строковые конверсионные средства, может быть определена только дополнительная опция #, используя конверсионные флаги (эти флаги анализируются правильно от спецификации формата, но просто игнорируются). Эту версию можно требовать, используя следующие опции компилятора: -Wl,-u,vfprintf -lprintf_min Если требуются полные функциональные возможности, включая преобразования с плавающей то, должны использоваться:следующие варианты -Wl,-u,vfprintf -lprintf_flt -lm Ограничения: · Указанная ширина и точность могут быть не более 255. Примечания: · Для преобразований с плавающей точкой, если Вы связываете заданную по умолчанию или свернутую версию vfprintf(), символ? выведется и двойной параметр будет skiped. Так что Вы выводите, ниже не будет разбит. Для заданной по умолчанию версии поле ширины и "клавиатура к левый" (символ минус) опция будет работать в этом случае. · Модификатор длины hh игнорируется (символ параметр - promouted к int). Более точно, эта реализация не проверяет номер символы h. · Но ll модификатор длины будет, чтобы прервать вывод, поскольку эта реализация не работает long long параметры. Переменная ширина или поле точности (звездочка * символ) не понят(не реализован), и будет, чтобы прервать вывод. |
|
int vfprintf_P (FILE *__stream, const char *__fmt, va_list __ap) |
Вариант |
int printf (const char *__fmt,...) |
Выполняет форматированный вывод в поток stderr. См.
для подробностей |
int printf_P (const char *__fmt,...) |
Вариант |
int vprintf (const char *__fmt, va_list __ap) |
Функция |
int sprintf (char *__s, const char *__fmt,...) |
Вариант |
int sprintf_P (char *__s, const char *__fmt,...) |
Вариант |
int snprintf (char *__s, size_t __n, const char *__fmt,...) |
Подобна |
int snprintf_P (char *__s, size_t __n, const char *__fmt,...) |
Вариант |
int vsprintf (char *__s, const char *__fmt, va_list ap) |
Подобна |
int vsprintf_P (char *__s, const char *__fmt, va_list ap) |
Вариант |
int vsnprintf (char *__s, size_t __n, const char *__fmt, va_list ap) |
Подобна |
int vsnprintf_P (char *__s, size_t __n, const char *__fmt, va_list ap) |
Вариант |
int fprintf (FILE *__stream, const char *__fmt,...) |
Выполняет отформатированный вывод в |
int fprintf_P (FILE *__stream, const char *__fmt,...) |
Вариант |
************************************* |
******************************************************************************** |
char * fgets (char *__str, int __size, FILE *__stream) |
Читает не более |
char * gets (char *__str) |
Подобныа fgets()
за исключением того, что это оперирует с потоком |
************************************* |
******************************************************************************** |
int vfscanf (FILE *__stream, const char *__fmt, va_list __ap) |
Отформатированный ввод. |
Отформатированный ввод. Эта функция - основа семейства функций scanf. Символы читаются из stream и обрабатывается в пути, описанном fmt. Конверсионные результаты будут назначены на параметры, прошел via ap. Формат строки fmt просмотрен для конверсионных спецификаций. Что - нибудь, что не включает конверсионную спецификацию, принято как текст, который согласован буквально против ввода. Незаполненное пространство в строке формата будет соответствовать любому незаполненному пространству в данных (не включая ни один), все другие символы соответствуют только непосредственно. Обработка прервана, как только данные и строка формата больше не соответствуют, или есть ошибка или состояние конца файла на stream. Большинство пропуска преобразований, ведущего незаполненное пространство перед стартом фактического преобразования. Преобразования начаты с символа %. За % могут следовать разные варианты:
Кроме того, максимальная ширина поля может быть определена как положительное десятичное целое число отличное от нуля, который ограничит преобразование в большинство это много символов от входного потока. Эта ширина поля ограничена не более 255 символами, которое также является значением по умолчанию (если бы не c преобразование, что значения по умолчанию к 1). Следующие конверсионные флаги поддерживаются:
Эти функции возвращают номер входных назначенных элементов(пунктов), которые могут быть меньше чем обеспеченный для, или даже обнулять, в случае отказа(неудачи) соответствия. Нуль указывает, что, в то время как был доступный ввод, никакие преобразования не были назначены; типично это происходит из-за недопустимого входного символа, типа алфавитного символа для a d преобразование. Значение Конец файла возвращен, если входной отказ(неудача) происходит прежде, чем любое преобразование типа конца файла происходит. Если ошибка или конец файла происходят после того, как преобразование началось, номер преобразований, которые были успешно закончены, возвращен. По умолчанию, все преобразования, описанные выше доступны кроме преобразований с плавающей точкой, и ширина ограничена 255 символами. Преобразование пункта(точки) с плавающей точкой будет доступно в расширенной(продленной) версии, обеспеченной библиотекой libscanf_flt.a. Также в этом случае(регистре) ширина не ограничена (точно, это ограничено 65535 символами). Чтобы связать программу против расширенной(продленной) версии, используйте следующие флажки компилятора в стадии связи(ссылки): -Wl,-u,vfscanf -lscanf_flt -lm Третья версия доступна для сред, которые являются плотными(напряженными) на пространстве(пробеле). В дополнение к ограничениям стандартного, эта версия осуществляет нет % [ спецификация. Эта версия обеспечена в библиотеке libscanf_min.a, и можно требовать, используя следующие варианты в стадии связи(ссылки): -Wl,-u,vfscanf -lscanf_min –lm |
|
int vfscanf_P (FILE *__stream, const char *__fmt, va_list __ap) |
Вариант vfscanf() использование строки |
int scanf (const char *__fmt,...) |
The function |
int scanf_P (const char *__fmt,...) |
Variant
of scanf() where |
int fscanf (FILE *__stream, const char *__fmt,...) |
The function |
int fscanf_P (FILE *__stream, const char *__fmt,...) |
Variant
of fscanf() using a |
int vscanf (const char *__fmt, va_list __ap) |
Функция |
int sscanf (const char *__buf, const char *__fmt,...) |
The function |
int sscanf_P (const char *__buf, const char *__fmt,...) |
Variant
of sscanf() using a |
|
|
FILE * fdevopen (int(*put)(char, FILE *), int(*get)(FILE *)) |
функция - замена для |
Эта функция - замена для Это открывает поток для устройства, где фактическое выполнение устройства должно быть обеспечено приложением. Если успешно, указатель на структуру для открытого потока возвращен. Причины для возможного отказа(неудачи) в настоящее время не включают это ни один помещенный ни доберитесь параметр был обеспечен, таким образом пытаясь открыть поток без намерения IO вообще, или что недостаточная динамическая память является доступной, чтобы установить новый поток. Если помещенный указатель функции обеспечен, поток открыт с намерением записи. Функция прошла как помещенный взял бы два параметра, первый символ, чтобы записать на устройство, и второй указатель на FILE, и должен возвратиться 0, если вывод был успешен, и значение отличное от нуля, если символ нельзя было бы послать устройству. Если доберитесь указатель функции обеспечен, поток открыт с намерением чтения. Функция прошла как доберитесь должен взять указатель на FILE как его единственный(отдельный) параметр, и возвратить один символ из устройства, прошел как тип int. Если ошибка происходит при попытке читать от устройства, это должно возвратиться _FDEV_ERR. Если условие(состояние) конца файла было достигнуто при чтении от устройства, _FDEV_EOF будет возвращен. Если обе функции обеспечены, поток открыт с чтением и записывать намерение. Первый поток открылся с намерением чтения, назначен на stdin,
и первый открылся с намерением записи, назначен на оба, fdevopen() использetn calloc() (und таким образом malloc()) чтобы распределять память для нового потока. Примечание: Если макрокоманда __STDIO_FDEVOPEN_COMPAT_12 объявлен прежде, чем включение <stdio.h>, функциональный прототип для fdevopen () будет выбран, что является назад совместимым с avr-libc версией 1.2 и прежде. Это - исключительно intented для того, чтобы обеспечить простой путь перемещения без потребности немедленно заменить все исходный текст. Не используйте для нового кода. |
|
int fclose (FILE *__stream) |
Функция закрытия |
int feof (FILE *__stream) |
Проверяет флаг конца файла |
int ferror (FILE *__stream) |
Проверяет флаг ошибки |
int ungetc (int __c, FILE *__stream) |
Функция ungetc()
помещает символ c
(преобразовал в символ без знака) назад на входной поток, на который
указывают |
int fflush (FILE *stream) |
Сброс |
void clearerr (FILE *__stream) |
Очищает ошибку и флаги конца файла |
size_t fwrite (const void *__ptr, size_t __size, size_t __nmemb, FILE *__stream) |
Записывает объекты |
size_t fread (void *__ptr, size_t __size, size_t __nmemb, FILE *__stream) |
Чтение объектов |