Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите впихнуть невпихуемое
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
alux
Размер программы превышает на 25 байт допустимой. Выжал из программы все, что смог. Рекомендации из апнота AVR035 прочитал. Можна ли как-то использовать неиспользованные вектора прерываний? В xcl-файле убрал:
/* Fill unused interrupt vector's with RETI */
//-H1895
//-h(CODE)0-_..X_INTVEC_SIZE
Не помогло. Пробовал уменьшить
-D_..X_INTVEC_SIZE=34 /* 26 Interrupt vectors * 2 bytes each */
до 30, если меньше выдает ошибку. Еще в программе используется 20 глобальных переменных. Пробовал объединять в структуры. Дало выигрыш аж в 4 байта. Может еще будут какие предложения? Может где-то в настройках стека или еще что... МК - мега48.
slog
Ну для начала "Историю одного байта" прочти.
http://www.caxapa.ru/lib/1byte.html
А потом садись оптимизировать код. Листинг ассемблерный поможет. В листинге линкера есть информация о том сколько какая функция занимает. С самых жирных и начинай. Уверен 100% что 25 байт ужать можно. Какой размер программы-то? И какие функции самые жирные?
alux
Цитата(slog @ Jun 11 2007, 14:28) *
Ну для начала "Историю одного байта" прочти.

Очень интересная история. Правда. Очень понравилась. У меня получилось почти как в рассказе. Правда еще один байт остался в запасе smile.gif. Выкинул проверку источника сброса и разместил три глобальные переменные в регистрах.
Самая ресурсоемкая функция - формула с применением деления и корня квадратного. Использую из math.h.
А что на счет использования неиспользуемых векторов прерывания?
IgorKossak
Можно подправить cstartup.s90 и повыкидывать из него то, что не нужно, но этого явно не хватит.
Помимо стандартных дя IAR компилятора методов оптимизации можно применить опцию мультифайловой оптимизации -mfc. Об этом написано в /avr/doc/manuals.htm
slog
Цитата(alux @ Jun 11 2007, 16:34) *
Самая ресурсоемкая функция - формула с применением деления и корня квадратного. Использую из math.h.
А что на счет использования неиспользуемых векторов прерывания?

Если у тебя не используется вообще ни одного прерывания, тогда может и сэкономишь чего. А делишь и корни извлекаешь случаем не из float? Если из него, то очень желательно заменить на long обычно это возможно, если получится, можно очень сильно сэкономить. Я недавно сэкономил 2,8кб просто заменив float powf(float, float) на float * float. smile.gif
alux
Цитата(slog @ Jun 11 2007, 16:30) *
Если у тебя не используется вообще ни одного прерывания, тогда может и сэкономишь чего.

Т.е. если хотя бы одно прерывание используется , то на адреса векторов прерываний можно не претендовать?
IgorKossak
Цитата(alux @ Jun 11 2007, 17:19) *
Т.е. если хотя бы одно прерывание используется , то на адреса векторов прерываний можно не претендовать?

Не на все, а только от нуля до используемого вектора включительно.
alux
Цитата(IgorKossak @ Jun 11 2007, 17:42) *
Не на все, а только от нуля до используемого вектора включительно.

Если у меня используется прерывание АЦП, то могу окупировать 4 байта? А что для этого нужно сделать?
KRS
Цитата(alux @ Jun 11 2007, 15:23) *
Еще в программе используется 20 глобальных переменных. Пробовал объединять в структуры. Дало выигрыш аж в 4 байта. Может еще будут какие предложения? Может где-то в настройках стека или еще что... МК - мега48.

Так у вас в каком сегменте памяти не хватает? Во флеше или SRAM, переменные то в SRAM хранятья.
А тут в основном обсуждалось как вектора прерываний освободить, но они во флеше и переменные там не разместить.
alux
Цитата(KRS @ Jun 11 2007, 20:56) *
Так у вас в каком сегменте памяти не хватает? Во флеше или SRAM, переменные то в SRAM хранятья.
А тут в основном обсуждалось как вектора прерываний освободить, но они во флеше и переменные там не разместить.

Да, флеша не хватает. С переменными я погорячился. Так как мне заполнить пространство кода до вектора прерывания? У меня используется два прерывания: OVF0(0x20) и ADC(0x2A) . Как раз 30 байт спасут "отца русской демократии" smile.gif
KRS
Цитата(alux @ Jun 11 2007, 22:50) *
Да, флеша не хватает. С переменными я погорячился. Так как мне заполнить пространство кода до вектора прерывания? У меня используется два прерывания: OVF0(0x20) и ADC(0x2A) . Как раз 30 байт спасут "отца русской демократии" smile.gif

Как тут уже говорили можно переписать cstartup. Причем если писать на asm то можно по адресу 0 расположить не сразу rjmp, а 15 инструкций и 16ая rjmp (32 байта свобдно).
Дальше пойдет обработчик OVF0, если он на asm то можно 4 инструкции + rjmp.
Потом разместить обработчик ADC целиком.
IgorKossak
Цитата(alux @ Jun 11 2007, 18:18) *
Если у меня используется прерывание АЦП, то могу окупировать 4 байта? А что для этого нужно сделать?

Подправить командный файл линкера, но не так как Вы это уже делали в плане количества векторов.
В опциях -Z(CODE) диапазоны адресов указать надо от 0, а не от INTVEC_SIZE.
Это более универсально, чем править cstartup на ассемблере, но менее экономично по высвобождаемой памяти.
Кроме того, если у Вас не предусмотрен возврат из функции main() (exit), в cstartup можно удалить всё, что после вызова main, а вызов main заменить на jmp. Да и саму main() можно определить как __task int main(), чтобы она не сохраняла и не восстанавливала регистры в начале и в конце.
alux
Цитата(IgorKossak @ Jun 12 2007, 10:26) *
Подправить командный файл линкера, но не так как Вы это уже делали в плане количества векторов.
В опциях -Z(CODE) диапазоны адресов указать надо от 0, а не от INTVEC_SIZE.


/* Code memory */
-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-1)
-Z(CODE)CODE=_..X_INTVEC_SIZE-_..X_FLASH_END

Что здесь необходимо изменить?
KRS
Цитата(alux @ Jun 12 2007, 11:53) *
/* Code memory */
-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-1)
-Z(CODE)CODE=_..X_INTVEC_SIZE-_..X_FLASH_END

Что здесь необходимо изменить?

Не используется послдение 4 вектора поэтому
/* Code memory */
-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-9)
-Z(CODE)CODE=(_..X_INTVEC_SIZE-8)-_..X_FLASH_END

Но это даст только 8 байт.
Сергей Борщ
Цитата(KRS @ Jun 12 2007, 12:06) *
Не используется послдение 4 вектора поэтому
/* Code memory */
-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-9)
-Z(CODE)CODE=(_..X_INTVEC_SIZE-8)-_..X_FLASH_END

Но это даст только 8 байт.
Странные вы люди. Линкер сам знает, сколько памяти он занял при размещении предыдущих сегментов и следующие сегменты размещаетс с первого свободного в указанном диапазоне, так зачем вы ему принудительно диапазон обрезаете? Размещаются сегменты в том порядке, в котором перечислены в .xcl
Код
/* Code memory */
-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE - 1)
-Z(CODE)CODE=0-_..X_FLASH_END
Все. Сколько надо - он возьмет под вектора и дальше пойдет код. Можете пользовать в любом проекте, независимо от количества используемых векторов
IgorKossak
Цитата(Сергей Борщ @ Jun 12 2007, 13:22) *
Код
/* Code memory */
-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE - 1)
-Z(CODE)CODE=0-_..X_FLASH_END
Все. Сколько надо - он возьмет под вектора и дальше пойдет код. Можете пользовать в любом проекте, независимо от количества используемых векторов

Или ещё проще
Код
-Z(CODE)INTVEC,CODE=0-_..X_FLASH_END
alux
Цитата(IgorKossak @ Jun 12 2007, 22:18) *
Или ещё проще
Код
-Z(CODE)INTVEC,CODE=0-_..X_FLASH_END

Спасибо. Помогло.
_artem_
Если используется вектор прерывания то можно зарезервировать как можно больше Rxx регистров (в настройках проекта) - в итоге в обработчике прерываний push pop для них выполнятся не будет.
IgorKossak
Цитата(_artem_ @ Jun 17 2007, 20:52) *
Если используется вектор прерывания то можно зарезервировать как можно больше Rxx регистров (в настройках проекта) - в итоге в обработчике прерываний push pop для них выполнятся не будет.

А если применяются некоторые сложные библиотечные функции, то такая экономия регистров может привести к нерабочему коду. ИАРовцы рекомендуют лочить не более пяти регистров (manuals.htm).
LeonY
Цитата(alux @ Jun 11 2007, 14:34) *
Очень интересная история. Правда. Очень понравилась. У меня получилось почти как в рассказе. Правда еще один байт остался в запасе smile.gif. Выкинул проверку источника сброса и разместил три глобальные переменные в регистрах.
Самая ресурсоемкая функция - формула с применением деления и корня квадратного. Использую из math.h.
А что на счет использования неиспользуемых векторов прерывания?

Эта история старая и представляет из себя полное фуфло (образцы чрезвычайно плохого руководства проектом в первую очередь и не слишком умного разработчика - во вторую). Такое возможно в среде фанатов-любителей, а не профессионалов. Если взять на рассмотрение этот Business Case, то кроме смеха никакой другой реакции не могу предположить. Надо просто взять калькулятор и посчитать оплату этого "гения" vs похороны всех выпущенных плат и их замены на платы с большим кристаллом. Как вариант остается полный нах заказчику, который там чего-то забыл и точно не является гением ни в электроннике ни в Projec Management. Интересно - слышали ли эти персонажи о таком понятии, как Redundant Resources. Если нет - то надо просто почитать букварь, а не писать слезливое фуфло; если да - то все они бандиты и лузеры. Ладно останавливаюсь, на эту тему можно писать бесконечно...
IgorKossak
Абсолютно согласен с LeonY, хоть и не так категорично.
Подобную же тему с таким же эффектом можно открыть и с названием "История одного такта".
С дугой стороны могу рассказать следующее. Заказчик выдал нам задание, мы его оценили с запасом примерно 50% как по памяти, так и по скорости. Реализовали проект - все довольны. Потом началось: "А вот нам бы ещё вот это и немножечко вот это" и т. д. раз в неделю. Дошло до того, что мега128 стала забита на 127,5 килобайт (оптимизация максимальная). Т. е. пожеланий осталось на один чих.
Слава Кому Следует, что по скорости пока нареканий нет.
GetSmart
Как вариант можно переписать одну из проедур на асме. Экономия будет.

Да и собственно в 99.99% случаев всегда можно оптимизировать код.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.