Не переполняю ли я флэш-память моего AVR слишком большой программой?

У меня есть проект, в котором ATtiny2313V управляет светодиодной матрицей 7x5 для отображения прокручиваемого текста. Для отображения текста я создал шрифт, который хранится во флэш-памяти вместе с остальной частью программы.

Вся программа, включая весь шрифт, занимает 1106 байт. Но когда я загружаю его в чип, он не работает; вместо этого просто загорается пара светодиодов и все.

Однако, когда я удаляю большую часть шрифта и компилирую только буквы от A до J, программа имеет размер 878 байт и работает нормально.

Это из-за какого-то переполнения флеш-памяти AVR?

В техническом описании ATtiny2313V указано, что у него 2 КБ флэш-памяти! Как может быть слишком много 1106 байт?

ОБНОВЛЕНИЕ. Чтобы было ясно, я использую цепочку инструментов AVR Studio (для компиляции кода), а затем AVRDude для загрузки его в микроконтроллер. Насколько я знаю, AVR Studio использует версию avr-gcc для компиляции кода.


person Shalom Craimer    schedule 19.10.2009    source источник
comment
Как вы переносите файлы на avr? Какие инструменты вы используете? Например, AVRDude проверяет размер программы перед передачей данных.   -  person theomega    schedule 19.10.2009
comment
Я использую AVRDude, который общается через Arduino, запрограммированный как программист ISP. AVRDude действительно проверяет размер программы, сообщает, сколько памяти было использовано. Там написано, что больше 1106 байт и что я использую менее 60% флэш-памяти. Область eeprom занимает всего 2 байта. Вот и все.   -  person Shalom Craimer    schedule 19.10.2009


Ответы (3)


Я не уверен, какую цепочку инструментов вы используете, но в avr-gcc вам нужно будет использовать заголовок <avr/pgmspace.h> для хранения и доступа к данным во флэш-памяти — недостаточно просто объявить ваши данные const, поскольку они все еще загружены в память во время выполнения и поэтому занимает место как во флэш-памяти, так и в оперативной памяти (как и любая другая инициализированная переменная).

Ознакомьтесь с Руководством пользователя и Документация заголовка для получения дополнительной информации. Использование довольно простое, чтобы объявить массив символов во flash, используйте макрос PROGMEM:

char data[] PROGMEM = {0xc4, 0x77}; // etc

Затем, чтобы получить доступ к данным, вам нужно использовать прилагаемые макросы

char d = pgm_read_byte(&(data[i]));

Редактировать: также имейте в виду, что avrdude сообщает только о статически выделенных частях оперативной памяти (.data и .bss) для глобальных переменных, статических переменных и т. д. Вам нужно оставить место для стека - сколько именно зависит от вашей программы (подсказка: рекурсия плохо).

person Peter Gibson    schedule 27.10.2009

Клянусь, в SO есть что-то волшебное; Я несколько недель ломал себе голову, пытаясь понять это, и, задав вопрос здесь, я наконец-то вижу, что смотрело мне в лицо!

Ниже показано использование памяти для компиляции только с буквами A-J в шрифте:

AVR Memory Usage
----------------
Device: attiny2313

Program:     872 bytes (42.6% Full)
(.text + .data + .bootloader)

Data:         82 bytes (64.1% Full)
(.data + .bss + .noinit)

И вот снова, с буквами A-Z:

AVR Memory Usage
----------------
Device: attiny2313

Program:     952 bytes (46.5% Full)
(.text + .data + .bootloader)

Data:        162 bytes (126.6% Full)
(.data + .bss + .noinit)

Видите 126.6% в данных? Ой! Я действительно переполнил!

person Shalom Craimer    schedule 19.10.2009
comment
Скраймер, ты можешь это исправить! Похоже, что ваш шрифт использует Flash и RAM, что означает, что вы, возможно, не используете специальные ключевые слова, чтобы хранить данные шрифта только во Flash. См. ответ Питера Гибсона и эту страницу для получения информации: nongnu.org/avr- libc/user-manual/group__avr__pgmspace.html - person dwhall; 01.12.2009
comment
Да, это то, что я сделал; перенес на флешку. Спасибо :-) - person Shalom Craimer; 02.12.2009

Проверьте, не переполняете ли вы свой стек? Это может привести к сбоям, которые трудно обнаружить. Вы можете либо установить размер стека где-нибудь в настройках компилятора/компоновщика, либо преобразовать некоторые локальные переменные в глобальные. У встроенного процессора обычно нет проверок на переполнение стека, он просто падает.

person MrZebra    schedule 19.10.2009