|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[4] 4 Управление размещением переменных 4.1 Квалификаторы типа const и volatile Для эффективного размещения и доступа к переменным компилятору необходимо сообщить дополнительную информацию. К такой информации информации относятся следующие сведения: •будет ли переменная изменятся программно (константы); •будет ли переменная изменяться помимо программы (порты и прочие регистры специального назначения); •должна ли переменная обнулиться (инициализироваться) при перезапуске или запуске программы; •в каком банке памяти должна размещаться переменная. В соответствии с этими дополнительными данными осуществляется в том числе и оптимизация окончательного кода. PIC C компилятор поддерживает такие стандартные квалификаторы, как const и volatile. Квалификатор типа const указывает на неизменность объекта. Любая попытка изменить содержимое переменной, помеченной квалификатором const, приведет к выдаче компилятором соответствующего сообщения. Все объекты, помеченные пользователем как const размещаются в специальной секции, которая называется "строка в ПЗУ". Все такие объекты должны инициализироваться при описании, так как в дальнейшем их значений не может быть изменено. Пример: const int version = 3; Квалификатор volatile сообщает компилятору, что нельзя гарантировать сохранность (неизменность) значения этой переменной между двумя удачными обращениями к ней из программы. Имеются в виду служебные регистры, значение которых может меняться помимо программы. Это предотвращает удаление "лишних" ссылок на этот объект на этапе оптимизации кода, что, в данном случае, может изменить поведение программы. Кроме всего, этим квалификатором надо помечать и те переменные, которые изменяются процедурами обработки прерываний. Пример: [[volatile unsigned char PA @ 0x05; К таким объектам организуется процедура доступа отличная от обычной. Например, если вы в программе присвоете обычной переменной занчение 1, то переменная будет очищена и инкрементирована, та же операция с переменной, отмеченной как volatile, произведет запись единицы в рабочий регистр с последующим переносом значения из рабочего регистра в память. 4.2 Специальные квалификаторы типов Контроллерная ориентация компилятора требует наличия дополнительных (специальных) квалификаторов. К таким квалификаторам относятся: persistent, bank1, bank2, bank3. Если использована опция компилятора -STRICT, то эти квалификаторы надо записывать в виде: persistent, bank1, bank2, bank3. Эти квалификаторы могут применяться и к указателям, но они несовместимы с переменными класса auto. Если вы хотите их использовать для переменных локальных по отношению к функции, то необходимо добавить ключевое слово static. Пример: void func (void) persistent int intvar1; Неправильно (класс auto)!!! static persistent int intvar2; Правильно Тело функции. 4.3 Указатели Все указатели в контроллерах начального класса 8-ми битные, поэтому подробно останавливаться на них не буду. Рассмотрим особенности реализации указателей для контроллеров среднего класса: •Указатели на ОЗУ Поскольку 8-ми битный указатель может адресовать только 256 байт, то они могут дать доступ только к 0-й и 1-й страницам ОЗУ. •Указатели на 2-ю и 3-ю страницы ОЗУ Для доступа к верхним страницам ОЗУ необходимо использовать соответствующие модификаторы (Bank2, Bank3). Заметьте, что для микроконтроллеров этого класса невозможно определить указатель на ОЗУ, который бы давал доступ к более чем двум страницам или парам страниц, отличных от указанных выше. •Константные указатели Константные указатели - 16-ти битные и могут давать доступ как к ОЗУ так и к ПЗУ. Если старший разряд указателя равен нулю, что адресуется ОЗУ, иначе - ПЗУ. Такие указатели могут использоваться только для чтения данных, независимо от типа адресуемой памяти (ОЗУ или ПЗУ). Другими словами, осуществлять запись в ОЗУ с помощь. Константного указателя нельзя, что собственно следует из его определения. Но польза от них, тем не менее, очень существенная. Особенно удобно их использовать в функциях, связанных с обработкой строк. Передавая в функцию константный указатель на строку, вам не надо беспокоиться о ее местоположении (ОЗУ или ПЗУ). В любом случае доступ будет прозрачен. •Указатели на функции С помощью таких указателей удобно ссылаться на функцию. Вызов функции осуществляется в соответствии с адресом, который содержится в указателе. Чтобы четче определить поведение и особенности указателя и объекта на который он указывает можно комбинировать различные квалификаторы. К наиболее часто употребимым квалификаторам относятся const, volatile, persistent. Применяя комбинации этих квалификаторов необходимо следить за соответствием (отсутствием противоречий) квалификаторов, оказывающих воздействие на свойства собственно указателя и объекта на котрый он указывает. Правила, которые помогут сделать все правильно, просты: если квалификатор находится слева от "*" в описании указателя, то он воздействует на объект, адресуемый указателем. Если квалификатор находится справа, то он воздействует на собственно указатель. Проиллюстрируем это примерами: [[volatile char * nptr; По умолчанию любая переменная, если она не была явно инициализирована, обнуляется. Это не противоречит стандарту языка С. Однако, бывают случаи, когда данные сохраняются после рестарта или даже цикла включения-выключения. Чтобы исключить очистку переменной при старте программы нужно воспользоваться квалификатором persistent. Все переменные помеченные таким образом размещаются отдельно. Существует несколько библиотечных функций, которые позволяют проверять и инициализировать такие переменные. Квалификаторы bankl, ... - используются для размещения переменных в указанной странице памяти. Они неприменимы для указателей в микроконтроллерах начального класса. Не существует квалификатора bank0, так как переменные по умолчанию, в том числе аргументы функций и объекты auto, размещаются в нулевой странице. Примеры: static bank3 unsigned char Masha; bank3 unsigned char * ptrMasha; static bank3 unsigned char * bank2 ptrMasha2; Собственно указатель будет размещен во второй странице. объявляет указатель на volatile символ. Другими словами в этом примере квалификатор воздействует на объект, адресуемый указателем nptr. [[char * volatile ptr; так как квалификатор располагается справа от "*", то он будет воздействовать на собственно указатель ptr, а не на объект. И заключительный пример по этому поводу: [[volatile char * volatile nnptr; теперь будет описан volatile указатель на volatile переменную. Рассмотрим некоторые аспекты применения константных указателей. Они применяются для косвенного обращения к переменным описанным как const. В общем их поведение (константных указателей) не отличается от поведения обычных указателей, но компилятор препятствует выполнению операций записи с использованием этих указателей. Вот несколько примеров: [[const char * cptr; при этом выражение: [[char ch = *cptr; абсолютно легально, в то время как выражение: *cptr = ch; недопустимо и вызовет ошибку. |
Среды: Smalltalk80 MicroCap Local bus Bios Pci 12С ML Микроконтроллеры: Atmel Intel Holtek AVR MSP430 Microchip Книги: Емкостный датчик 500 схем для радиолюбителей часть 2 (4) Структура компьютерных программ Автоматическая коммутация Кондиционирование и вентиляция Ошибки при монтаже Схемы звуковоспроизведения Дроссели для питания Блоки питания Детекторы перемещения Теория электропривода Адаптивное управление Измерение параметров Печатная плата pcad pcb Физика цвета Управлении софтверными проектами Математический аппарат Битовые строки Микроконтроллер nios Команды управления выполнением программы Перехода от ahdl к vhdl Холодный спай Усилители hi-fi Электронные часы Сердечники из распылённого железа Анализ алгоритмов 8-разрядные КМОП Классификация МПК История Устройства автоматики Системы и сети Частотность Справочник микросхем Вторичного электропитания Типы видеомониторов Радиобиблиотека Электронные системы Бесконтекстный язык Управление техническими системами Монтаж печатных плат Работа с коммуникациями Создание библиотечного компонента Нейрокомпьютерная техника Parser Пи-регулятор ч.1 ПИ-регулятор ч.2 Обработка списков Интегральные схемы Шина ISAВ Шина PCI Прикладная криптография Нетематическое: Взрывной автогидролиз Нечеткая логика Бытовые установки (укр) Автоматизация проектирования Сбор и защита Дискретная математика Kb радиостанция Энергетика Ретро: Прием в автомобиле Управление шаговым двигателем Магнитная запись Ремонт микроволновки Дискретные системы часть 2 | ||