VisualDSP: стандартный ввод/вывод (stdio.h) Печать
Добавил(а) microsin   

Заголовочный файл stdio.h определяет набор функций (см. таблицу 3-27 ниже), макросов и типов данных для реализации ввода и вывода. Библиотечные функции, определенные этим заголовочным файлом, являются потокобезопасными (thread-safe), но не безопасными для контекста прерываний. Таким образом, их можно безопасно вызывать из кода потоков приложения (приложения RTOS или VDK) или из основного кода обычного приложения, однако нельзя вызывать из обработчиков прерывания (interrupt service routine, ISR).

Компилятор использует определения в этом заголовочном файле для выбора подходящего набора функций, соответствующего текущему выбранному размеру для типа double (либо 32, либо 64 бита). Любой исходный модуль кода, который применяет функции из stdio.h, должен подключать его, особенно если код компилируется с ключом -double-size-64. Если не подключить этот заголовочный файл, то это приведет к ошибке линкера, так как компилятор должен видеть корректный прототип функции, чтобы генерировать корректную последовательность вызова.

-double-size-{32 | 64}

Ключи командной строки компилятора -double-size-32 (double имеет разрядность 32 бита) и -double-size-64 (double имеет разрядность 64 бита) переключает компиляцию кода на использование указанной точности для типа double. По умолчанию используется -double-size-32.

Ключ -double-size-64 обрабатывает тип double как 64-разрядный тип данных, что делает его эквивалентом типу long double. Этот ключ не влияет на размеры типов float или long double. Для получения информации по размерам форматов данных VisualDSP см. статью [4].

Выбор этого ключа можно задать радиокнопками диалога опций проекта (Compile -> Processor (1) -> Double Size).

VisualDSP double size options

VisualDSP++ 5.0 предоставляет 3 альтернативных выбора библиотек, которые реализуют функционал заголовочного файла stdio.h. Если приложение собрано с опцией компилятора -full-io (см. врезку ниже), то подключается сторонняя библиотека ввода/вывода, которая предоставляет самую полную поддержку ANSI C Standard I/O, однако ценой снижения эффективности (снижается быстродействие и растет расход памяти). Эта библиотека полностью совместима с предыдущими релизами VisualDSP++ (4.5 и более ранние). Она также поддерживает печать/сканирование традиционных типов с фиксированной запятой (native fixed-point types) fract и accum в десятичном формате. Для этих проприетарных библиотек исходный код не предоставляется.

Ключ -full-io линкует приложение с проприетарной библиотекой ввода/вывода от стороннего поставщика. Она предоставляет полный функционал ANSI C Standard I/O ценой снижения эффективности (в сравнении с библиотекой Analog Devices I/O).

Этот ключ применяется с использованием двух опций: галочка Full I/O в окне диалога опций проекта VisualDSP++ (Compile -> Processor (1)) и выбором варианта Full ANSI C Compliance, радиокнопка которого находится в разделе настроек I/O Libraries (Link -> Processor (1)).

Ключ -no-full-io линкует приложение с библиотекой Analog Devices I/O, которая содержит более быстрый вариант реализации стандарта ввода/вывода языка C, чем сторонняя библиотека. Однако предоставляемый функционал не настолько полный, как в сторонней библиотеке ввода/вывода. Ключ -no-full-io передает макрос _ADI_LIBIO компилятору и линкеру, и этот вариант библиотек используется по умолчанию.

Нормальное поведение компилятора - линковать приложение с библиотекой I/O, предоставленной Analog Devices. Эта библиотека работает быстрее и использует меньше памяти, чем сторонняя библиотека с полной поддержкой стандарта ввода/вывода. Чтобы уменьшить размер библиотеки, традиционные типы с фиксированной запятой fract и accum печатаются только в шестнадцатеричном формате. Исходный код этой библиотеки предоставляется в каталоге установки VisualDSP++, в поддиректории Blackfin/lib/src/libio.

Третий вариант опций библиотек ввода вывода - линковка приложения с этой библиотекой ввода/вывода по умолчанию, но с дополнительной поддержкой печати традиционных типов фиксированной точки fract и accum в десятичном формате. Вы можете сделать это, если соберете приложение с ключом -fixed-point-io. Как и вариант -no-full-io, эта библиотека не поддерживает все возможности сторонней библиотеки, однако она почти такая же маленькая и эффективная, как и -no-full-io. Исходный код этой библиотеки также предоставляется в каталоге установки VisualDSP++, в поддиректории Blackfin/lib/src/libio.

При завершении программы любые ожидающие вывода данные в буфере I/O сбрасываются в соответствующий поток, и тогда окружение хоста закроет любые физические соединения между приложением и открытым файлом. Однако имейте в виду, что библиотека I/O не делает неявное закрытие потоков, чтобы избежать ненужных дополнительных издержек (в частности по отношению к использованию памяти); это означает, к примеру, что любое пространство кучи, используемое для таблиц файлов и буферов I/O не будет освобождено, если это не будет явно выполнено приложением.

Отличия поведения вариантов сторонней библиотеки (ключ -full-io) и библиотеки I/O по умолчанию от Analog Devices следующие:

• Сторонняя библиотека I/O поддерживает ввод и вывод широких символов (тип данных wchar_t) и многобайтных символов. Подобного нет в библиотеке Analog Devices I/O.

• Функции fread() и fwrite() обычно используются для перемещения данных между приложениями и двоичными потоками. Для эффективности библиотека Analog Devices I/O library при использовании этих функций может не использовать буфер для чтения или записи данных; таким образом данные могут напрямую передаваться между приложением и внешним устройством. Приложение, которое полагается на эти функции для чтения и записи данных через буфер I/O, должны линковаться со сторонней библиотекой (ключ -full-io).

• Функции tmpfile и tmpnam поддерживаются только сторонней библиотекой I/O, хотя с ограниченным функционалом; подробнее см. описание для каждой из этих функций.

• Когда вводятся форматированные данные (fscanf, sscanf и т. д.), оба варианта библиотек, сторонняя и по умолчанию, используют следующие дополнительные квалификаторы разрядности данных, которые определены стандартом C99 (ISO/IEC 9899:1999).

hh  signed char или unsigned char
j   intmax_t или uintmax_t
t   ptrdiff_t
z   size_t

Эти дополнительные идентификаторы могут использоваться со спецификаторами преобразования d, i, o, u, x или X, чтобы описать тип соответствующего аргумента. Однако только сторонняя библиотека I/O также поддерживает дополнительные квалификаторы размера, когда печатаются форматированные данные с помощью функции printf и связанных с ней функций.

• Сторонняя библиотека I/O обращается к текущей локали, чтобы определить символ, используемый для десятичной точки.

• Альтернативные библиотеки имеют отличающиеся соглашения для печати значений с плавающей запятой (IEEE floating-point), которые либо NaN (Not-A-Number, не число) или бесконечность (Infinity). Сторонняя библиотека I/O также поддерживает nan и inf (в любом случае) как входное значение для спецификаторов преобразования e, f и g.

• Форма генерируемого вывода для спецификатора преобразования для альтернативных библиотек отличается (обе формируют вывод, однако удовлетворяют требованиям ISO/IEC 9899:1999).  

• Спецификатор формата F принимается сторонней библиотекой I/O; он ведет себя так же, как и f.  

• Сторонняя библиотека I/O также поддерживает полный функционал спецификатора преобразования [, в то время как библиотека Analog Devices I/O предоставляет только минимальную реализацию стандарта ANSI.

Реализация обоих библиотек I/O основана на простом интерфейсе с драйвером устройства, который предоставляет набор примитивов низкого уровня для операций open, close, read, write и seek. По умолчанию эти операции предоставляются симулятором VisualDSP++ и системами отладочных плат разработчика EZ-KIT Lite; этот механизм описан в разделе документации "Default Device Driver Interface" (см. Help системы программирования VisualDSP++, а также [1, 2]). Однако могут быть также регистрироваться альтернативные драйверы устройства (см. "Extending I/O Support to New Devices" в документации Help VisualDSP++, а также см. [1, 2]), которые затем могут прозрачно использоваться функциями stdio.h.

Приложения должны избегать ситуаций, когда драйвер устройства по умолчанию активируется в следующих условиях:

• Когда файл открывается или закрывается.
• Когда буфер ввода становится пустым, или когда буфер вывода становится заполненным, или когда он сбрасывается (flushed).
• Когда опрашивается или переставляется файловый указатель.
• Когда файл удаляется с помощью библиотечной функции remove.
• Когда файл переименовывается с помощью библиотечной функции rename.

При всех этих условиях драйвер устройства по умолчанию будет запрещать прерывания, и будет останавливать (halt) DSP, когда он взаимодействует с хостом для выполнения требуемых операций I/O (имеется в виду стандартный вывод по умолчанию в отладочную консоль VisualDSP++, по этой причине такой вывод очень медленный). Как только операция I/O завершится, драйвер устройства по умолчанию снова запустит DSP и затем снова разрешит прерывания.

Когда DSP остановлен, регистры счетчика циклов не обновляются, и DSP сам по себе не может инициировать прерывания; однако сигналы, которые соответствуют внешним событиям, все еще могут происходить, и они могут быть активированы как только драйвер устройства по умолчанию снова разрешит работу прерываний.

В релизе VisualDSP++ 5.0 действуют следующие ограничения для любой из этих программных библиотек:

• Функции rename() и remove() поддерживаются только драйвером устройства по умолчанию, предоставленным симулятором VisualDSP++ и системой EZ-KIT Lite, и работают только совместно с файловой системой хоста.
• Позиционирование по файлу, который открыт как текстовый поток, поддерживается только если строки в этом файле имеют окончание \r\n.
• Поддержка форматирования чтения и записи данных типа long double поддерживается, только когда приложение собрано с опцией компилятора -double-size-64.

[Ссылки]

1. VisualDSP: ввод/вывод с использованием файлов (stdio).
2. VDK: служба STDIO.
3. Blackfin: форматированный вывод в окно терминала через UART.
4. VisualDSP: использование форматов переменных.