aiwa 0 15 августа, 2017 Опубликовано 15 августа, 2017 · Жалоба во 2 случае данные из флеша копируются в переменную размещенную в ОЗУ. А в 1, размещаются в стеке Зависит от компилятора, но сейчас они не размещают строки в стеке. При соответствующих установках компилятор сгенерирует полностью идентичный код для обоих случаев, скормив функции в 1 первом случае адрес ER. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 16 августа, 2017 Опубликовано 16 августа, 2017 · Жалоба При соответствующих установках компилятор сгенерирует полностью идентичный код для обоих случаев, скормив функции в 1 первом случае адрес ER. А как он это сделает, если функция получает неконстантный буфер, т.е. может его модицифировать. В этом случае копирование во временный буфер не может быть соптимизировано... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Who_are_you? 0 16 августа, 2017 Опубликовано 16 августа, 2017 · Жалоба Похоже WinAVR в 1-ом случае и загоняет в стек - отсюда и глюки. Ещё два вопроса возникло: WinAVR-20100110 Как стал объем Program: 50.0% Full, То *.hex - файл не шьется делаешь 49.9 - все норм WinAVR- вроде как свободна для распространения? А стал отлаживать обмен данными по порту по прерыванию и непонятка: командный кадр приходит (вижу при передачи в комп), но на LCD видно не первый, а второй кадр (просто цикл for(); и в нем вывод) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 16 августа, 2017 Опубликовано 16 августа, 2017 · Жалоба А как он это сделает, если функция получает неконстантный буфер, т.е. может его модицифировать. В этом случае копирование во временный буфер не может быть соптимизировано... Да, виноват недосмотрел. Привык в последнее время, что все входящие буфера для вывода объявлены как 'const char*'. Как стал объем Program: 50.0% Full, То *.hex - файл не шьется делаешь 49.9 - все норм WinAVR- вроде как свободна для распространения? Наверное это связано с моделью памяти. 128-я регистрами может адресовать только 50% памяти - поэтому, пространство программ делится на две половины, выбор доступа к каждой из который осуществляется с помощью соответствующего бита в управляющем регистре. Для маленьких моделей компилятор строит программу при условии что она будет располагаться в нижних 50% памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Who_are_you? 0 17 августа, 2017 Опубликовано 17 августа, 2017 · Жалоба И как обойти это или в WinAVR не возможно? В конце концов не может же 50% висеть в воздухе! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 17 августа, 2017 Опубликовано 17 августа, 2017 (изменено) · Жалоба И как обойти это или в WinAVR не возможно? В конце концов не может же 50% висеть в воздухе! бит RAMPZ0 регистра RAMPZ отвечает за выбор банка при адресации команд ELPM/SPM. Я не знаю как в WinAVR, но в общем это обходится выбором модели памяти (huge) при компиляции. Тогда компилятор начинает использовать ELPM вместо LMP и отслеживает манипуляции с RAMPZ0. Изменено 17 августа, 2017 пользователем aiwa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Who_are_you? 0 17 августа, 2017 Опубликовано 17 августа, 2017 (изменено) · Жалоба Из Даташит: Внутрисистемно программируемая флэш-память программ ATmega128 содержит 128 кбайт внутренней внутрисистемно перепрограммируемой флэш-памяти для хранения программы. Поскольку все AVR-инструкции являются 16 или 32-разр., то флэш-память организована как 64 кбайт х 16. Для программной защиты флэш-память программ разделена на два сектора: сектор программы начальной загрузки и сектор прикладной программы. Регистр RAMPZ обычно используется для указания той страницы ОЗУ размером 64 кбайт, к которой выполняется доступ через Z-указатель. Т.к. ATmega128 не поддерживает память на статическом ОЗУ размером свыше 64 кбайт, то данный регистр используется только для выбора страницы памяти программ, доступ к которой осуществляется с помощью инструкций ELPM/SPM. Различные установки бита RAMPZ0 имеют следующий результат: RAMPZ0 =0: Инструкции ELPM/SPM осуществляют доступ к памяти программ в диапазоне адресов $0000 - $7FFF (младшие 64 кбайт) RAMPZ0 =1: Инструкции ELPM/SPM выполняют доступ к памяти программ в диапазоне адресов $8000 - $FFFF (старшие 64 кбайт) Обратите внимание, что действие инструкции LPM не зависит от установки RAMPZ. Получается программно нужно как-то расширять возможности записи программ больше 64к или все приехали: на данном микроконтроллере дальше не уедешь? Изменено 17 августа, 2017 пользователем Who_are_you? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 17 августа, 2017 Опубликовано 17 августа, 2017 · Жалоба Получается программно нужно как-то расширять возможности записи программ больше 64к или все приехали: на данном микроконтроллере дальше не уедешь? Для переменных есть модификаторы типа памяти, наподобие __farflash, __hugeflash и т.д. При использовании библиотек - соответствующую модель памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 17 августа, 2017 Опубликовано 17 августа, 2017 · Жалоба Пример использования char ER [] = "Error_RS422: "; #pragma location = 0x000100 __flash char ER_FLASH [] = "Error_RS422: "; #pragma location = 0x010100 __hugeflash char ER_HUGE [] = "Error_RS422: "; void main(void) { for(int i=0;i<10;i++) ER[i]=ER_HUGE[i]; for(int i=0;i<10;i++) ER[i]=ER_FLASH[i]; } И работа компилятора //копируем из верхней половины, здесь трехбайтный адрес в старшем байте которого принимается во внимание только младший бит, который имеет посадочное место RAMPZ0. // 16 ER[i]=ER_HUGE[i]; MOV R26, R25 LSL R26 SBC R26, R26 MOV R27, R26 LDI R30, LOW(ER_HUGE) LDI R31, HIGH(ER_HUGE) LDI R19, (ER_HUGE) >> 16 ADD R30, R24 ADC R31, R25 ADC R19, R26 OUT 0x3B, R19 !!!!!!!!! заносим в RAMPZ третий байт адреса для нижних адресов это 0x00, для верхних адресов - 0x01 ELPM R16, Z !!!!!!!!! доступ к памяти программ через "длинный" вариант - ELP, т.е. через [RAMPZ0]:Z MOVW R31:R30, R25:R24 SUBI R30, LOW((-(ER) & 0xFFFF)) SBCI R31, (-(ER) & 0xFFFF) >> 8 ST Z, R16 копируем из нижней половины. здесь двухбайтный адрес. // 16 ER[i]=ER_HUGE[i]; MOV R26, R25 LSL R26 SBC R26, R26 MOV R27, R26 LDI R30, LOW(ER_HUGE) LDI R31, HIGH(ER_HUGE) LDI R19, (ER_HUGE) >> 16 ADD R30, R24 ADC R31, R25 ADC R19, R26 OUT 0x3B, R19 ELPM R16, Z !!!!!!!!! доступ к памяти программ через "короткий" вариант - LPМ, т.е. через Z MOVW R31:R30, R25:R24 SUBI R30, LOW((-(ER) & 0xFFFF)) SBCI R31, (-(ER) & 0xFFFF) >> 8 ST Z, R16 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 18 августа, 2017 Опубликовано 18 августа, 2017 · Жалоба Проблема в чём-то другом. У вас ведь программа не состоит только из данных во флеше, а есть ещё и код программ. avr-gcc (см скрипт линкера и map-файл) обычно размещает секцию с данными перед секцией кода. Поэтому проблемы с заполнением памяти на 49% и 51% не следуют из вышеназванных предположений. А на будущее рекомендую изучить файлик pgmspace.h a = pgm_read_byte_far(GET_FAR_ADDRESS(v)); Также есть смысл использовать более свежий тулчейн хотя бы avr-gcc-4.9.2 т.к. там появилась поддержка ключевого слова __flash (на подобии IAR). https://sourceforge.net/projects/mobileches...%20%28Win32%29/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться