Перейти к содержанию
    

резервирование места в ОЗУ

Здравствуйте! Работаю с Atmega128 и компилятором ICC6.31. Возникла необходимость, чтобы ряд глобальных переменных находился по фиксированным адресам. Сделал это путем, предложенным встроенным application builder-ом

 

void mapping_init(void)

{

asm(

".area memory(abs)\n"

".org 0x0a00\n"

" _temp1:: .blkb 4\n"

 

".text\n"

);

}

 

В АВР-студио эта процедура не видится (стоит ret) вместо тела. А компилятор не видит, что эта область занята и пытается по тем же адресам расположить другие переменные. Можно ли как-то объяснить ему, что место уже занято?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как в ИАРе не получится?

__no_init volatile char a @ 0x8000;

Не получилось. Пока обошел, разместив переменные в начале ОЗУ. Но вопрос остается открытым. Кстати, заметил интересную особенность. Адреса переменных фактически прижаты к верхней границе ОЗУ (не считая стека). А переменные, инициализируемые одновременно с объявлением (char a=8;) - в начале. Пришлось инициализировать их отдельно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В АВР-студио эта процедура не видится (стоит ret) вместо тела.
Ваша процедура не содержит ни одного исполняемого оператора. Что Вы ожидали увидить кроме RET?

 

А компилятор не видит, что эта область занята и пытается по тем же адресам расположить другие переменные.
Этот механизм не для того, чтобы "двигать" переменные по ОЗУ туда-сюда, как Вы этого желаете, а для доступа к регистрам устройств, спроецированных на память...

 

Можно ли как-то объяснить ему, что место уже занято?
Нет. Но, можно сделать другой финт: сказать транслятору, что размер памяти меньше, чем есть на самом деле, а остаток использовать для распределения переменных по фиксированным адресам.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но, можно сделать другой финт: сказать транслятору, что размер памяти меньше, чем есть на самом деле, а остаток использовать для распределения переменных по фиксированным адресам.

А можно поподробнее? И не будет ли проблем в том, что у меня еще 128кБ внешней памяти стоит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А можно поподробнее?

1. Menu -> Project -> Options -> Target

2. Device Coinfiguration = Custom

3. Internal SRAM. Если есть внешнее ОЗУ, то задаём ключем -bdata:XXXX.YYYY в Other Options

 

Если желаем освободить область в:

1) нижних адресах Internal RAM - увеличиваем Data Address

2) верхних адресах Internal RAM - уменьшаем Data Memory

3) нижних адресах External RAM - увеличиваем значение XXXX в ключе -bdata:XXXX.YYYY

4) верхних адресах External RAM - уменьшаем значение YYYY в ключе -bdata:XXXX.YYYY

 

И не будет ли проблем в том, что у меня еще 128кБ внешней памяти стоит?
Если посмотреть в DS:
Up to 64Kbytes Optional External Memory Space
Вероятно речь идет о внешней памяти, подключенной минуя шины адреса\данных МК?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте! Работаю с Atmega128 и компилятором ICC6.31. Возникла необходимость, чтобы ряд глобальных переменных находился по фиксированным адресам.

Читая последние ответы можно подумать что нормального способа сделать это нет. Но, к счастью, это не так. Отсутствие возможности разместить перемееную по конкретному адресу звучит для меня настолько дико, что я просто не могу в это поверить.

 

Никогда не пользовался ICC-шным компилятором, но все же не поленился залезь в хелп у них на сайте, где нашел такое:

#pragma abs_address 

In a C file, put the following: 

    #pragma abs_address:0x1000 
    unsigned LCD_control_register; 
    #pragma end_abs_address 

    #pragma abs_address:0x2000 
    unsigned char dual_port_SRAM[100]; 
    #pragma end_abs_address

These variables may be declared as extern per the usual C rules in other files. Note that you cannot initialize them in the declarations.

Насколько я понимаю, это именно то, что вам требуется.

 

P.S. Раздел хелпа "Addressing Absolute Memory Locations". Там еще про то же на ассемблере.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понимаю, это именно то, что вам требуется.

Это - решение для ICC v7. У TC - шестая версия: в ней аналог приведенного Вами - ассемблерная вставка, приведенная ТС в первом посте.

Но у ТС теперь другая проблема: в ICC хоть и можно разместить переменную по любому адресу, но делается это через секцию "abs", котрая перекрывается любой другой секцией данных. Поэтому, не исключено, что транслятор разместит по этому адресу некие другие данные...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это - решение для ICC v7. У TC - шестая версия: в ней аналог приведенного Вами - ассемблерная вставка, приведенная ТС в первом посте.

Но у ТС теперь другая проблема: в ICC хоть и можно разместить переменную по любому адресу, но делается это через секцию "abs", котрая перекрывается любой другой секцией данных. Поэтому, не исключено, что транслятор разместит по этому адресу некие другие данные...

Да, действительно, не обратил внимания на версию. Хелп на сайте уже на 8. Тогда действительно видимо придется договариваться с линкером.

 

ТС: я бы все же рекомендовал задуматься над сменой компилятора на нормальный. GCС и лучше и бесплатней, а если совести нет - то IAR имхо лучше всех.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем откликнувшимся! Отдельное и огромное - Палычу!

Зарезервировал нижние 128 байт - все работает. При обмене устройства с ПК (в т.ч. для отладки) ввел команды доступа к ОЗУ. Соответственно потребовалось зафиксировать адреса "интересных" переменных для чтения плюс наложить маску по адресам на запись.

А внешнее ОЗУ действительно 128к. Дополнительный адресный бит заведен на отдельный пин в/в, а в старшей половине хранится несколько массивов, которые для обработки перегружаются в нижнюю часть ОЗУ.

Что касается компилятора - привык я к нему :). Лет 10 уже использую. Особенно нравится аппликэшн билдер. Хотя периодически возникают проблемы. В текущем проекте столкнулся с ситуацией, когда компилятор не смог корректно осилить операцию байтового копирования *(adr1++)=*(adr2++) - писал нули. ICC7 есть, но использовал только когда работал с мега2561. Есть там какие-то нюансы по переносимости, разбираться не стал. IAR когда-то показался слишком заумным для начинающего.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хотя периодически возникают проблемы. В текущем проекте столкнулся с ситуацией, когда компилятор не смог корректно осилить операцию байтового копирования *(adr1++)=*(adr2++) - писал нули.

Из известных ошибок в ICC версии 6 мне известны две:

1. Неверно вычисляются длинные выражения. Например, такое преобразование из символов в число

X= ((((Buffer[2] - '0') * 10 + (Buffer[3] - '0') ) * 10) + (Buffer[4] - '0') ) * 10) + Buffer[5] - '0';

Так и не смог разобраться, что за код компилятор "наворотил" - кажется, что-то неверно с длиной переменных в начале вычисления выражения... Эта ошибка присутствует как в версии 6, так и в версии 7.

2. Разрушение регистров R0, R1 в прерывании, при обращении к массиву

Если в прерывании есть обращение к элементу массива и нет обращений к функциям, то при входе в процедуру прерывания сохраняются не все регистры, а только те, которые компилятор использует для выполнения кода процедуры прерывания. Для доступа к элементу массива используются R0 и R1, вот, только, компилятор "забывает" их сохранить, а при выходе из прерывания - восстановить. В версии 7 эта ошибка устранена.

 

ICC7 есть, но использовал только когда работал с мега2561. Есть там какие-то нюансы по переносимости, разбираться не стал.
Нюансов по переносимости как-то не заметил, но, результирующий размер кода куда бОльший (процентов на 10-15), чем даёт версия 6.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот еще проблема с ICC6.31a. Все та же 128-я мега. После увеличения размера кода пошла ругань вида: 'text' area too large (>64K byte) и предложение перенести часть кода в другой файл. При чем здесь 64кБайт? Именно килобайт, а не килослов. Если закомментировать небольшую часть кода, то нормально компилится с результатом 55%. Версия "Professional".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эта бяка другого рода - у этой меги память 128 килобайт, а компилятор этого не понимает.

Лечится какими-то настройками проекта. Какими именно - не знаю, не пользовался, но где-то читал об этом.

 

Насчёт "килослов". Единица измерения всегда байт, а не слово. То, что АВРы шьют флэш словами, а не байтами - это "их проблемы", не влияющие на общепринятую терминологию.

Современные x86 процы имеют ШД 32 бита (4 байта). Но мы же не начинаем из-за этого измерять объём каких-то данных в двойных словах?

Изменено пользователем hd44780

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...