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

Глюки программирования mega128

во 2 случае данные из флеша копируются в переменную размещенную в ОЗУ.

А в 1, размещаются в стеке

Зависит от компилятора, но сейчас они не размещают строки в стеке.

При соответствующих установках компилятор сгенерирует полностью идентичный код для обоих случаев, скормив функции в 1 первом случае адрес ER.

 

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


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

При соответствующих установках компилятор сгенерирует полностью идентичный код для обоих случаев, скормив функции в 1 первом случае адрес ER.

 

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

 

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


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

Похоже WinAVR в 1-ом случае и загоняет в стек - отсюда и глюки.

 

Ещё два вопроса возникло:

WinAVR-20100110

Как стал объем

Program: 50.0% Full,

То *.hex - файл не шьется

делаешь 49.9 - все норм

WinAVR- вроде как свободна для распространения?

 

А стал отлаживать обмен данными по порту по прерыванию и непонятка:

командный кадр приходит (вижу при передачи в комп), но

на LCD видно не первый, а второй кадр

(просто цикл for(); и в нем вывод)

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


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

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

Да, виноват недосмотрел. Привык в последнее время, что все входящие буфера для вывода объявлены как 'const char*'.

 

 

 

 

Как стал объем

Program: 50.0% Full,

То *.hex - файл не шьется

делаешь 49.9 - все норм

WinAVR- вроде как свободна для распространения?

 

Наверное это связано с моделью памяти.

128-я регистрами может адресовать только 50% памяти - поэтому, пространство программ делится на две половины, выбор доступа к каждой из который осуществляется с помощью соответствующего бита в управляющем регистре.

Для маленьких моделей компилятор строит программу при условии что она будет располагаться в нижних 50% памяти.

 

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


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

И как обойти это или в WinAVR не возможно?

 

В конце концов не может же 50% висеть в воздухе!

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


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

И как обойти это или в WinAVR не возможно?

 

В конце концов не может же 50% висеть в воздухе!

 

бит RAMPZ0 регистра RAMPZ отвечает за выбор банка при адресации команд ELPM/SPM.

Я не знаю как в WinAVR, но в общем это обходится выбором модели памяти (huge) при компиляции.

Тогда компилятор начинает использовать ELPM вместо LMP и отслеживает манипуляции с RAMPZ0.

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

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


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

Из Даташит:

Внутрисистемно программируемая флэш-память программ 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к

или все приехали: на данном микроконтроллере дальше не уедешь?

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

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


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

Получается программно нужно как-то расширять возможности записи программ больше 64к

или все приехали: на данном микроконтроллере дальше не уедешь?

Для переменных есть модификаторы типа памяти, наподобие __farflash, __hugeflash и т.д.

При использовании библиотек - соответствующую модель памяти.

 

 

 

 

 

 

 

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


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

Пример использования

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

 

 

 

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


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

Проблема в чём-то другом.

У вас ведь программа не состоит только из данных во флеше, а есть ещё и код программ.

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/

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


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

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

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

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

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

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

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

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

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

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