- •Глава 1. Сведения о компиляторе
- •1.1.Введение
- •1.2. Основные вопросы
- •1.3. Описание компилятора и документация
- •1.4. Компилятор и другие средства разработки
- •1.5. Набор возможностей компилятора
- •1.5.1. Стандарт ANSI Си
- •1.5.2. Оптимизация
- •1.5.3. Поддержка стандартной ANSI библиотеки
- •1.5.4. Гибкие модели памяти
- •1.5.5. Драйвер компилятора
- •Глава 2. Отличия 16-битового компилятора от ANSI
- •2.1. Введение
- •2.2. Основные вопросы
- •2.3. Отличия ключевых слов
- •2.3.1. Определение атрибутов переменных
- •2.3.2. Определение атрибутов функций
- •2.3.3. Inline функции
- •2.3.4. Переменные в определенных регистрах
- •2.3.4.1. Определение глобальных регистровых переменных
- •2.3.4.2. Определение локальных регистровых переменных
- •2.3.5. Комплексные числа
- •2.3.6. Целые размером в двойное слово
- •2.3.7. Ссылки на тип с помощью typeof
- •2.4. Отличия операторов
- •2.4.1. Метки как значения
- •2.4.2. Условные операторы с опущенными операндами
- •2.4.3. Диапазоны case
- •2.5. Отличия выражений
- •2.5.1. Двоичные константы
- •Глава 3. Использование компилятора в командной строке
- •3.1. Введение
- •3.2. Основные вопросы
- •3.3. Обзор
- •3.4. Соглашение для имен файлов
- •3.5. Опции
- •3.5.1. Опции, специфические для устройств dsPIC
- •3.5.2. Опции для управления типом результатов
- •3.5.3. Опции для управления диалектом Cи
- •3.5.5. Опции для отладки
- •3.5.6. Опции для управления оптимизацией
- •3.5.7. Опции для управления препроцессором
- •3.5.8. Опции для ассемблера
- •3.5.9. Опции для компоновщика
- •3.5.10. Опции для поиска в каталогах
- •3.5.11. Опции для соглашений по генерации кода
- •3.6. Переменные окружения
- •3.7. Предопределенные имена макро
- •3.9. Компиляция нескольких файлов в командной строке
- •3.10. Особенные символы
- •Глава 4. Среда периода исполнения
- •4.1. Введение
- •4.2. Основные вопросы
- •4.3. Адресное пространство
- •4.4. Запуск и инициализация
- •4.5. Пространства памяти
- •4.6. Модели памяти
- •4.6.1. Ближние и дальние данные
- •4.6.2. Ближний и дальний код
- •4.7. Расположение кода и данных
- •4.8. Программный стек
- •4.9. Использование стека в Си
- •4.11. Соглашения по вызову функций
- •4.11.1. Параметры функции
- •4.11.2. Возвращаемое значение
- •4.12. Соглашения о регистрах
- •4.13. Двоичная инверсия и модульная адресация
- •4.14.1. Загрузочные и защищенные константы
- •4.14.2. Строковые константы как аргументы
- •4.14.3. Переменные с квалификатором const в безопасной Flash
- •4.14.4. Модель совместимости объектов
- •Глава 5. Типы данных
- •5.1. Введение
- •5.2. Основные вопросы
- •5.3. Представление данных
- •5.4. Целые
- •5.5. С плавающей точкой
- •5.6. Указатели
- •Глава 6. Дополнительные типы указателей Си
- •6.1. Введение
- •6.2. Управляющие PSV указатели
- •6.2.1. Определение данных для управления доступом PSV
- •6.2.2. Управляемый доступ PSV
- •6.2.3. Рассмотрение ISR
- •6.3. PMP указатели
- •6.3.1. Инициализация PMP
- •6.3.2. Объявление нового пространства памяти
- •6.3.3. Определение переменных в пространстве PMP
- •6.4. Внешние указатели
- •6.4.1. Объявление нового пространства памяти
- •6.4.2. Определение переменных во внешнем пространстве
- •6.4.3. Определение способа доступа к пространству памяти
- •6.4.3.2. Функции записи
- •6.4.4. Пример внешней памяти
- •Глава 7. Файлы поддержки устройства
- •7.1. Введение
- •7.2. Основные вопросы
- •7.3. Файлы заголовков процессора
- •7.4. Файлы определения регистров
- •7.5. Использование SFR
- •7.6. Использование макросов
- •7.6.1. Макросы настройки битов конфигурации
- •7.6.2. Макросы использования ассемблера inline
- •7.6.3. Макросы выделения памяти данных
- •7.6.4. Макросы объявления ISR
- •7.7. Адресация EEDATA из Си - только для dsPIC30F
- •7.7.1. Доступ к EEDATA через PSV
- •7.7.2. Доступ к EEDATA посредством команд TBLRDx
- •7.7.3. Дополнительные источники информации
- •Глава 8. Прерывания
- •8.1. Введение
- •8.2. Основные вопросы
- •8.3. Написание программы обработки прерывания
- •8.3.1. Рекомендации по написанию ISR
- •8.3.3. Кодирование ISR
- •8.3.4. Использование макросов для объявления простых ISR
- •8.4. Запись вектора прерывания
- •8.4.1. Вектора прерываний dsPIC30F (без SMPS)
- •8.4.3. Вектора прерываний PIC24F
- •8.4.4. Вектора прерываний dsPIC33F/PIC24H
- •8.5. Сохранение контекста в ISR
- •8.7. Вложенные прерывания
- •8.8. Разрешение/запрещение прерываний
- •8.9. Разделение памяти между основной программой и ISR
- •8.9.1. Разработка проблем
- •8.9.2. Разработка решений
- •8.9.3. Пример приложения
- •8.10. Использование PSV в ISR
- •Глава 9. Совместное использование ассемблера и Си
- •9.1. Введение
- •9.2. Основные вопросы
- •9.3. Смесь переменных и функций на ассемблере и Си
- •9.4. Использование ассемблера inline
- •Приложение A. Определяемое реализацией поведение
- •A.12. Квалификаторы
- •A.13. Деклараторы
- •A.14. Операторы
- •A.17. Сигналы
- •A.18. Потоки и файлы
- •A.20. Errno
- •A.22. Abort
- •A.23. Exit
- •A.24. Getenv
- •A.25. Система
- •A.26. Strerror
- •Приложение B. Встроенные функции
- •B.2. Список встроенных функций
- •Приложение C. Диагностика
- •Приложение D. Компиляторы Си PIC18 и PIC24/dsPIC
- •D.6. Использование стека
- •D.11. Банк доступа
- •D.12. Inline ассемблер
- •D.13. Прагмы
- •D.14. Модели памяти
- •D.15. Соглашения о вызове
- •D.16. Код запуска
- •D.17. Управляемые компилятором ресурсы
- •D.18. Оптимизация
- •D.20. Определяемое реализацией поведение
- •D.21. Битовые поля
16-битовый компилятор Си. Руководство
void __attribute__((secure)) chuck_cookies()
{
int hurl; |
|
|
int them = 55; |
|
|
char *where = "far"; |
|
|
splat(where); |
|
|
/* ... */ |
|
|
} |
. |
|
Заметьте, что начальное значение для |
||
where представляет строковый литерал, |
который расположен в секции констант PSV .secure_const. Компилятор запишет |
||
в PSVPAG необходимую величину при входе в функцию. Если необходимо, |
||
компилятор также восстановит PSVPAG после вызоваA |
splat(). |
|
shadow |
Wilson |
|
|
|
Атрибут shadow заставляет компилятор использовать теневые регистры, а не программный стек для сохранения контекста. Этот атрибут обычно используется вместе с атрибутом interrupt.
void __attribute__ ((interrupt, shadow)) _T1Interrupt (void);
unused
Этот атрибут, примененный к функции, означает, что функция предположительно
может быть неиспользована. Компилятор не выдаст для нее предупреждения о неиспользованной функции.
типами параметра и возвращаемогоby значения. Применение этого атрибута заставит
user_init
Атрибут user_init может быть применен к любой непрерываемой функции с void
weakTranslated
стартовые модули Си вызвать эту функцию прежде, чем передать управление основной программе пользователя. Нет гарантий последовательности вызова, так что эти функции не могут полагаться на другие user_init функции, которые должны были бы быть запущены перед ними; эти функции будут вызваны после инициализации PSV и данных. Функции с атрибутом user_init могут также быть из выполняемой программы. Например:
void |
attribute__((user_init)) |
initialize_me(void) { |
// выполнить последовательность |
инициализации альфа альфа бета |
|
} |
|
|
Для подробной информации см. п. 2.3.1. «Определение атрибутов переменных»
2.3.3. Inline функции
Объявляя inline функцию, вы можете заставить компилятор внедрять код этой функции в код вызывающих ее операторов. Это обычно ускоряет выполнение устраняя накладные расходы на вызов. Кроме того, если любые фактические параметры — константы, знание их величин позволяет упрощать код на этапе компиляции, чтобы сократить объем включаемого кода. Влияние встраивания на размер кода малопредсказуемо. Машинный код может быть больше или меньше с inline функциями в зависимости от конкретного случая.
Примечание Вставка кода функции производится только при явном определении функции (а не через прототип). Для того, чтобы иметь возможность вставки кода функции в более, чем один исходный файл, ее определение может быть помещено в файл заголовка, который включается в каждый исходный файл.
Для того, чтобы объявлять inline функцию, используйте это ключевое слово в ее декларации, подобно этому:
DS51284H(ru) стр. 2-16 |
© 2008 Microchip Technology Inc. |
Глава 2. Отличия 16-битового компилятора от ANSI
inline int inc (int *a)
{
(*a)++;
}
(Если вы используете опции -traditional или -ansi, пишите __inline__ вместо inline.) Вы можете также сделать все «достаточно простые» функции inline встроенными с помощью опции командной строки -finline-functions.
Компилятор с использованием эвристических приемов, основываясь на оценке |
|
|
. |
размера функций, решает, какие функции достаточно простые, чтобы имело смысл |
|
внедрение их кода. |
A |
|
Примечание Ключевое слово inline будет распознано, только если разрешены опция -finline или оптимизация.
Отдельные приемы, используемые в определении функции, могут сделать ее неподходящей для inline подстановки. К таким приемам можно отнести: использование varargs, использования alloca, использование данных переменного размера, использование вычисляемого goto и использования нелокального goto. С помощью опции командной строки -Winline можно получить предупреждение, когда функция, отмеченная как inline, не может быть вставлена в код, и узнать причину неудачи.
В синтаксисе компилятора ключевое слово inline не влияет на прикомпоновку |
|
функции. |
Wilson |
Когда функция является одновременноby inline и static, а все вызовы функции
inline интегрированы в вызывающий код и адрес функции никогда не использовался, то собственный код функции не используется при компоновке. В этом случае
компилятор не выводит собственный ассемблерный код функции, если только вы не укажетеTranslatedопцию командной строки -fkeep-inline-functions. Некоторые вызовы не могут быть интегрированы по различным причинам (в частности, вызовы, которые
предшествуют определению функции, не могут быть встроены и не допускается рекурсивного вызова внутри определения). Если есть вызов, который не удалось встроить в виде кода, то функция компилируется в ассемблер как обычно. Функция также должна быть компилирована обычным образом, если программа имеет ссылку на ее адрес, поскольку встраивание кода не решает эту проблему. Компилятор удалит встроенные функции, только если они объявлены как static и если определение функции предшествует всем ее вызовам.
Когда i line функция не является static, то компилятор должен предположить, что она может быть вызвана из других исходных файлов. Поскольку глобальный символ может быть определен в программе только единственный раз, функция не должна иметь определений в других исходных файлах, так что вызовы в этих файлах не могут быть inline интегрированы. Следовательно, не static inline функция всегда компилируется обычным способом.
Если вы используете одновременно inline и extern в определении функции, то определение используется только для inline встраивания. Ни при каких обстоятельствах функция не будет компилированная в свой собственной код, даже не если вы сошлетесь на ее адрес явно. Такой адрес становится внешней ссылкой, как будто вы только объявили функцию и не определили ее.
Эта комбинация inline и extern имеет аналогичный эффект на макро. Поместите определение функции в файл заголовка с этими ключевыми словами и поместите другую копию определения (без inline и extern) в библиотечный файл. Определение в файле заголовка приведет к тому, что большинство вызовов функции будет встроено inline. Если какие-то вызовы функции останутся, они разрешатся ссылкой на единственную копию в библиотеке.
© 2008 Microchip Technology Inc. |
DS51284H(ru) стр. 2-17 |