Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по WINAVR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Karl
Как расположить массив по определенному адресу в памяти программ? Что нужно сказать компилятору?
BorisRozentsvaig
Цитата(Karl @ Apr 29 2005, 13:06)
Как расположить массив по определенному адресу в памяти программ? Что нужно сказать компилятору?
*


Думается, что стандартными средствами, никак. Все что можно делать с переменными в памяти программ см. pgmspace.h и http://users.rcn.com/rneswold/avr/c957.html#PROGMEM
SL@V@
Если в IAR-е то:

__no_init char mas[10] @0x200;

(массив mas[10] в озу по ардесу 0x200)
Karl
Цитата(BorisRozentsvaig @ Apr 29 2005, 16:06)
Цитата(Karl @ Apr 29 2005, 13:06)
Как расположить массив по определенному адресу в памяти программ? Что нужно сказать компилятору?
*


Думается, что стандартными средствами, никак. Все что можно делать с переменными в памяти программ см. pgmspace.h и http://users.rcn.com/rneswold/avr/c957.html#PROGMEM
*



Это не совсем то, что мне надо. Хм. А как же тогда программу - загрузчик в загрузочный сектор поместить?
pulsar-17
Цитата(Karl @ May 3 2005, 13:24)
А как же тогда программу - загрузчик в загрузочный сектор поместить?
*


Очень просто:

сам загрузчик:
BOOTLOADER_SECTION void func()
{

}

BOOTLOADER_SECTION определен:
#define BOOTLOADER_SECTION __attribute__ ((section (".bootloader")))

в makefile надо пропиcать в параметрах линькера адрес секции:
-Wl,--section-start=.bootloader=0x1FE00

адрес может быть и другой в зависимости от фьюзов(смотри доку на контроллер)
pulsar-17
большие массивы данных я конвертировал:

avr-objcopy -I binary --change-addresses 0x1234 -O ihex infile outfile
infile - входной бинарный файл
outfile - выходной файл в формате ihex
вместо 0x1234 указать необходимый адрес

а затем загружал во флэш
Karl
Цитата(pulsar-17 @ May 3 2005, 21:20)
Цитата(Karl @ May 3 2005, 13:24)
А как же тогда программу - загрузчик в загрузочный сектор поместить?
*


Очень просто:

сам загрузчик:
BOOTLOADER_SECTION void func()
{

}

BOOTLOADER_SECTION определен:
#define BOOTLOADER_SECTION __attribute__ ((section (".bootloader")))

в makefile надо пропиcать в параметрах линькера адрес секции:
-Wl,--section-start=.bootloader=0x1FE00

адрес может быть и другой в зависимости от фьюзов(смотри доку на контроллер)
*



Попробовал - по вызову функции func() происходит переход на нужное место (по указанному адресу). Только вот самой функции там нет sad.gif . Там вообще пусто.
Karl
Реально функция func() располагается в памяти программ там же, гд и была бы без BOOTLOADER_SECTION. Меняется только адрес, на который осуществляется переход после обращения к функции sad.gif
pulsar-17
Как я понял переход происходит по адресу указанному в ключе:
-Wl,--section-start=.bootloader=0x1FE00

Какой версией WinAVR Вы пользуетесь?

Если Вы можете пришлите Ваш makefile мне будет значительно легче вам помочь.
Karl
Вы поняли правильно. Переход происходит именно по указанному адресу.
Пользуюсь версией WinAVR-20040720. Позавчера скачал WinAVR-20050214 - результат тот же.
pulsar-17
Я проверил на версии 20050214.

За исключением лишнего пробела в Makefile в строке 32 криминала нет.

Секция bootloader располагается по заданному адресу, код функции лежит именно там. Проверял по дизассемблеру и для полной достоверности по HEX-файлу.

Тест прилагаю.
В файле boot.c находится пример использования самопрограммирования из моих проектов.
Надеюсь Вам это поможет.
Karl
Огромная благодарность за помощь. Действительно, hex - файл собирается верно. Я попался на том, что проверял программу в симуляторе AvrStudio. А cof - файл собирается, похоже, не правильно smile.gif
Но если не сгенерить правильно cof - файл, то не получится отлаживать с JTAG? Нехорошо sad.gif
Karl
Так никто не занет, как сделать, чтобы cof - файл создавался правильным???
BorisRozentsvaig
Цитата(Karl @ May 18 2005, 07:42)
Так никто не занет, как сделать, чтобы cof - файл создавался правильным???
*

В makefile добавь:

BIN = $(AVR)/bin/avr-objcopy
ELFCOF = $(BIN) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000

%.cof: %.elf
$(ELFCOF) -O coff-ext-avr $< $@
или
$(ELFCOF) -O coff-avr $< $@

Но, вообще-то, последняя AVR Studio прекрасно понимает формат elf.

Много информации по этому поводу можно найти на avrfreaks.net, например:
h_t_t_p://w_w_w.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=28815&highlight=elf+support
Karl
Попробовал elf - файл. В дизасемблере AVRStudio увидел следующее smile.gif :

@00000F80: boot_write_page
---- F:\Work\Tegran\V1\boot.c -----------------------------------------------------------
9: {
+00000F80: FFFF ??? Data or unknown opcode
No Source -----------------------------------------------------------------------------------
+00000F81: FFFF ??? Data or unknown opcode
+00000F82: FFFF ??? Data or unknown opcode
+00000F83: FFFF ??? Data or unknown opcode
+00000F84: FFFF ??? Data or unknown opcode
+00000F85: FFFF ??? Data or unknown opcode
BorisRozentsvaig
Цитата(Karl @ May 19 2005, 14:04)
Попробовал elf - файл. В дизасемблере AVRStudio увидел следующее smile.gif :

@00000F80: boot_write_page
---- F:\Work\Tegran\V1\boot.c -----------------------------------------------------------
9:        {
+00000F80:  FFFF        ???                      Data or unknown opcode
No Source -----------------------------------------------------------------------------------
+00000F81:  FFFF        ???                      Data or unknown opcode
+00000F82:  FFFF        ???                      Data or unknown opcode
+00000F83:  FFFF        ???                      Data or unknown opcode
+00000F84:  FFFF        ???                      Data or unknown opcode
+00000F85:  FFFF        ???                      Data or unknown opcode
*


А ты генеришь файл в ELF/DRAFT-2 формате? AVR-studio поддерживает только его. Проверь makefile:

DEBUG = dwarf-2

CPFLAGS = ..... -g$(DEBUG) ...

Если ты брал Makefile из примеров, то этого достаточно.
Если писал сам, то замени CPFLAGS на значение, которое ты используешь для передачи параметров при вызове avr-gcc.
BorisRozentsvaig
Цитата(Karl @ May 19 2005, 14:04)
Попробовал elf - файл. В дизасемблере AVRStudio увидел следующее smile.gif :
.....


Кстати, а какую версии WinAVR и AVR Studio ты используешь?
Karl
Я использую WinAVR-20050214, AVRStudio4.11 b406SP2. make файл генерил программой MFile. DEBUG = dwarf-2. Так и есть.
BorisRozentsvaig
Цитата(Karl @ May 20 2005, 07:44)
Я использую WinAVR-20050214, AVRStudio4.11 b406SP2. make файл генерил программой MFile. DEBUG = dwarf-2. Так и есть.
*


Погоди. Ты в майкфайле пишешь:
LDFLAGS += --section-start=.bootloader=0x1f00
А функция boot_write_page у тебя как раз в бутлоадере:
...
BOOTLOADER_SECTION
void boot_write_page(unsigned long fptr, unsigned short *sptr)
...

Значит, ее начальный адрес должен быть старше 0x1F00, а в твоем дампе адреса с 0x0F80 начинаются...... ?????
BorisRozentsvaig
Так и есть. Проверил на своем проекте.
Если генерить elf и открывать в AVR-студио, то адрес процедуры бутлоадера определяется некорректно. С coff файлом все нормально.
Karl
Цитата(BorisRozentsvaig @ May 20 2005, 21:15)
Так и есть. Проверил на своем проекте.
Если генерить elf и открывать в AVR-студио, то адрес процедуры бутлоадера определяется некорректно. С coff файлом все нормально.
*


AVR- студио показывает адреса в словах, а в make - файле адрес указывается в байтах. Я так понял. 0x1f00/2=0хf80. А мой проектик запускал? Так же вместо кода одни 0xFF?
BorisRozentsvaig
Цитата(Karl @ May 23 2005, 07:40)
AVR- студио показывает адреса в словах, а в make - файле адрес указывается в байтах. Я так понял. 0x1f00/2=0хf80. А мой проектик запускал? Так же вместо кода одни 0xFF?
*



С твоим проектом тоже самое. Действительно, AVR-студио в окне dubug показывает адреса в словах, а в зависимости от типа файла (elf или coff), создаваемых WinAvr, адреса в окне watch показываются в словах или в байтах.
Если не лениво, попробуй откомпилировать приложенный демо-проект с avrfreaks.net - может там нормально будет бутлоадер отлаживаться?
LViktor
Подскажите где можно найти компилятор avr-gcc 4.х для windows. И как можно прикрутить новую библиотеку avr-libc-1.2.5 к WinAVR-20050214. Только посылать на http://winavr.sourceforge.net/ нет необходимости.
AndryG
Вот решил переползти с CVAVR на WINAVR (проект текущий глючит ужасно в CVAVR - чем не повод :-) )

Поднял эту тему, дабы не плодить новую.

WinAVR 20060421

И поток вопросов :-)

Для пробы набросал кучку всякой фигни в функцию ...

Код
   #include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <inttypes.h>
#include <util/delay.h>

#include "rzlds.h"

static Tpoint EEMEM points[MAX_POINT+1];

ISR (INT0_vect)
{
  eeprom_write_byte(&points[0].h,01);
}

int main(void)
{
  unsigned char buf;

  DDRD = 0x02;
  while(1){
    buf++;
    _delay_ms(1000);
    PORTD ^= 0x02;
  }; //while


}

[/code]
1. Задержки.
ставлю _delay_ms() при оптимизации "0" - код вырастает почти на 500 байт - многовато ... при опт. "s" - вырастает немного ... но задежки нет в любом варианте sad.gif Видать оптимизатор отработал на славу.
Как задержки организовывать? (не говрите про таймеры и загрузку проца ... я в курсе - я с компилятором разобраться хочу)

2. Сборка проекта
В makefile ("cтандартный") с дистрибутива добавляю еще один файлик
Код
# List C source files here. (C dependencies are automatically generated.)
SRC = rzlds.c crc8.c

В основной программе его функции нигде не использую ... а в hex код добавляется sad.gif Оптимизация "s"

3. ELF -> СOFF
Просто лог ...
Код
Converting to AVR Extended COFF: rzlds.cof
avr-objcopy --debugging --change-section-address .data-0x800000 --change-section
-address .bss-0x800000 --change-section-address .noinit-0x800000 --change-sectio
n-address .eeprom-0x810000 -O coff-ext-avr rzlds.elf rzlds.cof
Warning: file C:/DOCUME~1/EWEDDI~1/LOCALS~1/Temp/ccsreaaa.s not found in symbol
table, ignoring
Warning: ignoring function __vectors() outside any compilation unit
Warning: ignoring function __bad_interrupt() outside any compilation unit

Не могу избавится от трех варнингов ... от первого я вообще в шоке - что он хочет (%TEMP% в пер. среды прописан короткий d:\temp)
А второй итретий - о чем это? И как это убрать?

Просьба :-) не гоните меня форум читать ... два дня все темы с упоминанием WinAVR читаю ... о _delay_ms() нашел упоминание, но без ответа sad.gif ... да и вообще ... хоть сколько-нить работающий кусок кода -- эт из форумских бесед :-)
ReAl
1. Задержки.
В более свежих версиях, кажется, уже добавили ругню через #warning про то, что при выключенной оптимизации будет совсем не то.
Перед включением delay.h должна быть определена константа F_CPU (тактовая в герцах), иначе - опять предупреждение и определение её на 1000000.
В документации на libc (какая там стандартная FIDO-шная такса на чтение доеументации вслух?) и в самом delay.h (поскольку дока doxygen-ом собирается) написано, что максимально допустимая задержка для _delay_ms равна приблизительно 262мс/тактовая_в_мегагерцах, все более длинные задержки будут отрабатываться как эта максимальная.

2. Сборка проекта
Пока могу только порекомендовать не включать в проект то, что не нужно. Кажется, --relax ещё окончательно не отлажен.

3. ELF -> СOFF
Не пользуюсь симуляцией. Кажется, новые авр-студии уже берут elf от новых avr-gcc

p.s. "Просьба :-) не гоните меня форум читать ... два дня все темы с упоминанием WinAVR читаю ... о _delay_ms() нашел упоминание"

Документацию надо читать. Документацию.
aesok
Цитата(ReAl @ Jun 21 2007, 19:43) *
2. Сборка проекта
Пока могу только порекомендовать не включать в проект то, что не нужно. Кажется, --relax ещё окончательно не отлажен.


--relax - не отвечает за удаление неиспользуемых функций, он отвечает за замену CALL/JMP на RCALL/RJMP.

Анатолий.
ReAl
Цитата(aesok @ Jun 21 2007, 22:12) *
--relax - не отвечает за удаление неиспользуемых функций, он отвечает за замену CALL/JMP на RCALL/RJMP.

Точно, это я как всегда спутал с прямым углом.
За удаление функций отвечает --gc-sections при условии, что функции распиханы по отдельным секциям при помощи -ffunction-sections
Всё равно оно ещё, кажется, недоделано. -ffunction-sections в компиляторе работает, а --gc-sections в линкере - нет.
AndryG
Подведем промежуточные итоги:
1. известные на этапе компиляции задержки делаем через _delay_loop[_2]() функции (можно удобный define сделать, дабы с тактовой сразу высчитывать)
Если задержки нужно вычислять в программе - таймер Вам в рки :-)
2. Нефиг, пока, лишние функции в свои файлы совать. Отсюда вопрос ... а как тогда используются "прилагаемые" хидеры ... там ведь куча функций описана, а линкуются только нужные? (тупой вопрос - надо идти читать документы ... видать с библиотек линкер нормально тянет только нужное)
3. ELF понимает и Студия и Протеус ... вот только в Протеусе (Студию не пробовал) половина строк кода стоит "не выполняемая" ... и на нулевой оптимизации тоже ... получается один шаг и половина программы выполнена sad.gif Вопрос открытый остается.

Еще вопросик. "Переменная" F_CPU определяется в makefile ... и она же нужна мне в моем исходнике. Если я определяю ее сам, то ругается, что идет переопределение, если вообще не определять, то кричит, что не знаю такого слова ? Как быть?

____
P.S.
Пользуясь случаем передаю свое огромное "спасибо, Real" за Ваш программатор. (надеюсь автором не ошибся :-) ) После того как я сжег c STK200/300 половину линий LPT-порта ... с Вашим программатором я неразлучен smile.gif
ReAl
Цитата(AndryG @ Jun 22 2007, 11:35) *
1. известные на этапе компиляции задержки делаем через _delay_loop[_2]() функции (можно удобный define сделать, дабы с тактовой сразу высчитывать)
Зачем самому делать?
_delay_us() и _delay_ms() из delay.h как раз представляют из себя комбинацию из "сразу высчитывать" и вызова _delay_loop1() и _delay_loop2() соответственно. Тактовую они берут по F_CPU. А при выключенной оптимизации проблемы именно потому, что "сразу высчитывание" без оптимизации не всё делается на этапе компиляции.

Цитата(AndryG @ Jun 22 2007, 11:35) *
2. ... видать с библиотек линкер нормально тянет только нужное
Именно так.

Цитата(AndryG @ Jun 22 2007, 11:35) *
Еще вопросик. "Переменная" F_CPU определяется в makefile ... и она же нужна мне в моем исходнике. Если я определяю ее сам, то ругается, что идет переопределение, если вообще не определять, то кричит, что не знаю такого слова
Не понял. У меня в makefile определяется, через -DF_CPU=$(F_CPU)UL передаётся gcc и через -o$(F_CPU)hz передаётся в avreal. При компиляции delay всё нормально.
Если F_CPU определять в исходниках, то это нужно делать не перед вызовом _delay_*, а перед включением delay.h.
Если сделать наоборот, то будет ругаться на переопределение, так как при отсутствии F_CPU во время разбора delay.h устанавливается F_CPU по умолчанию (я бы предпочёл вывал по #error "delay.h: F_CPU not defined").


p.s. автором не ошибся.
ReAl
Цитата(ReAl @ Jun 22 2007, 09:08) *
Всё равно оно ещё, кажется, недоделано. -ffunction-sections в компиляторе работает, а --gc-sections в линкере - нет.

Давно не проверял работу этих ключиков, оказывается (вот так оно мне нужно, значит smile.gif ).
По кр. мере в двух самых свежих сборках WinAVR --gc-sections работает, незадействованные функции успешно выбрасывает (соответственно при -fdata-sections будет должно вышвыривать глоблаьные и static-переменные, на которые нет ссылок).
Вероятно, заработало это где-то тогда, когда к обработчикам прерываний стали __attribute__((used)) цеплять.
AndryG
повозился вчера с makefile от компилятора ...
добавил в gcc -D__AVR_$(TARGET)__ -- теперь в коде можно вспоминать только хидер io.h , а "персональные" хидеры для контроллера теперь io.h вставит!

Люди, а не поделится ли кто описанием ключей запуска на winavr на русском языке?
mdmitry
Цитата(AndryG @ Jul 26 2007, 18:01) *
повозился вчера с makefile от компилятора ...
добавил в gcc -D__AVR_$(TARGET)__ -- теперь в коде можно вспоминать только хидер io.h , а "персональные" хидеры для контроллера теперь io.h вставит!

Люди, а не поделится ли кто описанием ключей запуска на winavr на русском языке?

По умолчанию TARGET задается в makefile и только там определяется.
Что понимается под ключами? Опции компилятора и линкера, так в makefile все определяется.
AndryG
У меня релиз апреля(вроде) 2006 года ... таргет определяется в makefile ... но если в исходник не ставить хидер конкретного чипа, то комилятор ругается, что не определен тип микроконтроллера ... после добавления вышеуказанного куска в makefile мы добавляем define, по котрому io.h вставит нужный хидер нужного контроллера.

Для многих это полная фигня, а для меня маленькая победа в освоении компилятора :-) вот и поделился радостью.

А ключи ... да я имел ввиду описание опций вызова компилятора и линкера. То что они определяются в makefile - это здорово, но все же они упоминаются в "базовом" makefile.
ReAl
Цитата(AndryG @ Jul 26 2007, 16:01) *
повозился вчера с makefile от компилятора ...
добавил в gcc -D__AVR_$(TARGET)__ -- теперь в коде можно вспоминать только хидер io.h , а "персональные" хидеры для контроллера теперь io.h вставит!

Люди, а не поделится ли кто описанием ключей запуска на winavr на русском языке?

Что-то я спросонок не пойму... Если есть ключ, например, -mmcu=atmega88 то gcc сам порождает и нужный __AVR_ATmega88__, и по мере необходимости всякие __AVR_ENHANCED__, __AVR_HAVE_LPMX__ и т.п. Причём я не помню времён, когда этого не было, т.е. когда мне не хватало комбинации -mmcu и io.h
AndryG
Хм! -mmcu вспоминается ... но почему ж тогда у меня ругается, что не определен контроллер ?

Будем колупать дальше ... спасибо.
Сергей Борщ
Цитата(ReAl @ Jul 5 2007, 21:04) *
По кр. мере в двух самых свежих сборках WinAVR --gc-sections работает, незадействованные функции успешно выбрасывает (соответственно при -fdata-sections будет должно вышвыривать глоблаьные и static-переменные, на которые нет ссылок).
Вероятно, заработало это где-то тогда, когда к обработчикам прерываний стали __attribute__((used)) цеплять.
Вчера и я попробовал. Действительно выбрасывает. Даже те функции, которые с __attribute__((used)) описал. даже без -ffunction-sections. Пробовал и 20060421 и 20070525. Что же делать? Есть у меня одна функция, которая из отдельно скомпилированного загрузчика вызывается. И вторая проблема: то же самое, но с данными. -fdata-sections выкидывает массив, который нужно зарезервировать для функции из области загрузчика, т.е. скомпилированной отдельным проектом. Несмотря на наличие __attribute__((used)). Как бороться? Заводить фиктивные указатели на эти функцию и массив не хочу - некрасиво это.
Еще один вопрос - как называется функция, с которой начинается выполнение (что в ENTRY() скрипта ld указывать)?
ReAl
Цитата(Сергей Борщ @ Oct 24 2007, 18:12) *
Вчера и я попробовал. Действительно выбрасывает. Даже те функции, которые с __attribute__((used)) описал. даже без -ffunction-sections. Пробовал и 20060421 и 20070525.
...
Заводить фиктивные указатели на эти функцию и массив не хочу - некрасиво это.
Мда. Мрак.
Бестолку фиктивный указатель... Сначала он выбрасывается "ввиду необращения", потом то, на что он указывал.
Кстати, я пробовал с 20070525 --gc-sections без -ffunction-sections ничего не выбрасывает.
А с -ffunction-sections - да, used не помогает. Почитал ещё - таки похоже used касается только компилятора и только на этапе компиляции файла. Линкеру никакой информации об этом аттрибуте не передаётся.
Пока нарыл только то, что невызываемая ниоткуда функция не выбрасывается, если передать линкеру ключик -u/--undefined
-Wl,-u,func_name
он применяется для принудительной линковки модуля из библиотеки по имени глобального символа, даже если на него нигде нет ссылки - эдакое ручное помещение символа в таблицу необходимых ссылок. Судя по описанию ключа - то же самое делается командой EXTERN в линкероном скрипте. После чего линкер считает это имя хоть кому-то да нужным и не выбрасывает по --gc-sections

Цитата(Сергей Борщ @ Oct 24 2007, 18:12) *
Еще один вопрос - как называется функция, с которой начинается выполнение (что в ENTRY() скрипта ld указывать)?
В запускалке стандартной там вообще не функция, а идёт переход на weak метку __init, она в секции .init0, потом вслед за ней линкерным скриптом складываются секции вплоть до .init9, которая состоит из jmp main. А из init-секции в init-секцию переход не jmp/call, а просто "естественным путём".
Т.е. если у себя завести функцию с именем __init, то по нулевому адресу будет поставлен jump (а не call) на неё и вся цепочка - инициализация указателя стека, обнуление __zero_reg__, инициализация .data, зачистка .bss, конструкторы С++ - пойдут лесом.
Сергей Борщ
Цитата(ReAl @ Oct 26 2007, 00:40) *
Пока нарыл только то, что невызываемая ниоткуда функция не выбрасывается, если передать линкеру ключик -u/--undefined
Спасибо, использую. Непередача used линкеру - это как, бага или фича? Может надо сообщить авторам, чтоб поправили?
Цитата(ReAl @ Oct 26 2007, 00:40) *
В запускалке стандартной там вообще не функция, а идёт переход на weak метку __init, она в секции .init0, потом вслед за ней линкерным скриптом складываются секции вплоть до .init9, которая состоит из jmp main. А из init-секции в init-секцию переход не jmp/call, а просто "естественным путём".
Т.е. ENTRY() не нужна? А по --gc-sections вся эта инициализация не выкинется однажды?
aesok
Цитата(Сергей Борщ @ Oct 26 2007, 12:30) *
А по --gc-sections вся эта инициализация не выкинется однажды?


Не выкиниться, все стандартные имена (vectors, initX, и.т.д.) в ld скрипте начиня с версии binutils 2.17 помпомечены атрибутом KEEP (...).

В версии 2.16 (WinAVR-2006..) еще не помечены, и по этой причине опции "-ffunction-sections" и "-fdata-sections" не работают.

Анатолий.
AndryG
Почитал я ваши посты ... и поник ... как просто было с CV ... а тут sad.gif
Сергей Борщ
Цитата(aesok @ Oct 26 2007, 11:56) *
Не выкиниться, все стандартные имена (vectors, initX, и.т.д.) в ld скрипте начиня с версии binutils 2.17 помпомечены атрибутом KEEP (...).
Вот оно! Я клал свою функцию и массив в отдельные секции принудительно. Сделал в скрипте этим секциям KEEP() и все получилось. Спасибо!!! Остался открытым вопрос - то, что компилятор не передает линкеру атрибут used - это бага или так и должно быть?

Цитата(AndryG @ Oct 26 2007, 13:17) *
Почитал я ваши посты ... и поник ... как просто было с CV ... а тут sad.gif
Сложности возникают при попытке сделать что-то нетривиальное - "чесать левое ухо правой ногой". Поверьте, я писал аналогичную программу в CV - знали бы вы сколько времени было потрачено, чтобы заставить его разместить ту самую функцию и тот самый массив по нужным мне адресам, и через какую ж.. это в конце-концов получилось реализовать. Так что зря пугаетесть - с WinAVR у вас могут быть трудности в начале, зато потом гладкий полет, с CV будете иметь с точностью до наоборот - сначала легкий старт, потом какое-то время полет, потом большие трудности (если, конечно, ваши программы будут развиваться).
После того, как подружили WinAVR и AVRStudio проблем с WinAVR нет даже в начале. В этой связке сложности начнутся, если захотите использовать С++. Плагин пока почему-то не позволяет подключать плюсовые файлы. Но есть альтернатива в виде Eclipse - как среда разработки гораздо удобнее студии, студию можно пользовать только как симулятор.
aesok
Цитата(Сергей Борщ @ Oct 26 2007, 16:03) *
Вот оно! Я клал свою функцию и массив в отдельные секции принудительно. Сделал в скрипте этим секциям KEEP() и все получилось. Спасибо!!! Остался открытым вопрос - то, что компилятор не передает линкеру атрибут used - это бага или так и должно быть?


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

Анатолий.
Сергей Борщ
Цитата(aesok @ Oct 26 2007, 15:20) *
Из описания атрибута used следует что код функции должен быть в объектном файле, но ничего не говориться о том должен ли линкер добавить секцию где находиться этот код в исполняемый файл.
Честно говоря я описание аттрибутов читаю здесь и там сказано просто:
Цитата
means that code must be emitted for the function even if it appears that the function is not referenced
И тут нет деления на объектный/исполняемый код. Компилятор-то все равно в объектник складывает все, и используемое и нет. А уже линкер собирает только нужное. Вот я и в непонимании нахожусь... Мне кажется, что именно линкер должен получать и использовать used. Иначе я не вижу смысла в used. Поправьте, если я не прав.
ReAl
Цитата(Сергей Борщ @ Oct 26 2007, 15:22) *
и там сказано просто:
means that code must be emitted for the function even if it appears that the function is not referenced
И тут нет деления на объектный/исполняемый код. Компилятор-то все равно в объектник складывает все, и используемое и нет. А уже линкер собирает только нужное. Вот я и в непонимании нахожусь...
Ну вот прочтя это я и решил, что такуи used относится только к компиляции файла - будет сгенерировано и окажется в объектнике. А дальше как линкер на душу положит. Хотя сначала мне казалось, что должно бы и до линкера дойти. Но нет - так нет, что тут скажешь, способ нашёлся, и то хорошо. Хотя какой-нибудь __attribute__((force_linking)) не помешал бы smile.gif

Цитата(Сергей Борщ @ Oct 26 2007, 15:22) *
Иначе я не вижу смысла в used. Поправьте, если я не прав.
Ну, как минимум один вариант использования я нашёл
Код
static void init(void) __attrinbte__((section(".init5"),naked,used));
static void init(void)
{
   ...
}

Это инициализация модуля, которая линкуется автоматически, если модуль (файл) подключен
- нет риска забыть в начале main() забыть вызвать какой-то из множества init
- размещением в "правильной" секции можно обеспечить выполнение этой инициализации, например, до выполнения каких-либо конструкторов, или до инициализации .data/очистки .bss (если в init открывается доступ к памяти на внешней шине).
Благодаря used помещается в объектный файл, иначе невызванная static-функиця удалится ещё компилятором. Т.е. used даёт возможность тут использовать static, благодаря чему спрятать эту точку входа от доступа снаружи.
firework
Цитата(AndryG @ Oct 26 2007, 12:17) *
Почитал я ваши посты ... и поник ... как просто было с CV ... а тут sad.gif

У меня очень навороченный прект на CV (ATmega2561 + на параллельной шине ST16C554). Все работает как часы. Единственный смысл перехода на WINAVR вижу только в том, что он бесплатный. Не нужно каждый раз при появлении новых версий искать лекарство. В остольном CV рулит. Работаю с ним 3,5 года.
yvk
Использую Winavr-20070525. При компиляции бутлоадера на выходе код, в котором сама программа расположена в области бутлоадера, но все инициализация лежит в младших адресах. Каким образом заставить линкер ложить секции .initN в секцию бутлоадера?
Сергей Борщ
Цитата(yvk @ Nov 1 2007, 17:32) *
на выходе код, в котором сама программа расположена в области бутлоадера, но все инициализация лежит в младших адресах.
Каким образом вы заставили его положить код в верхние адреса? От этого зависит что посоветовать. Я добавил в опции линкера -Wl,--section-start=.text=0x1800 и все кладется как надо.
yvk
Цитата(Сергей Борщ @ Nov 1 2007, 20:17) *
Каким образом вы заставили его положить код в верхние адреса? От этого зависит что посоветовать. Я добавил в опции линкера -Wl,--section-start=.text=0x1800 и все кладется как надо.

именно таким образоми заставил
в авр студио (4.13.528) в Project Option\Memory Settings: Memory type - Flash; Name - .bootloader; Address - 0xf000;
сама прога BOOTLOADER_SECTION uint8_t main (void){...}
если стартовать с нулевого адреса, то все будет работать, но с фьюзом Boot Reset Enabled как минимум не будет инициализации стека
Сергей Борщ
Цитата(yvk @ Nov 1 2007, 20:45) *
в авр студио (4.13.528) в Project Option\Memory Settings: Memory type - Flash; Name - .bootloader; Address - 0xf000;
сама прога BOOTLOADER_SECTION uint8_t main (void){...}
если стартовать с нулевого адреса, то все будет работать, но с фьюзом Boot Reset Enabled как минимум не будет инициализации стека
Выкиньте из проги BOOTLOADER_SECTION, верните настройки Memory Settings как были, а в Project options->Custom Options->Linker options добавьте -Wl,--section-start=.text=0xF000. Не буду утверждать, что это единственно правильное решение, но так работает. Вы же не собираетесь в одном проекте собирать и приложение и загрузчик?
А еще можно скопировать из AVR/LIB/LDSCRIPTS в папку проекта скрипт от вашего процессора, отредактировать в нем размещение (раздел MEMORY в самом начале) и подключить этот скрипт через ключ линкера -Wl,-T,имя скрипта
yvk
Спасибо, помогло. Нужно было заменить .bootloader на .text
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.