Перейти к содержанию
    

Ещё раз о бутлоадере

Т.е., на 12 лишних байт вы соптимизировали :)

Мораль сей басни - оптимизировать низкоуровневые вещи должен компилятор, ему то в 95% случаев надо эту оптимизацию и доверить...

Если максимальная оптимизация по размеру, то первый вариант весит 312 байт, второй - 192.

Тут действительно вылезают обещанные singlskv 120 байт.

А осадок то остался... © (не мой) :) :)

 

На самом деле в первом варианте "по скорости", IAR просто переклинило по какой-то только ему

ведомой причине.

Так иногда бывает с компиляторами. :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А осадок то остался... © (не мой) :) :)

 

На самом деле в первом варианте "по скорости", IAR просто переклинило по какой-то только ему

ведомой причине.

Так иногда бывает с компиляторами. :(

 

По сравнению с вариантом от Сергей Борщ, любезно им предоставленном мне, проигрыш вашего варианта оптимизации на этой подпрограмме составил 26 байт. Хотя честно говоря я не понимаю почему. Я оптимизировал прерывания примерно вашим способом. Видимо знаний компилятора недостаточно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По сравнению с вариантом от Сергей Борщ, любезно им предоставленном мне, проигрыш вашего варианта оптимизации на этой подпрограмме составил 26 байт. Хотя честно говоря я не понимаю почему. Я оптимизировал прерывания примерно вашим способом. Видимо знаний компилятора недостаточно.
Мой вариант, это еще был не "мой" вариант, к реальной оптимизации я просто не приступал ;)

так, показал направление ....

Вам нравится IAR ?

Хорошо, будет для IAR:

    143          
    144          __z void InvMixColumn1( byte * column ,byte bpoly_);
    145          

   \                                 In segment CODE, align 2, keep-with-next
    146          __z void InvMixColumn(byte *column)
   \                     InvMixColumn:
    147          {
    148             InvMixColumn1( column ,BPOLY);
   \   00000000   E10B               LDI     R16, 27
   \   00000002                      REQUIRE InvMixColumn1
   \   00000002                     ;               // Fall through to label InvMixColumn1
    149          }

   \                                 In segment CODE, align 2, keep-with-next
    150          __z void InvMixColumn1( byte * column ,byte bpoly)
   \                     InvMixColumn1:
    151          {
    152              byte r0, r1, r2, r3;
    153              byte co0 = column[0],co1=column[1],co2=column[2],co3=column[3];
   \   00000000   8110               LD      R17, Z
   \   00000002   8121               LDD     R18, Z+1
   \   00000004   8132               LDD     R19, Z+2
   \   00000006   8143               LDD     R20, Z+3
    154          byte tmp;
    155          
    156          r0 = co1 ^ co2 ^ co3;
   \   00000008   2F53               MOV     R21, R19
   \   0000000A   2752               EOR     R21, R18
   \   0000000C   2754               EOR     R21, R20
    157          r1 = co0 ^ co2 ^ co3;
   \   0000000E   2F63               MOV     R22, R19
   \   00000010   2761               EOR     R22, R17
   \   00000012   2764               EOR     R22, R20
    158          tmp = r0 ^ r1;
   \   00000014   2F76               MOV     R23, R22
   \   00000016   2775               EOR     R23, R21
    159          r2 = tmp ^ co3;
   \   00000018   2E04               MOV     R0, R20
   \   0000001A   2607               EOR     R0, R23
    160          r3 = tmp ^ co2;
   \   0000001C   2E13               MOV     R1, R19
   \   0000001E   ....               RCALL   ?Subroutine0
    161          
    162          co0 = (tmp=co0) << 1;
    163          if ((tmp & 0x80)==0x80) co0 ^= bpoly;
    164          co1 = (tmp=co1) << 1;
    165          if ((tmp & 0x80)==0x80) co1 ^= bpoly;
    166          co2 = (tmp=co2) << 1;
    167          if ((tmp & 0x80)==0x80) co2 ^= bpoly;
    168          co3 = (tmp=co3) << 1;
    169          if ((tmp & 0x80)==0x80) co3 ^= bpoly;
    170          
    171              r0 ^= co0 ^ co1;
   \                     ??CrossCallReturnLabel_0:
   \   00000020   2F72               MOV     R23, R18
   \   00000022   2771               EOR     R23, R17
   \   00000024   2757               EOR     R21, R23
    172              r1 ^= co1 ^ co2;
   \   00000026   2F73               MOV     R23, R19
   \   00000028   2772               EOR     R23, R18
   \   0000002A   2767               EOR     R22, R23
    173              r2 ^= co2 ^ co3;
   \   0000002C   2F74               MOV     R23, R20
   \   0000002E   2773               EOR     R23, R19
   \   00000030   2607               EOR     R0, R23
    174              r3 ^= co0 ^ co3;
   \   00000032   2F74               MOV     R23, R20
   \   00000034   2771               EOR     R23, R17
   \   00000036   ....               RCALL   ?Subroutine0
    175          
    176          co0 = (tmp=co0) << 1;
    177          if ((tmp & 0x80)==0x80) co0 ^= bpoly;
    178          co1 = (tmp=co1) << 1;
    179          if ((tmp & 0x80)==0x80) co1 ^= bpoly;
    180          co2 = (tmp=co2) << 1;
    181          if ((tmp & 0x80)==0x80) co2 ^= bpoly;
    182          co3 = (tmp=co3) << 1;
    183          if ((tmp & 0x80)==0x80) co3 ^= bpoly;
    184          
    185              r0 ^= co0 ^ co2;
   \                     ??CrossCallReturnLabel_1:
   \   00000038   2F73               MOV     R23, R19
   \   0000003A   2771               EOR     R23, R17
   \   0000003C   2757               EOR     R21, R23
    186              r1 ^= co1 ^ co3;
   \   0000003E   2F74               MOV     R23, R20
   \   00000040   2772               EOR     R23, R18
   \   00000042   2767               EOR     R22, R23
    187              r2 ^= co0 ^ co2;
   \   00000044   2F73               MOV     R23, R19
   \   00000046   2771               EOR     R23, R17
   \   00000048   2607               EOR     R0, R23
    188              r3 ^= co1 ^ co3;
   \   0000004A   2F74               MOV     R23, R20
   \   0000004C   2772               EOR     R23, R18
   \   0000004E   ....               RCALL   ?Subroutine0
    189                  
    190          co0 = (tmp=co0) << 1;
    191          if ((tmp & 0x80)==0x80) co0 ^= bpoly;
    192          co1 = (tmp=co1) << 1;
    193          if ((tmp & 0x80)==0x80) co1 ^= bpoly;
    194          co2 = (tmp=co2) << 1;
    195          if ((tmp & 0x80)==0x80) co2 ^= bpoly;
    196          co3 = (tmp=co3) << 1;
    197          if ((tmp & 0x80)==0x80) co3 ^= bpoly;
    198          
    199              tmp=co0 ^ co1 ^ co2 ^ co3;
   \                     ??CrossCallReturnLabel_2:
   \   00000050   2721               EOR     R18, R17
   \   00000052   2723               EOR     R18, R19
   \   00000054   2724               EOR     R18, R20
    200          
    201              column[0] = tmp ^ r0;
   \   00000056   2752               EOR     R21, R18
   \   00000058   8350               ST      Z, R21
    202              column[1] = tmp ^ r1;
   \   0000005A   2762               EOR     R22, R18
   \   0000005C   8361               STD     Z+1, R22
    203              column[2] = tmp ^ r2;
   \   0000005E   2602               EOR     R0, R18
   \   00000060   8202               STD     Z+2, R0
    204              column[3] = tmp ^ r3;
   \   00000062   2612               EOR     R1, R18
   \   00000064   8213               STD     Z+3, R1
    205          }
   \   00000066   9508               RET

   \                                 In segment CODE, align 2, keep-with-next
   \                     ?Subroutine0:
   \   00000000   2617               EOR     R1, R23
   \   00000002   2F71               MOV     R23, R17
   \   00000004   0F11               LSL     R17
   \   00000006   FB77               BST     R23, 7
   \   00000008   F40E               BRTC    ??Subroutine0_0
   \   0000000A   2710               EOR     R17, R16
   \                     ??Subroutine0_0:
   \   0000000C   2F72               MOV     R23, R18
   \   0000000E   0F22               LSL     R18
   \   00000010   FB77               BST     R23, 7
   \   00000012   F40E               BRTC    ??Subroutine0_1
   \   00000014   2720               EOR     R18, R16
   \                     ??Subroutine0_1:
   \   00000016   2F73               MOV     R23, R19
   \   00000018   0F33               LSL     R19
   \   0000001A   FB77               BST     R23, 7
   \   0000001C   F40E               BRTC    ??Subroutine0_2
   \   0000001E   2730               EOR     R19, R16
   \                     ??Subroutine0_2:
   \   00000020   2F74               MOV     R23, R20
   \   00000022   0F44               LSL     R20
   \   00000024   FB77               BST     R23, 7
   \   00000026   F40E               BRTC    ??Subroutine0_3
   \   00000028   2740               EOR     R20, R16
   \                     ??Subroutine0_3:
   \   0000002A   9508               RET

ИТОГО:

150 байтов программного кода (уже в 2 раза лучше чем оригинал ;) )

 

И если еще чуть напрячь мозг, то можно на 20-30 байт сократить...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Внимательно просмотрю.

Правда я отказался на сегодняшний момент от ужатия, так как в угоду функциональности всётаки проект распух. :(

 

Он уже работает.

 

С другой стороны, как я вижу, и как вы сами доказываете - вполне можно пользоваться любым инструментом. Надо просто его хорошо знать. Методы такого рода оптимизации основаны на знании как именно сам компилятор генерит код. С другой стороны, такая оптимизация достаточно зависима от компилятора.

 

Спасибо всем за помощь в реализации данного проекта. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

__z void InvMixColumn(...)

Поясните, пожалуйста, назначение "__z" (и источник информации) - в описании на компилятор 4.30A("Help>AVR>AVR C/C++ Compiler Reference Guide")не нашёл ничего подобного. Без использования "__z"код "прибавляет в весе" 4 байта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поясните, пожалуйста, назначение "__z" (и источник информации)
Было в каком-то из .html в папке документации. Указывает компилятору передавать первый указатель в регистровой паре Z. Встречается также в вариациях __x, __xz (если память не изменяет).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С другой стороны, как я вижу, и как вы сами доказываете - вполне можно пользоваться любым инструментом. Надо просто его хорошо знать. Методы такого рода оптимизации основаны на знании как именно сам компилятор генерит код. С другой стороны, такая оптимизация достаточно зависима от компилятора.
Эээ... попробую пояснить почему я Вас агитировал за Gcc.

Конечно у IAR оптимизатор написан чуть лучше чем у Gcc(в среднем), и на "плохом" коде

это всегда сказывается.

Дальше все зависит от конкретной задачки и от модели компиляции разными компиляторами.

У IAR AVR есть одно принципиальное отличие от других компиляторов,

он использует регистровую пару Y под стек и на этом очень часто превосходит

другие компиляторы, но, задачки то разные бывают...

Посмотрев исходники я увидел что в данной проге очень часто нужно >2 указателей одновременно.

Соответственно преимущество для таких задач будет иметь компилятор у которого больше

регистровых пар в распоряжении, а это Gcc а не IAR.

Просто посмотрите на листинги первоначального варианта кода и количество

использования в них инструкций типа mov X/Z, R(xx):R(xx+1) и mov R(xx):R(xx+1), X/Z

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:)

Я когда первый раз увидел результаты компилирования IAR, то тоже был немало удивлён наличием двух стеков. И первый вопрос - зачем! Чем не устраивает стандартный стэк? Зачем использовать такую дефицитную вещь как регистровая пара?

 

Внимательно рассматривая листинги - я понял. Именно при оптимизации по объёму такой подход даёт преимущество. При оптимизации по объёму появляется большое количество подпрограмм. При использовании второго стека можно делать подпрограммы сохранения регистров и восстановления. Есть и ещё ряд преимуществ. В частности возможность прямого обращения к данным в стэке. Например когда параметры находятся в стеке. Если использовать основной стек, то это более сложно получится.

 

Короче каждый подход имеет свои положительные стороны и свои отрицательные. Что очевидно.

 

К GCC претензий у меня нет и не может быть. Я не против данного компилятора. Просто работать с ним оказалось сложнее чем с IAR. Может быть когда-нибудь я его освою.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не стал создавать новую тему, поэтому здесь.

Можно ли заставить работать(не получается пока) приложение скомпилированное с такими настройками линкера

define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000044;
define symbol __ICFEDIT_region_ROM_end__   = 0x0007FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x40000040;
define symbol __ICFEDIT_region_RAM_end__   = 0x4000FFFF;

если расположить его по адресу скажем 0х1000?

Скопировал вектора, сделал ремап, передал управление на 0-вой адрес. Переходит разумеется не туда...

Если я к тому что лежит с 0х40000020-го адреса прибавляю число 0х1000 то после сброса переходит туда куда надо :biggrin: но приложение всё равно не работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что никто не знает? ...или я что-то не то спросил.

Нет желания разгадывать шарады.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть вопрос по прерываниям в bootloader и application. Итак, контроллер atmega8. Карта памяти:

0x0000 - 0x13FF: Application

0x1400 -0x17FF: Common memory (здесь храняться общие функции, доступные из application & bootloader)

0x1800 - 0x1FFF: Bootloader.

В bootloader используется одно прерывание от таймера2 по сравнению.

Контроллер программируется Avreal и стартует с Bootloader, проверяется CRC, если все ок, то переход на application. Также есть возможность запуска bootloader из application.

Итак, программирую контроллер только прошивкой загрузчика: все хорошо, прерывание работает.

Теперь, программирую контроллер с общей прошивкой (приложение+загрузчик): загрузчик запускается, отрабатывает и передает управление приложению. Затем из приложения вызываю загрузчик и вижу, что прерывание не работает. В загрузчике и приложении использую разные low_level_init, причем в загрузчике устанавливаю IVSEL, а в приложении сбрасываю. Может у кого было подобное?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может у кого было подобное?
Нет, не было. Прекрасно работают прерывания и там и там. Можете прислать проект на serzh собака rrt.lv, посмотрю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Отправил повторно.....

Moderator:

Для обильной личной переписки существует служба личных сообщений. Заодно напоминаю, что кросспосты на форуме запрещены.

Личная переписка удалена.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...