Easyelectronics.ru

Электроника для всех
Текущее время: 25 май 2018, 17:38

Часовой пояс: UTC + 5 часов



    • JLCPCB - Платы прототипов всего за 2$ c бесплатной доставкой (при первом заказе)
    • 10 PCBs за $2 для 2 слоев, $15 для 4 слойной, $74 для 6 слойной платы.
    • Крупнейший китайский производитель прототипных плат. 290000+ клиентов & 8000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин радиодеталей.

Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
 Заголовок сообщения: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 15 янв 2018, 00:13 
Только пришел
Аватара пользователя

Зарегистрирован: 07 окт 2017, 20:58
Сообщения: 23
Откуда: Поволжье
Приветствую форумчан!
Тут такая тема.... Сижу, копаюсь в Atmel Studio 6.2 (целевой камень - atmega168), и понадобилось мне разместить массив из 256 байт в оперативной памяти таким образом, чтоб старший байт его адреса не изменялся. В IAR такие вещи делаются при помощи собаки (@), а тут что-то не получается у меня малой кровью добиться нужного эффекта :(

Мысль 0 - Создаёшь указатель и присваиваешь. Казалось бы...
Код:
char *array = (char*)0x0400;
Только таким образом нельзя выделить массив фиксированного размера. Можно только "копать отсюда и до обеда" с отсутствием гарантии, что по пути не попадутся другие переменные.

Мысль 1 - Слыхал про такую вещь, как секции (named sections), и даже удачно применил раньше на флеше. Пока расклад такой - в настройках проекта пошёл в Toolchain > AVR/GNU Linker > Memory Settings и там для SRAM добавил строку
Код:
.mysram=0x000400
что сгенерировало параметр
Код:
-Wl,-section-start=.mysram=0x800400
в исходнике соответственно
Код:
__attribute__((used, section(".mysram"))) unsigned char array[256];
Ну и чтобы стэк не грохнулся, начальный указатель прописал 0x03FF всё в том же Memory Settings. Переменная выделилась в оперативке где нужно, но секция просочилась в (!!) hex-файл :O
Цитата:
avrdude: ERROR: address 0x800410 out of range at line 309
После ручного удаления лишних строк дудка согласился залить прошивку, и в итоге устройство даже что-то там делает по этой прошивке. Однако, неудобный вариант.

Вопросы таковы: Какие другие способы жесткого задания адреса в avr-gcc вы можете посоветовать? Или хотя бы как настроить AS6, чтобы секции SRAM волшебным образом не оказывались в файле прошивки?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 16 янв 2018, 10:21 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 ноя 2010, 20:11
Сообщения: 54
Откуда: Омск
Добавьте аттрибут выравнивания по 256 байт:
Код:
char array[256] __attribute__ ((aligned (256)));

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

PS: Знаю, в какой-то мере костыль.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 16 янв 2018, 13:22 
Заглядывает иногда

Зарегистрирован: 10 фев 2016, 19:55
Сообщения: 183
Не совсем понимаю зачем располагать массив по определённому адресу в оперативной (!) памяти микроконтроллера?
Ведь кроме АЛУ микроконтроллера к этой памяти ни кто больше доступа не имеет.
Есть подозрение, что исходная задача решается каким-то странным способом (через одно место...).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 16 янв 2018, 20:45 
Только пришел
Аватара пользователя

Зарегистрирован: 07 окт 2017, 20:58
Сообщения: 23
Откуда: Поволжье
-Alan-, спасибо за отклик. С атрибутом aligned(256) в map-файле картина интересная нарисовалась
Show визуалим
ну не может же быть на 168-й адреса 0x0500. Странное размещение, особенно при том, что я в итоге переменными и массивом едва ли занял 30% памяти.
Show фрагмент map варианта с выравниванием

Show фрагмент map варианта с секцией


Netzschlange, тема конечно не об этом, но ладно.
Через одно место? Весьма вероятно. Неправильно? Ну не знаю...
В первом посте написал:
Цитата:
таким образом, чтоб старший байт его адреса не изменялся.
То есть пробую оптимизировать часто вызываемую ISR на ассемблере. Пока моя мысль дошла до избавления от лишних операций при вычислении адреса элемента и от резервирования лишних регистров такой ценой. Пока как-то так.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 16 янв 2018, 23:42 
Заглядывает иногда

Зарегистрирован: 10 фев 2016, 19:55
Сообщения: 183
dezz0r писал(а):
В первом посте написал:
Цитата:
таким образом, чтоб старший байт его адреса не изменялся.
То есть пробую оптимизировать часто вызываемую ISR на ассемблере. Пока моя мысль дошла до избавления от лишних операций при вычислении адреса элемента и от резервирования лишних регистров такой ценой. Пока как-то так.

Т.е., если правильно понимаю, главное разместить массив где-нибудь в памяти, но на постоянной основе, что бы адрес первого элемента массива не менялся? Так?
Если так, то это делается немного по другому -- объявляется глобальная переменная и она уже используется в коде (без необходимости размещать массив по определённому адресу). Компилятор сам вычислит правильный адрес массива.
Если проблема в том, как передать адрес в код на ассемблере, то тут надо смотреть, что за компилятор и уже плясать от этого.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 18 янв 2018, 22:29 
Только пришел
Аватара пользователя

Зарегистрирован: 07 окт 2017, 20:58
Сообщения: 23
Откуда: Поволжье
Netzschlange, не где-нибудь, а на 256-байтной границе. То, что глобальная, это понятно.
Адрес элемента массива = адрес первого элемента + индекс.
Если массив из 256 байт положить на такую границу, то достаточно будет в старший регистр адреса положить старший байт адреса массива, а в младший регистр - значение индекса. И получившаяся пара - это уже нужный результат, не надо тратить ещё 2 такта на сложение двух 16-битных чисел.

По теме: если я правильно понимаю, чистка hex от ненужных секций - работа для objcopy. Пока не знаю, как это обьяснить Atmel Studio....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 19 янв 2018, 16:37 
Заглядывает иногда

Зарегистрирован: 10 фев 2016, 19:55
Сообщения: 183
Прошу прощения не сразу вник в суть вопроса.
dezz0r писал(а):
Пока не знаю, как это обьяснить Atmel Studio....

Ни как не объясните.
Один из вариантов решения -- исправить генерируемый Makefile и проект настроить на использования этого Makefile'а. Т.е. делаете сборку проекта. В подпапке Release (имя папки зависит от вида сборки) появляется Makefile. Его копируете в корень проекта (хотя наверно можно и не копировать, а оставить его на месте) и ищете вызов 'avr-objcopy', который генерирует HEX-файл. В команду добавляете опцию -R .mysram (или как там секция называется). Например:
Код:
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .mysram -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "MEGA_LED_EXAMPLE1.elf" "MEGA_LED_EXAMPLE1.hex"


PS: Небольшой хак-костыль -- на усмотрение (проблему добавления массива в HEX-файл не решает):
Если не ошибаюсь секция .data размещается с адреса 0x800100 (т.е. то, что нужно). Можно разместить переменную как раз по этому адресу. Для этого можно взять используемый скрипт линкера (в моём случае скрипты располагались в каталоге: C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\lib\ldscripts, желательно сделать копию скрипта в проекте) и немного его подправить, что в принципе не является сложной задачей. Пример описания секции .data в скрипте линкера:
Код:
.data          :
  {
     PROVIDE (__data_start = .) ;
    *(.mysram)     /* новая секция .mysram, добавленная по аналогии с остальными секциями*/
      *(.mysram*)
    *(.data)
     *(.data*)
    *(.rodata)  /* We need to include .rodata here if gcc is used */
     *(.rodata*) /* with -fdata-sections.  */
    *(.gnu.linkonce.d*)
    . = ALIGN(2);
     _edata = . ;
     PROVIDE (__data_end = .) ;
  }  > data AT> text

Скрипт указывается в качестве параметра линкера: '-Wl,--script=...путь к скрипту....'.
Переменную, отмеченную атрибутом 'section(".mysram")', линкер закинет в начало секции .data, а все остальные переменные после неё. За стек можно будет не переживать...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 19 янв 2018, 18:01 
Заглядывает иногда

Зарегистрирован: 10 фев 2016, 19:55
Сообщения: 183
dezz0r писал(а):
Если массив из 256 байт положить на такую границу, то достаточно будет в старший регистр адреса положить старший байт адреса массива, а в младший регистр - значение индекса. И получившаяся пара - это уже нужный результат, не надо тратить ещё 2 такта на сложение двух 16-битных чисел.

Правильно понимаю, что работу с массивом будете реализовывать с помощью ассемблерных вставок?
Потому как оптимизатор Си-шного кода Вашу хитрость вряд ли распознает и создаст код, который будет "тратить ещё 2 такта на сложение двух 16-битных чисел".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AS6/gcc - задание адреса переменной или массива в SRAM
СообщениеДобавлено: 20 янв 2018, 00:29 
Только пришел
Аватара пользователя

Зарегистрирован: 07 окт 2017, 20:58
Сообщения: 23
Откуда: Поволжье
Ого... Netzschlange, спасибо за подробный исчерпывающий ответ :D Теперь всё получилось как надо.
Для студии 6.2 скрипты линкера лежали в \Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\avr\lib\ldscripts

Netzschlange писал(а):
Правильно понимаю, что работу с массивом будете реализовывать с помощью ассемблерных вставок?
Да, так и есть. По этой части пока всё получается.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB