Jump to content

    
Sign in to follow this  
yung

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

Recommended Posts

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

 

void mapping_init(void)

{

asm(

".area memory(abs)\n"

".org 0x0a00\n"

" _temp1:: .blkb 4\n"

 

".text\n"

);

}

 

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

Share this post


Link to post
Share on other sites
А как в ИАРе не получится?

__no_init volatile char a @ 0x8000;

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

Share this post


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

 

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

 

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

 

Share this post


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

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

Share this post


Link to post
Share on other sites
А можно поподробнее?

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
Вероятно речь идет о внешней памяти, подключенной минуя шины адреса\данных МК?

Share this post


Link to post
Share on other sites
Здравствуйте! Работаю с 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". Там еще про то же на ассемблере.

Share this post


Link to post
Share on other sites
Насколько я понимаю, это именно то, что вам требуется.

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

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

Share this post


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

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

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

 

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

 

 

 

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites
Хотя периодически возникают проблемы. В текущем проекте столкнулся с ситуацией, когда компилятор не смог корректно осилить операцию байтового копирования *(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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

 

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

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

Edited by hd44780

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this