yung 0 13 января, 2012 Опубликовано 13 января, 2012 · Жалоба Здравствуйте! Работаю с Atmega128 и компилятором ICC6.31. Возникла необходимость, чтобы ряд глобальных переменных находился по фиксированным адресам. Сделал это путем, предложенным встроенным application builder-ом void mapping_init(void) { asm( ".area memory(abs)\n" ".org 0x0a00\n" " _temp1:: .blkb 4\n" ".text\n" ); } В АВР-студио эта процедура не видится (стоит ret) вместо тела. А компилятор не видит, что эта область занята и пытается по тем же адресам расположить другие переменные. Можно ли как-то объяснить ему, что место уже занято? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LexaK 0 13 января, 2012 Опубликовано 13 января, 2012 · Жалоба А как в ИАРе не получится? __no_init volatile char a @ 0x8000; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yung 0 14 января, 2012 Опубликовано 14 января, 2012 · Жалоба А как в ИАРе не получится? __no_init volatile char a @ 0x8000; Не получилось. Пока обошел, разместив переменные в начале ОЗУ. Но вопрос остается открытым. Кстати, заметил интересную особенность. Адреса переменных фактически прижаты к верхней границе ОЗУ (не считая стека). А переменные, инициализируемые одновременно с объявлением (char a=8;) - в начале. Пришлось инициализировать их отдельно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 7 14 января, 2012 Опубликовано 14 января, 2012 · Жалоба В АВР-студио эта процедура не видится (стоит ret) вместо тела.Ваша процедура не содержит ни одного исполняемого оператора. Что Вы ожидали увидить кроме RET? А компилятор не видит, что эта область занята и пытается по тем же адресам расположить другие переменные.Этот механизм не для того, чтобы "двигать" переменные по ОЗУ туда-сюда, как Вы этого желаете, а для доступа к регистрам устройств, спроецированных на память... Можно ли как-то объяснить ему, что место уже занято?Нет. Но, можно сделать другой финт: сказать транслятору, что размер памяти меньше, чем есть на самом деле, а остаток использовать для распределения переменных по фиксированным адресам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yung 0 14 января, 2012 Опубликовано 14 января, 2012 · Жалоба Но, можно сделать другой финт: сказать транслятору, что размер памяти меньше, чем есть на самом деле, а остаток использовать для распределения переменных по фиксированным адресам. А можно поподробнее? И не будет ли проблем в том, что у меня еще 128кБ внешней памяти стоит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 7 14 января, 2012 Опубликовано 14 января, 2012 · Жалоба А можно поподробнее? 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Вероятно речь идет о внешней памяти, подключенной минуя шины адреса\данных МК? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Artem_Petrik 0 14 января, 2012 Опубликовано 14 января, 2012 · Жалоба Здравствуйте! Работаю с 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". Там еще про то же на ассемблере. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 7 15 января, 2012 Опубликовано 15 января, 2012 · Жалоба Насколько я понимаю, это именно то, что вам требуется. Это - решение для ICC v7. У TC - шестая версия: в ней аналог приведенного Вами - ассемблерная вставка, приведенная ТС в первом посте. Но у ТС теперь другая проблема: в ICC хоть и можно разместить переменную по любому адресу, но делается это через секцию "abs", котрая перекрывается любой другой секцией данных. Поэтому, не исключено, что транслятор разместит по этому адресу некие другие данные... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Artem_Petrik 0 15 января, 2012 Опубликовано 15 января, 2012 · Жалоба Это - решение для ICC v7. У TC - шестая версия: в ней аналог приведенного Вами - ассемблерная вставка, приведенная ТС в первом посте. Но у ТС теперь другая проблема: в ICC хоть и можно разместить переменную по любому адресу, но делается это через секцию "abs", котрая перекрывается любой другой секцией данных. Поэтому, не исключено, что транслятор разместит по этому адресу некие другие данные... Да, действительно, не обратил внимания на версию. Хелп на сайте уже на 8. Тогда действительно видимо придется договариваться с линкером. ТС: я бы все же рекомендовал задуматься над сменой компилятора на нормальный. GCС и лучше и бесплатней, а если совести нет - то IAR имхо лучше всех. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yung 0 16 января, 2012 Опубликовано 16 января, 2012 · Жалоба Спасибо всем откликнувшимся! Отдельное и огромное - Палычу! Зарезервировал нижние 128 байт - все работает. При обмене устройства с ПК (в т.ч. для отладки) ввел команды доступа к ОЗУ. Соответственно потребовалось зафиксировать адреса "интересных" переменных для чтения плюс наложить маску по адресам на запись. А внешнее ОЗУ действительно 128к. Дополнительный адресный бит заведен на отдельный пин в/в, а в старшей половине хранится несколько массивов, которые для обработки перегружаются в нижнюю часть ОЗУ. Что касается компилятора - привык я к нему :). Лет 10 уже использую. Особенно нравится аппликэшн билдер. Хотя периодически возникают проблемы. В текущем проекте столкнулся с ситуацией, когда компилятор не смог корректно осилить операцию байтового копирования *(adr1++)=*(adr2++) - писал нули. ICC7 есть, но использовал только когда работал с мега2561. Есть там какие-то нюансы по переносимости, разбираться не стал. IAR когда-то показался слишком заумным для начинающего. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 7 16 января, 2012 Опубликовано 16 января, 2012 · Жалоба Хотя периодически возникают проблемы. В текущем проекте столкнулся с ситуацией, когда компилятор не смог корректно осилить операцию байтового копирования *(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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yung 0 16 марта, 2012 Опубликовано 16 марта, 2012 · Жалоба Вот еще проблема с ICC6.31a. Все та же 128-я мега. После увеличения размера кода пошла ругань вида: 'text' area too large (>64K byte) и предложение перенести часть кода в другой файл. При чем здесь 64кБайт? Именно килобайт, а не килослов. Если закомментировать небольшую часть кода, то нормально компилится с результатом 55%. Версия "Professional". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 16 марта, 2012 Опубликовано 16 марта, 2012 (изменено) · Жалоба Эта бяка другого рода - у этой меги память 128 килобайт, а компилятор этого не понимает. Лечится какими-то настройками проекта. Какими именно - не знаю, не пользовался, но где-то читал об этом. Насчёт "килослов". Единица измерения всегда байт, а не слово. То, что АВРы шьют флэш словами, а не байтами - это "их проблемы", не влияющие на общепринятую терминологию. Современные x86 процы имеют ШД 32 бита (4 байта). Но мы же не начинаем из-за этого измерять объём каких-то данных в двойных словах? Изменено 16 марта, 2012 пользователем hd44780 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться