Комментарии 58
Мсье знает толк в извращениях оптимизациях…
+15
Дааа!
Грязные хаки в продакшне — недопустимы. Но читать про них применимо к исследованию чего-либо… Истинное наслаждение. Спасибо.
Грязные хаки в продакшне — недопустимы. Но читать про них применимо к исследованию чего-либо… Истинное наслаждение. Спасибо.
+9
Ну как сказать недопустимы в продакшене… Бывают, знаете ли, ситуации, когда устройства уже готовы и вам нужно кровь из носу запихать прошивку в отведенные ей N килобайт ПЗУ контроллера.
+3
Вспоминается рассказ История одного байта.
+7
Любой продакшен состоит из трёх частей: говна, палок и интеллектуальной собственности. Палки из этих трёх — самые прочные и предсказуемые.
+11
Так как нам не нужно отвлекаться на другие задачи, то использование таймеров явно избыточно.
При несколько измененном ТЗ, как раз таймер очень уместен в подобной задаче: Мигаем светодиодом в AVR-бутлодере
0
Энергетически неэффективно, по сравнению с предыдущим автором :-)
+1
В последнем случае нужно считать, что размер программы — 4096 байт :)
+4
Да, у нас в конкретном случае объём 4 KiB, взяв другой микроконтроллер с большей памятью программ мы увеличим период, однако остальные ноги порта B осциллируют с бо́льшими частотами, можем подпаяться к ним.
0
А, не понял сразу))
«Исполняться» будут все 4 KiB, просто AVR Studio выдаст: Размер CSEG = 4
«Исполняться» будут все 4 KiB, просто AVR Studio выдаст: Размер CSEG = 4
+1
То есть, имея МК с большей памятью, можно обойтись вообще одной командой?
0
Двумя — в порт можно выводить только РОН, а РОН при включении пусты, поэтому инструкций две:
У МК есть еще конфигурационные биты, ими можно понизить или повысить тактовую частоту.
inc r16
out ddrb,r16
У МК есть еще конфигурационные биты, ими можно понизить или повысить тактовую частоту.
0
Верно, запрограммировав фьюз CKDIV8, можно снизить тактовую частоту в 8 раз — до 16 кГц.
+1
Этот фьюз может здорово попить кровь, к примеру, на ATTiny2313 он выставлен по умолчанию, поэтому генератор вроде как работает на 8МГц, а контроллеру достается только один.
+1
Делать надо это аккуратно, от тактовой частоты работает схема внутрисхемного программирования — программатор тоже надо будет замедлять чтобы контроллер оставался видимым программатору.
+2
Несомненно, например, AVRISP mkII поддерживает частоты программирования от 50 Гц, AVRDude тоже настраивается, говорят, что 16 кГц — не проблема.
0
Классическая неприятность — запрограммироваться на тактирование от внешнего источника. После этого спасает или высоковольтный программатор, или этот самый внешний источник.
Это усугубляется следующим моментом:
Исторически, fuse обозначал пережигаемый бит в памяти контроллера и программировался ровно один раз, путем обнуления. Поэтому все даташиты atmel пестрят фразой «0 means programmed»
Разные утилиты-прошивальщики интерпретируют запрограммированный фьюз по-разному. Популярная PonyProg рисует галочку, если значение бита 1, то есть фьюз как раз не запрограммирован. От сюда путаница и куча окирпиченных контроллеров.
Это усугубляется следующим моментом:
Исторически, fuse обозначал пережигаемый бит в памяти контроллера и программировался ровно один раз, путем обнуления. Поэтому все даташиты atmel пестрят фразой «0 means programmed»
Разные утилиты-прошивальщики интерпретируют запрограммированный фьюз по-разному. Популярная PonyProg рисует галочку, если значение бита 1, то есть фьюз как раз не запрограммирован. От сюда путаница и куча окирпиченных контроллеров.
+1
Нефига, мы ведь не писали все эти 4096 байт, да и прошивка контроллера заливаться будет всего 4 байта. А то что исполнятся будут все 4096 байт… на то он и хак!
Можно вообще сделать на 3 команды программу — инкрементируем регистр, выводим в порт и тут же зацикливаемся одной командой RJMP на её же. Устанавливаем бит конфигурации WDTON в активное состояние и наслаждаемся. Наш код будет выполняться каждые 16мс, 5-й бит порта будет мигать с периодом в 1 секунду.
Регистры по вачдогу не обнуляются, только состояние периферии поэтому каждое срабатывание вачдога будет изменение внутреннего состояния.
Хм. даже зацикливаться не надо, достаточно использовать команду SLEEP — заодно экономичная работа получится. Поскольку контроллер никогда не проснется… то никакого выполнения пустого кода не будет.
Можно вообще сделать на 3 команды программу — инкрементируем регистр, выводим в порт и тут же зацикливаемся одной командой RJMP на её же. Устанавливаем бит конфигурации WDTON в активное состояние и наслаждаемся. Наш код будет выполняться каждые 16мс, 5-й бит порта будет мигать с периодом в 1 секунду.
Регистры по вачдогу не обнуляются, только состояние периферии поэтому каждое срабатывание вачдога будет изменение внутреннего состояния.
Хм. даже зацикливаться не надо, достаточно использовать команду SLEEP — заодно экономичная работа получится. Поскольку контроллер никогда не проснется… то никакого выполнения пустого кода не будет.
0
Пардон, вы к посту про программу из двух команд пишете «Можно вообще сделать на 3 команды».
+2
Дело в том, что использовать ту память, которая не занята нашей программой для чего-то другого все равно нельзя. Потому что она таки используется нашей программой, задействована под нашу программу
В общем, тут сложный вопрос
В общем, тут сложный вопрос
0
Как же нельзя? AVR прекрасно умеет читать/писать свою собственную память программ (а иначе бутлоадер не реализовать). Там можно данные хранить.
0
Если туда что-то записать, то программа станет работать не так, как положено. В этом конкретном случае, имеется в виду.
+1
Ан нет — некоторые AVR можно перепрограммировать на старт не с 0x0000, в таком случае все что впереди — в нашем распоряжении.
+1
Так в этом конкретном случае никто же не пишет в память программ.
Или я не понял о чём вы?
Или я не понял о чём вы?
0
Тут просто по дороге нашелся еще один косвенный способ управления частотой генерации для четырехбайтной прошивки — передвинуть старт, укоротив прогоняемый контроллером участок кода.
0
НЛО прилетело и опубликовало эту надпись здесь
В пересчете на байт, наверное, была самая дорогая программа в мире
0
Нет, не угадали. habrahabr.ru/post/147075/ — бесконечно выгодная программа.
Так GO.COM, которая состояла из 0 байтов кода и продавалась по 5 фунтов за копию, оказалась самой прибыльной в мире — любая другая программа принесла куда меньше фунтов на байт!
+6
Это если цельная программа. А если программное решение, то у меня был случай, когда я в течении дня пялился в неработающий код, который ребята не могли заставить работать три дня, после чего удалил из него 4 буковки и всё заработало. В пересчёте на написанный байт моё исправление имело вообще отрицательную цену.
+2
это был x86? джамп на ребут не может занимать 3 байта однако. адрес длиннее.
и опасно это — надо обязательно буфера smartdrv флашнуть на диск — он-то не в курсе
можно было через 19-ое прерывание (кажется 19-ое? я уже не помню), но тогда это не 3 байта
и опасно это — надо обязательно буфера smartdrv флашнуть на диск — он-то не в курсе
можно было через 19-ое прерывание (кажется 19-ое? я уже не помню), но тогда это не 3 байта
0
НЛО прилетело и опубликовало эту надпись здесь
вызвать прерывание… два байта — команда 1 байт и номер прерывания 1 байт.
Как сейчас помню — байт-код 0xCDxx где XX — номер прерывания.
18 или 19 прерывание… одно из них сброс, а другое зарезервировано за вызовом встроенного интерпретатора бейсика, но даже со времён XT бейсика там и в помине не было, поэтому прерывание выполняло функцию сброса системы…
Но ИМХО сейчас на современных машинах это не прокатит, супервизор перехватит переход на прерывание и даст по рукам программе — «ай-яй-яй так делать нельзя!».
Как сейчас помню — байт-код 0xCDxx где XX — номер прерывания.
18 или 19 прерывание… одно из них сброс, а другое зарезервировано за вызовом встроенного интерпретатора бейсика, но даже со времён XT бейсика там и в помине не было, поэтому прерывание выполняло функцию сброса системы…
Но ИМХО сейчас на современных машинах это не прокатит, супервизор перехватит переход на прерывание и даст по рукам программе — «ай-яй-яй так делать нельзя!».
+1
а я что сказал? то же самое, что это не три байта.
кроме того, совершенно нет гарантии, что какой-то резидент не перехватывает это прерывание, либо просто вектор указывает куда-то в пустоту после того как кто-то затер системную память.
так что перезагрузка таким образом не совсем надёжна.
кроме того, совершенно нет гарантии, что какой-то резидент не перехватывает это прерывание, либо просто вектор указывает куда-то в пустоту после того как кто-то затер системную память.
так что перезагрузка таким образом не совсем надёжна.
0
На современных системах НИ ОДИН способ программной перезагрузки не может быть абсолютно надёжным.
+1
Полностью согласен — помогает только железный костыль в виде сторожевого таймера.
0
НЛО прилетело и опубликовало эту надпись здесь
Старинный компьютер с LPT, 12 опторазвязок Sharp PC817 — и готова станция перезапуска/включения/наблюдения для четырех серверов.
Такой себе iLO на коленке.
Такой себе iLO на коленке.
0
НЛО прилетело и опубликовало эту надпись здесь
Любая программа содержит ошибки.
Любую программу можно укоротить хотя бы на байт.
Вывод: в результате оптимизации получаем программу длиной в 1 байт, содержащий ошибку.
Любую программу можно укоротить хотя бы на байт.
Вывод: в результате оптимизации получаем программу длиной в 1 байт, содержащий ошибку.
0
Ну, господа, грех не использовать хардварные регистры для битовых переменных, если сам функционал хардварный не используется. Доступ за один такт например, очень пользительно. Главное бит активации не трогать. Так можно использовать spi, twi, или usart.
Даже в продакшене это не не кошерно.
А есть еще кучка хинтов, и отнють не грязных. Просто не используемых…
Даже в продакшене это не не кошерно.
А есть еще кучка хинтов, и отнють не грязных. Просто не используемых…
+1
У AVR доступ ко всем РОН в один такт:
Регистровый файл с битовым доступом содержит 32 восьмибитных РОН с доступом за один тактовый цикл:
«The fast-access Register File concept contains 32 x 8-bit general purpose working registers with a single-clock-cycle access».
//////// Даташит на ATTiny15, страница 5.
Регистровый файл с битовым доступом содержит 32 восьмибитных РОН с доступом за один тактовый цикл:
«The fast-access Register File concept contains 32 x 8-bit general purpose working registers with a single-clock-cycle access».
//////// Даташит на ATTiny15, страница 5.
+1
Как автор публикации про 24 байта замечу, что мной и вторым автором — рекордсменом (12 байт) были показаны чистые способы экономии байт, которые таки годятся в продакшн.
В очередной раз благодарю за проявленный интерес и усердие в исследованиях тонкостей ассемблера и AVR в частности.
0xFFFF = SBRS R31,7
В очередной раз благодарю за проявленный интерес и усердие в исследованиях тонкостей ассемблера и AVR в частности.
т. е. после того, как процессор выходит за пределы программы ему попадаются исключительно инструкции 0xFFFF, они незадокументированы
0xFFFF = SBRS R31,7
+1
sbrs r, b
Пропустить команду, если рязряд регистра общего назначения установлен.
Если r.b = 1, то PC = PC + 2 (3), иначе PC = PC + 1
Код операции: 1111 111r rrrr 0bbb
Следовательно, sbrs r31, 7 это 0xFFF7.
Возможно, процессор воспринимает 0xFFFF как эту команду, при r31.7 = 0 он просто переходит дальше.
Пропустить команду, если рязряд регистра общего назначения установлен.
Если r.b = 1, то PC = PC + 2 (3), иначе PC = PC + 1
Код операции: 1111 111r rrrr 0bbb
Следовательно, sbrs r31, 7 это 0xFFF7.
Возможно, процессор воспринимает 0xFFFF как эту команду, при r31.7 = 0 он просто переходит дальше.
+1
Во времена 16F84 был такой способ написать HelloWorld: изменялось состояние нужного пина на обратное и выставлялся WatchDog. Через какое-то время WatchDog сбрасывал и перезагружал процессор, то все опять с начала: изменили, заснули.
+2
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Где предел минимального Hello World на AVR?