Свежие обсуждения
Микроконтроллеры

avr-gcc (WinAVR 20080512) 4.3.0 Data:889 bytes (86.8% Full) (.data + .bss + .noinit)?

Кто знает, объясните пожалуйста любителю далекому от программирования чем отличаются эти две строки.
Program: 14894 bytes (90.9% Full) (.text + .data + .bootloader)
Data: 889 bytes (86.8% Full) (.data + .bss + .noinit)
Первая строка это объём который занимает скомпилированная программа, а вот что означает вторая строка?
Настройка линковщика.
Linking: LCD494.elf
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=LCD494.o -std=gnu99 -Wundef -MMD -MP -MF .dep/LCD494.elf.d LCD494.o --output LCD494.elf -Wl,-Map=LCD494.map,--cref -lm

Creating load file for Flash: LCD494.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock LCD494.elf LCD494.hex
Creating load file for EEPROM: LCD494.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex LCD494.elf LCD494.eep || exit 0
Creating Extended Listing: LCD494.lss
avr-objdump -h -S -z LCD494.elf > LCD494.lss
Creating Symbol Table: LCD494.sym
avr-nm -n LCD494.elf > LCD494.sym
Size after:
AVR Memory Usage
----------------
Device: atmega16
Program: 14894 bytes (90.9% Full)
(.text + .data + .bootloader)
Data: 889 bytes (86.8% Full)
(.data + .bss + .noinit)
-------- end --------
> Process Exit Code: 0
> Time Taken: 00:06

 

Link: Program: 14894 bytes (90.9% Full) (.text + .data + .bootloader)
Data: 889 bytes (86.8% Full) (.data + .bss + .noinit)
Первая строка это объём который занимает скомпилированная программа, а вот что означает вторая строка?

объем данных в ЕЕПРОМ ?? ( но Всего в єтом камне 512. байт??)

 

Вторая строка "Data: 889 bytes (86.8% Full) (.data + .bss + .noinit)" описывает состояние оперативной памяти в МК, а именно, сколько всего использовано, сколько отведено под инициализированную секцию, сколько под неинициализированную...

Link, уже есть AVRstudio версия 4.18 и компилятор под неё 2010 года, советую проапгрейдить.

 

Добрый вечер GM рад Вас «видеть».
GM: описывает состояние оперативной памяти в МК
Я где то так и подозревал. Спасибо за объяснения.
А можно ещё пару вопросов?
Я в программе использую вывод на ЖК дисплей от Нокии символов, так вот когда я в рабочей программе добавляю ещё одну, критическую по счёту, строку (сообщений у меня много) вывода текста на дисплей putstr("минус к минусу"); к функции putstr(); я периодически обращаюсь по тексту программы, функция не библиотечная а самописанная, после компиляции Size after: AVR Memory Usage
----------------
Device: atmega16
Program: 14986 bytes (91.5% Full)
(.text + .data + .bootloader)
Data: 933 bytes (91.1% Full)
(.data + .bss + .noinit)
-------- end --------
> Process Exit Code: 0
> Time Taken: 00:05

Программа после загрузки в МК начинает не корректно работать, со сбоями.
Я вот что не могу понять, ведь текст сообщения в МК хранится во флеш памяти, при чём тут ОЗУ, почему у меня увеличивается объём использованного ОЗУ, как можно разгрузить ОЗУ? А то у меня получается, что я могу вывести на дисплей ограниченное количество символов.

GM: уже есть AVRstudio версия 4.18 и компилятор под неё 2010 года, советую проапгрейдить.
Я привык к WinAVR, да и вроде говорят что компилятор gcc, для любителей самое то что надо, минимум кода при «глупом» написании программы. AVRstudio смотрел года два назад, и не захотел разбираться, как то избыточен он.

И ещё вопрос - я смотрю что Program: 14986 bytes (91.5% Full)
(.text + .data + .bootloader) компилятор показывает объем памяти с учётом области, которая выделена под bootloader, я правильно понимаю?

 

Ну, если загрузчик компилируется вместе со штатной программой, то вы правильно понимаете.

Конечно, текст сообщения в МК должен храниться во флеши, но когда вы передаёте сообщение как аргумент в функцию putstr, оно сначала переписывается в системный стек, так устроен компилятор. Отсюда и память может разрастаться и ошибки могут возникнуть, если (системный) стек переполняется. Если уж используется своя функция putstr, то лучше её переписать для работы с флешью напрямую. Давайте на неё посмотрим, хотя бы издаля...

Теперь про AVRstudio. Это оболочка разработчика, которой интуитивно легко и просто пользоваться. Можно симулировать прямо в ней, иногда очень удобно, ещё железа нет, а программа уже задышала. Я использую и в Си проектах, и в ассемблерных.

Если используется Си, то можно симулировать по операторам Си. Сишный компилятор winavr (28MB) подключается автоматически, раньше он назывался avr-gcc, просто атмельцы подгребли под себя. Впрочем, говорят, что так же легко настроить CVAVR или IAR (сам не пробовал). У меня стоит дракон, удобная вещь и дешёвая, у нас стоит 40 фунтов, можно эмулировать в железе по сишному коду (мне не надо, но некоторым товарищам не помешает), им же можно и прошивать, кроме того, в составе дракона имеется JTAG.

И ещё. Попробуйте подобрать уровень оптимизации проекта, в winavr имеется 4 уровня.

 

GM: Если уж используется своя функция putstr, то лучше её переписать для работы с флешью напрямую. Давайте на неё посмотрим, хотя бы издаля...
Буду очень признателен.
Функцию putstr(); я нашёл в Интернете и адаптировал под свои нужды.

GM: Попробуйте подобрать уровень оптимизации проекта, в winavr имеется 4 уровня.
Пробовал оптимизация типа s- самая оптимальная оказалась.
Прикрепил архив с Си программой и Мейк файлом.
http://flyfolder.ru/17976909/?logoff

 

Откомпилил, без оптимизации -О0 получилось 8986 (55%) и 443 (43%) байт во флеши и в озу, с оптимизацией -Оs получилось 2092 (13%) и 435 (43%) байт, так что Link, не упирайтесь, а просто обновите WinAvr. Кстати, компилятор ругался на putchar, поскольку вы ее переопределили, а она может быть использрвана в других стандартных функциях, таких как printf, например.

Надеюсь вопрос решён, хотя можно ещё уменьшить программу, если использовать функцию pgm_read_byte(address_short), которая читает непосредственно из флеши.

 

GM: Откомпилил, без оптимизации -О0 получилось 8986 (55%) и 443 (43%) байт во флеши и в озу, с оптимизацией -Оs получилось 2092 (13%) и 435 (43%) байт, так что Link, не упирайтесь

Как видно из результата компилирования ОЗУ стабильно занято на 43% при любой оптимизации. Суть вопроса была как разгрузить ОЗУ.
Это я дал программу для примера, обрезанный вариант, собственно ответ мне понятен, надо работать на прямую с ячеек флешь, только я не пойму откуда я узнаю адрес символа, хотя помнится мне что в Си есть операнд который узнаёт адрес, спасибо за консультацию, в моей программе мне хватило ОЗУ и флешь памяти, я просто начал расширять подсказки и упёрся в то что при 91% занятости ОЗУ программа начинала чудить, и меня собственно и заинтересовал вопрос, что это за комментарий Data: 933 bytes (91.1% Full)
(.data + .bss + .noinit).

 

Вот нашлась свободная минутка, вставил функцию pgm_read_byte(address_short). Аттрибут PROGMEM располагает таблицу фонтов во флеши, а pgm_read_byte читает её оттуда напрямую. В принципе возможно дальнейшее уменьшение объёма памяти, если строки сообщений в putstr также читать из флеши, однако здесь сообщений мало и выигрыш будет незначителен.

Программа занимает 2088 байт (13%), озу - 53 байта (5%). Код ниже, изменения выделены жирным шрифтом. Надеюсь кому-то поможет победить нехватку оперативной памяти.


unsigned char fonts[][5] PROGMEM =
{
{0x3E, 0x51, 0x49, 0x45, 0x3E}, // 30 0
{0x00, 0x42, 0x7F, 0x40, 0x00}, // 31 1
{0x42, 0x61, 0x51, 0x49, 0x46}, // 32 2
void putbyte(int symb)
{
unsigned char i,ai;
unsigned char byte;
if(symb==0x2e) symb=0x4A; //Перехват для вывода других символов
if(symb==0x3D) symb=0x4B; //=
if(symb==0x49) symb=0x4C; //I
if(symb==0x56) symb=0x4D; //V
if(symb==0x20) symb=0x4E; // spaсe
if((symb>0x29)&(symb<0x40)) symb-=0x30; // Адаптация адреса к русским буквам
if(symb>=0xC0) symb-=0xB6;
ai=0;
for(i=5;i>0;i--) // Draw columns to print the character
{
PORTB &=~_BV(SCK); // Set Clock Idle level LOW.
PORTB |=_BV(SDI);
PORTB |=_BV(SCK); //clocked on the rising edge of SCK

byte=pgm_read_byte(&fonts[(unsigned char)symb][(unsigned char)ai++]);

clockdata(byte); // Clock in data bits.
}
PORTB &=~_BV(SCK); // Set Clock Idle level LOW.
PORTB |=_BV(SDI);
PORTB |=_BV(SCK); //clocked on the rising edge of SCK.
clockdata(0x00); // 1 pixel spacing per character.
}

 

GM: Надеюсь кому-то поможет победить нехватку оперативной памяти.
Мне помогло. Большое или даже огромное Спасибо я бы сам не допёр как исправить текст программы.

Device: atmega16
Program: 14006 bytes (85.5% Full)
(.text + .data + .bootloader)
Data: 495 bytes (48.3% Full)
(.data + .bss + .noinit)