Давным давно наткнулся на прекрасную статью (тык) — в ней автор достаточно наглядно показал разницу между использованием ардуиновских функций и работой с регистрами. Статей, как восхваляющих ардуино, так и утверждающих, что это все несерьезно и вообще для детей, написано множество, так что не будем повторяться, а попытаемся разобраться в том, что послужило причиной для результатов, полученных автором той статьи. И, что не менее важно, подумаем что можно предпринять. Всех, кому интересно, прошу под кат.
Часть 1 "Вопросы"
Цитируя автора указанной статьи:
Получается проигрыш производительности в данном случае — 28 раз. Разумеется что это не значит, что ардуино работает в 28 раз медленнее, но я считаю, что для наглядности, это лучший пример того, за что не любят ардуино.
Так как статья только началась, не будем пока разбираться, а проигнорируем второе предложение и будем считать что скорость работы контроллера приблизительно эквивалентна частоте переключения пина. Т.е. перед нами стоит задача сделать генератор наибольшей частоты из того что имеем. Для начала посмотрим насколько всё плохо.
Напишем простую программу для ардуино (по сути просто скопируем blink).
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, 1); // turn the LED on (HIGH is the voltage level)
digitalWrite(13, 0); // turn the LED off by making the voltage LOW
}
Зашиваем в контроллер. Так как у меня нет осциллографа, а только китайский логический анализатор, его необходимо правильно настроить. Максимальная частота анализатора 24 MHz следовательно её необходимо уравнять с частотой контроллера — выставить 16MHz. Смотрим ...
… долго. Пытаемся вспомнить, от чего зависит скорость работы контроллера — точно, частота. Смотрим в arduino.cc. Clock Speed — 16 MHz, а у нас тут 145.5 kHz. Что делать? Попробуем решить в лоб. На том же arduino.cc смотрим остальные платы:
- Leonardo — не подайдёт — там тоже 16 MHz
- Mega — тоже — 16 MHz
- 101 — подойдёт — 32MHz
- DUE — ещё лучше — 84 MHz
Можно предположить, что если увеличить частоту контроллера в 2 раза, то частота мигания светодиода тоже увеличится в 2 раза, а если в 5 — то в 5 раза.
Мы не получили желаемых результатов. Да и генератор все меньше и меньше напоминает меандр. Думаем дальше — теперь, наверное, язык плохой. Вроде как есть с, с++, но это сложно(в соответствии с эффектом Даннинга-Крюгера мы не можем осознать что уже пишем на с++), потому ищем альтернативы. Недолгие поиски приводят нас к BASCOM-AVR (тут неплохо про него рассказано), ставим, пишем код:
$Regfile="m328pdef.dat"
$Crystal=16000000
Config Portb.5 = Output
Do
Toggle Portb.5
Loop
Получаем:
Результат намного лучше, к тому же получился идеальный меандр, но… бейсик в 2018м, серьезно? Пожалуй, оставим это в прошлом.
Часть 2 "Ответы"
Кажется, уже пора переставать валять дурака и начинать разбираться (а также вспомнить си и ассемблер). Просто скопируем "полезный" код из статьи, упоминавшейся в начале, в loop().
Здесь, полагаю, нужно пояснение: весь код будет писаться в проекте ардуино, но в среде Atmel Studio 7.0 (там удобный дизассемблер), скрины будут из неё же.
void setup() {
DDRB |= (1 << 5); // PB5
}
void loop() {
PORTB &= ~(1 << 5); //OFF
PORTB |= (1 << 5); //ON
}
результат:
Вот оно! Почти то, что нужно. Только форма не особо на меандр похожа и частота, хоть и уже ближе, но все равно не та. Также попробуем увеличить масштаб и обнаружим разрывы в сигнале каждую миллисекунду.
Связано это со срабатыванием прерываний от таймера, отвечающего за millis(). Так что поступим просто — отключим. Ищем ISR (функция обработчик прерывания). Находим:
ISR(TIMER0_OVF_vect)
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
nsigned char f = timer0_fract;
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}
timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
}
Много бесполезного для нас кода. Можно изменить режим работы таймера или отключить прерывание, но это излишне для наших целей, поэтому просто запретим все прерывания командой cli(). Так же посмотрим на наш код:
PORTB &= ~(1 << 5); //OFF
PORTB |= (1 << 5); //ON
слишком много операторов, уменьшим до одного присвоения.
PORTB = 0b00000000; //OFF
PORTB = 0b11111111; //ON
Да и переход по loop() занимает много команд, так как это лишняя функция в основном цикле.
int main(void)
{
init();
// ...
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
Поэтому просто сделаем бесконечный цикл в setup(). Получаем следующее:
void setup() {
cli();
DDRB |= (1 << 5); // PB5
while (1) {
PORTB = 0b00000000; //OFF
PORTB = 0b11111111; //ON
}
}
61 ns это максимум, соответствующий частоте работы контроллера. А можно ли быстрее? Спойлер — нет. Давайте попробуем понять почему — для этого дизасемблим наш код:
Как видно из скрина, для того чтобы записать в порт 1 или 0 тратится ровно 1 такт, вот только дальше идет переход, который не может быть выполнен меньше чем за один такт (RJMP выполняется за два такта, а, например, JMP, за три). И мы практически у цели — для того, чтобы получился меандр, необходимо увеличить время, когда подан 0, на два такта. Добавим для этого две ассемблерные команды nop, которые ничего не делают, но занимают 1 такт:
void setup() {
cli();
DDRB |= (1 << 5); // PB5
while (1) {
PORTB = 0b00000000; //OFF
asm("nop");
asm("nop");
PORTB = 0b11111111; //ON
}
}
Часть 3 "Выводы"
К сожалению, все что мы делали абсолютно бесполезно с практической точки зрения, потому что мы не можем больше исполнять никакой код. Так же в 99,9% случаев частот переключения портов вполне хватает для любых целей. Да и если нам очень нужно генерировать ровный меандр, можно взять stm32 с dma или внешнюю микросхему таймера вроде NE555. Данная статья полезна для понимания устройства работы mega328p и arduino в целом.
Тем не менее запись в регистры 8ми битных значений PORTB = 0b11111111;
намного быстрее чем digitalWrite(13, 1);
но за это придется заплатить невозможностью переноса кода на другие платы, потому что названия регистров могут отличатся.
Остался лишь один вопрос: почему использование более быстрых камней не дало результатов? Ответ очень прост — в сложных системах частота gpio ниже чем частота ядра. А вот насколько ниже и как её выставить всегда можно посмотреть в даташите на конкретный контроллер.
В публикации ссылался на статьи:
- HWman https://habr.com/post/254163/
- vvzvlad https://habr.com/post/151544/
- Даташит ATmega328/P
- Конечно https://arduino.cc
- Превью https://habr.com/post/190180/
Комментарии (86)
koldyr
03.09.2018 17:39Можно быстрее. Запрещяете прерывания и пишите через всю память порт 0, порт 1. Счетчик команд циклический, а порт, если мне не изменяет память, по умолчанию — out. получаете меандр на половине тактовой частоты.
ZEN_LS Автор
04.09.2018 14:08Скорее всего не прокатит, счетчик команд (на сколько я помню) 16 битный, а размер памяти произвольный, поэтому он пойдет вперед когда память уже кончится. Также память нужна для кучи и стека.
technomancer
03.09.2018 17:51+1Пришло время, когда люди на C пишут грамотнее, чем на русском. Не о таком киберпанке я мечтал. :-(
Часто «для переноса кода на другие платы» аппаратно-зависимые вещи выделяют в отдельные (условно — «низкоуровневые») блоки, которые правят под конкретное железо. А «логика» портируется без изменений.
smart_alex
03.09.2018 19:06Хотелось бы отделить мух от котлет. Для 99% типичных задач, которые решаются на Ардуино, нет абсолютно никакой разницы с какой скоростью работает digitalWrite. А для тех задач, где принципиальна скорость — используем соответствующие решения — ассемблерные вставки, прямое программирование портов, мощные контроллеры или вообще уходим от парадигмы Ардуино и используем «профессиональные» решения.
Не нужно создавать проблемы на ровном месте и противопоставлять Ардуино и «взрослые» решения.Vladimir_Feschenko
03.09.2018 19:31всё верно, если 99% задач — помигать светодиодом.
Mike_soft
03.09.2018 20:16+2вентилятор, вентилятор в туалете забыли!!!
Zombieff
04.09.2018 13:04Если в туалете включён свет, и с мобильника по вайфаю пошёл трафик на хабр/реддит, то включаем вентилятор?
Вот он, умный дом.IvanKor2017
05.09.2018 16:49я пошел дальше :D
сделал на arduine geomagnetic magnetometer
github.com/IvanKor/geomagnetic-magnetometer
который круче (полоса пропускания шире более чем в три раза ) чем используется здесь
geodata.izmiran.ru
Mike_soft
03.09.2018 20:19+1если нужна скорость — нужно не «ассемблерные вставки», а выкидывать ардуину…
ZEN_LS Автор
04.09.2018 06:36Вот, вот, это статья как-раз и нацелена на то, чтобы никто не делал такое ошибочное суждение, ибо arduino это всего лишь uart загрузчик. Никто не просит использовать её IDE и тем более arduino core.
Mike_soft
04.09.2018 06:59-1тогда от дуйни ничего и не остаётся. если выкинуть ядро — выкинешь и все наработки, всё сообщество. а в этом и есть вся ценность дуйни для начинающих. ну и сейчас, в 201х, использовать ассемблер. тем более, устаревшего железа… зачем? начинающему проще перелезть на нуклео, а грамотный и без дуйни справится
FDA847
03.09.2018 21:53Совершенно верно! Каждый инструмент для своих задач. На ардуине быстро и легко создавать новые проекты. Под неё вон сколько библиотек есть. Я сам за вечер сделал с нуля термометр на балкон на базе датчика DS18B20 и матричного светодиодного индикатора. При этом с ардуино ранее вообще не работал!
Но в то же время в какое-то серийное изделие на мой взгляд ардуина не особо вписывается.Mike_soft
04.09.2018 08:55ровно так же вы могли сделать это же на STM по статье olartamonov
FDA847
04.09.2018 09:01+1Ну на STM, PIC, AVR я действительно мог бы и сам сделать, потому что работаю с ними уже давно. Просто однажды мне стало интересно поиграться с ардуиной. Оказалось, что порог вхождения там очень низкий, что меня весьма порадовало. Для своего сегмента это просто отличное решение!
Mike_soft
04.09.2018 09:30для mbed порог вхождения не выше (ну или не сильно выше).
ZEN_LS Автор
04.09.2018 14:12Mbed не набор либ, а операционная система. Сказать что и как она делает почти не реально. Поэтому все используют free rtos. Вспомнил вот что по этому поводу: habr.com/post/387299
Mike_soft
04.09.2018 14:36ну, олегартамонов же недавно сказал, что допилили mbed совсем недавно. если первые версии дуйни вспомнить — там тоже изрядно косяков было…
IvanKor2017
05.09.2018 16:42на STM в среде arduino термометр на базе датчика DS18B20
github.com/IvanKor/DS18B20_USART_DMA_STM32
без «ногодрыга» в режиме реалтайм за пару вечеров :Diig
06.09.2018 10:45Если учесть, что нет смысла очень часто температуру мерить (если например, температура на улице — раз в полчаса выше крыши), то ардуиновский модуль с ногодрыгом за 5 минут вполне годное решение. Пару вечеров можно и на что-то другое потратить.
GipsyIF
04.09.2018 14:01Согласен с Вами. Самый простой и быстрый путь проверить например какой-то новый экранчик, с которым ещё не работал — это Ардуина. У неё есть библиотеки почти под все устройства.
ZEN_LS Автор
04.09.2018 14:04Я заметел очень класную штуку. Года 4 для меня сказанное было неоспоримой истиной, но теперь после avr, stm, длайверов под linux, для меня зайвет одинаковое количество времени написать либу под новый дисплей что под arduino, что под avr, что под linux. Но писать под avr будет намного приятнее.
ZEN_LS Автор
04.09.2018 04:08Проблема не в качестве решения, проблема в том что 90% ардуинщиков не понимают что они пишут. Статья для того чтобы показать что код собирается не магией, а авровским тулчейном.
farcaller
03.09.2018 19:44+1Максимальная частота анализатора 24 MHz следовательно её необходимо уравнять с частотой контроллера — выставить 16MHz
Но зачем? Частота анализатора должна быть выше чем частота сигнала, что бы снять его точно, нет?
ZEN_LS Автор
04.09.2018 04:41Тут вот какое дело, если частота будет 24 Мгц, то мы не сможем нормально померить время. Полученные результаты просто не будут пропорциональны времени такта. Пример: минимальное время полученное в статье соответствует времени между 2мя измерениями анализатора и это 62,5 нс, если мы поставим 24 Мгц то анализатор успеет сделать 2 измерения и время будет 83,3 нс, что не соответствует действительности. Так что нет, частота анализатора должна быть пропорциональна частоте контроллера для получения точных результатов.
SergeyMax
03.09.2018 20:17Да и если нам очень нужно генерировать ровный меандр, можно взять stm32 с dma или внешнюю микросхему таймера вроде NE555.
Скажите, а вы слышали когда-нибудь о таймерах? Говорят, они даже в ардуине есть.
Данная статья полезна для понимания устройства работы mega328p и arduino в целом.
Хм, не уверен.ZEN_LS Автор
04.09.2018 04:11Слышал, про них даже в моей статье можно прочитать, речь о том чтобы генерация меандра не занимала тактов контроллера.
SergeyMax
04.09.2018 08:05+1Но ведь генерация меандра таймером не занимает тактов контроллера.
ZEN_LS Автор
04.09.2018 13:58Если только на этом таймере висит дма, а так нужен обработчик.
SergeyMax
04.09.2018 14:59Если только на этом таймере висит дма, а так нужен обработчик.
Для генерации меандра таймеру не нужен ни DMA, ни обработчик.ZEN_LS Автор
04.09.2018 16:35+1Вы правы, как оказалось, я забыл про режир работы тактового генератора, да и если с шимом поколдовать тоже можно что-то подобное сделать. Выдержка из даташита:
Channel Counter
• Clear Timer on Compare Match (Auto Reload)
• Glitch-free, Phase Correct Pulse-Width Modulator (PWM)
• Frequency Generator
• 10-bit Clock Prescaler
• Overflow and Compare Match Interrupt Sources (TOV2, OCF2A, and OCF2B)
• Allows Clocking from External 32 kHz Watch Crystal Independent of the I/O Clock
shiru8bit
03.09.2018 20:27Мне Arduino никогда не казалась медленной. 16-20 MIPS — это очень много, '16 MIPS должно хватить всем' и этого достаточно даже для генерации монохромного видеосигнала чисто кодом. Разумеется, где критична скорость, не должно быть никаких высокоуровневых библиотек и скрытых прерываний. Обычно хватает прямой работы с портами на C, но Arduino IDE позволяет и ассемблерные вставки (с диким синтаксисом), если что. И конечно таймеры.
В прошлом году ради интереса делал перенос на Arduino пяти 1-битных синтезаторов звука с ZX Spectrum, в которых довольно хитроумный, максимально оптимизированный код на Z80. Оригинальные алгоритмы ложились на новую платформу довольно занимательным образом, на чистом C, без вставок ассемблера. Наиболее интересный пример: randomflux.info/1bit/viewtopic.php?id=127ZEN_LS Автор
04.09.2018 04:13Про скорость это скорее шутка, я считал что очевидно что описанное в статье не имеет отношение к производительности (в контексте математических операций).
AndrewRo
03.09.2018 22:06+2Очень полезная статья. По-моему, для новичков очень важно знать, что высокоуровневый код никогда не даст такой скорости и точности, как низкоуровневый и масштабы этого явления. От себя добавлю, что примерно то же самое происходит и с памятью кода. Когда я решил сделать один из своих проектов не на С, как обычно, а на ардуиновском диалекте, для меня было большой неожиданностью, что ATMega2560 закончилась буквально на 400 строке. Насколько я понимаю, особенно прожорлива местная объектная модель.
smart_alex
04.09.2018 06:37Хочу заметить, что практическая полезность определяется не абстрактными «скоростью и точностью» (которые нужны только на специфических задачах), а решением насущных проблем, с которыми Ардуино справляется на ура (и тут её популярность говорит сама за себя).
Что касается памяти, то её тоже «нужно уметь готовить» — на Меге в Ардуино нет никаких проблем с объёмными (как по оперативной, так и по флеш памяти) проектами. Чужие библиотеки действительно могут очень вольно обращаться с памятью, но это скорее проблема не объектной модели программирования, а уровня знаний и прилежания самого автора библиотеки.
Mike_soft
04.09.2018 07:25все нормальные люди знают, что низкоуровневый код [для всех систем] работает быстрее, но пишется дольше и сложнее. и наоборот. и что ЯВУ разменивают скорость разработки на скорость работы. людям, которым для осознания этого требуется статья — она уже не поможет.
mksma
03.09.2018 22:33Кажется можно сделать быстрее если вместо присвоения использовать xor на соответствующем бите порта B. При этом в идеале загрузить битовую маску в регистр нужно 1 раз, до начала цикла.
ZEN_LS Автор
04.09.2018 04:16Присвоение — один такт, по сути запись из регистра в порт, проводить xor и потом писать значение в порт как минимум 2 такта.
gerasimenkoao
04.09.2018 11:03С первой публикацией на хабре!
Все конечно хорошо, но саму платформу arduino(как и любых других МК) рассматриваю как утилитарную вещь для решения определенных прикладных задач, пускай уже и тысячу раз реализованных.
Поэтому за парктроник, пускай и на столе работающий — проголосовал, а за сферический blink в вакууме — увы — нет.
Вот если с помощью ардуино квадрокоптеры сбивать, да хоть пуляя микроконтроллерами из рогатки — это был-бы FUN ;-)
Mike_soft
04.09.2018 11:21сын делал в 8 классе на конкурс по робототехнике стрелялку по вертолету. как раз на ардуине. сам спаял ее из фридуиновского набора.
точность невелика — но довольно эффектно. но как раз перед демонстрацией сгорела катушка соленоида «электоспуска». было обидно.
Peacemaker
04.09.2018 11:48Вот если с помощью ардуино квадрокоптеры сбивать
Думал над концепцией такого обвеса для автоматического оружия, которое позволит определять лазерным дальномером дистанцию до дрона, и имея прошитые данные по баллистике применяемого боеприпаса, а также данные с сенсоров температуры, давления и силы ветра (опционально) находить и показывать бойцу, в какое положение необходимо поставить оружие для максимальной вероятности поражения коптера. Такой себе баллистический компьютер для бедных.iig
04.09.2018 12:03Добавить сервомоторы, турель… Человек тут лишний, пулять в зенит из ручного оружия очень неудобно, а роботу все равно.
IGR2014
04.09.2018 12:15Простите, но то что Wiring Ардуиновский медленный — это уже даже
баянне новость. Там ведь куча проверок с защитой отдуракановичка, которые тратят на себя драгоценные такты. Хочется скорости — Wiring в мусорку и вперёд. Он ведь именно на простоту рассчитан.
VioletGiraffe
04.09.2018 12:27Не понимаю, почему нельзя
PORTA=value
завернуть в макрос, который под каждую платформу будет правильно реализован?iig
04.09.2018 13:59Кроме портов, в нутре контроллера есть еще много платформозависимого. Заворачивать все в правильно портируемые макросы… В результате будет еще одно arduino, только на макросах.
ZEN_LS Автор
04.09.2018 14:01Долго, дорого, лань, почти в каждом avr разные названия регистров, а если присмотрется то ардуинок в сотни раз меньше чем мег.
d_nine
04.09.2018 16:32Я вот честно вообще не понимаю таких заявлений, что дуина медленная. Там те же самые AVR и т.п. и естественно, если хотите выжать максимум, то все упирается в: тактирующий резонатор — это раз, в необходимое количество тактов на команду — это два и минимум мусора в коде — три. Берете АСМ и выжимаете максимум. Просто надо понимать, что есть задачи которые решаются на 51-й серии, а есть требующие серьезных ARM.
З.ы. да я тот динозавр 25 Голиков пишушиший на АСМ(d_nine
04.09.2018 16:4225 годиков пишущий на АСМ* (верните смартфоны с физической клавиатурой)
IvanKor2017
04.09.2018 20:48а смысл этого извращения? «C» с включенной оптимизацией все равно напишет лучше в том же ASM :D
d_nine
04.09.2018 21:04Ну насчёт лучше, это скорее всего нет, а вот то, что 90+% кода совпадет по итогу — реально. Просто мне, как инженеру АСМ ближе. Естественно речь не об ARM, там С и только местами АСМ.
shiru8bit
04.09.2018 21:41На Arduino в time critical задачах компилятор лучше не напишет, 100%. Хотя я регулярно встречаю в среде Arduino'щиков людей, без тени сомнения утверждающих, что напишет, но без примеров. Видимо была какая-то 'авторитетная' статья.
IvanKor2017
04.09.2018 22:15я вообще то начинал в 1975 году с фортрана, и с тех пор непрерывно пишу на всяких всячинах, и проверял многократно самолично. Что может быть проще, получаеш asm с С и пытаешся его улучшить. На DE0-Nano-SoC последний раз проверял.
В этом году и на arduino попробывал, понравилось, очень удобно без напряга извилин, правда все же свалил на на stm32duino, там уже привычный бардак и мрак :Dshiru8bit
04.09.2018 22:21Не надо пытаться улучшить ассемблерный выхлоп компилятора. Разумеется, это тупиковый путь. Надо писать решение на ассемблере изначально, тогда будет заметная выгода.
ZEN_LS Автор
04.09.2018 23:30-1При выигрыше в производительности кода в 10%, проигрываем в производительности программиста в 1000% — отличный результат.
shiru8bit
04.09.2018 23:40Это совершенно случайные цифры, взятые с неизвестно какого потолка, с единственной целью доказать свою (оп)позицию. Они не имеют ничего общего с действительностью. Обратите внимание, это свойственно всей аргументации 'компилятор пишет лучше программиста'.
Переписать критичный ко времени участок кода на ассемблер (обычно внутренний цикл в тяжёлых вычислениях или небольшой обработчик прерывания) — недолго и ничем не сложнее написания реализации на C. Выигрыш измеряется не в процентах, а в решении задачи. Код не успевает — задача не решена (надо менять платформу и т.д.). Код успевает — задача решена. Решение задачи вполне стоит лишнего часа-двух работы.ZEN_LS Автор
05.09.2018 17:39Эх, на ходу меняем мнение.
Надо писать решение на ассемблере изначально
Речь о том что писать весь код — глупая затея. А если писать только, для улечшения производительности в отдельных местах — это и естьулучшить ассемблерный выхлоп компилятора.
Если выбирать для решения большой задачи асм, то мы лишаем себя всех луществующих сишных либ. Если задача помигать светодиодом то разницы нет, а если нужно много сенсоров + обработка информации + цветной дисплей к этому всему, не думаю что это пару часов.shiru8bit
05.09.2018 18:03Я полагаю, что тут собрались опытные люди, понимающие, что в контексте time critical 'решение' — это именно time critical часть, а не весь проект. Очевидно же, что это не имеет никакого смысла, писать некритичный код вручную.
Я также полагаю, что это очевидно для опытных embedded программистов — ничего общего между написанием (критичного ко времени исполнения фрагмента!) кода на ассемблере и оптимизацией ассемблерного выхода компилятора ЯВУ нет. Компилятор понятия не имеет, какая задача решается, он предлагает просто рабочее решение в рамках формальной логики, и потом оптимизатор его оптимизирует на микроуровне. Но это решение изначально неоптимально. Когда человек делает то же самое на ассемблере, он знает, какая задача решается, где и какие углы можно срезать, и какие параметры в решении ему важнее.
Mike_soft
05.09.2018 05:00Дуйня-это не только AVR. Это и ядро, и IDE, и библиотеки, и сообщество — именно то, что обеспечивает начинающим лёгкий старт. Вы предлагаете оставить от дуйни лишь формфактор.
d_nine
05.09.2018 20:55Речь-то немного не про то. Просто заявление «дуина медленная» не совсем корректно, ибо медленным является именно код с использованием дуиновских средств разработки. И это нужно держать в уме. Ну и если не хочется отказываться от удобства дуины — паяльник в помощь =)
Mike_soft
06.09.2018 07:35да как раз про то. дуина — компромисс, как и любая техническая система. в данном случае сильной стороной является простота и низкий порох вхождения. а платой за это — некотрый объем ядра и некоторые тормоза.
для начинающих дуйня — великолепный инструмент (хотя уже устаревший). если ее начинает не хватать — значит, ее пора выкидывать — это будет быстрее и проще, чем переписывать на ассемблере, и т.п.
путей выкидывания много — от применения вместо «классической на AVR» на STM с той же средой «дуино» (если человек не планирует заниматься разработкой более-менее профессионально или часто), до нормального проектирования нормальных устройств (если он планирует двигаться в сторону профессионализма)
dlinyj
Статья бы имела хоть какую-то ценность, хоть маломальскую, если бы автор писал на ассемблере, и отвязался от компилятора. А так, очередная поделка. Тут самое время пригласить olartamonov
Vladimir_Feschenko
Даже если на ассемблере… Можно оптимизировать даже программу в машинных кодах (сам, лично, делал чтение с дисковода на К580ВИ80 (радио 86 рк), не хватало чуть чуть, поэтому прога сама себя переписывала перед каждой операцией (так на пару тактов было быстрее). А с учётом всяких там STM32 на армовском ядре — я уже не смогу, компилятор умнее (
dlinyj
В чём принципиально тут будет разница между ассемблером и машинными кодами, кроме геммороя?
Vladimir_Feschenko
Практически ни в чём, я собственно на асме всё и делал, только в качестве данных у меня был кусочек программы, и даже после первого исполнения он не соответствовал ассемблерной мнемонике.
smart_alex
Не-не, не надо Олега, пока не начались очередные военные действия.
ZEN_LS Автор
Я не хочу вас расстраивать, но asm под avr тоже компилируется. И отвязаться от компилятора не возможно, если конечно не писать .bin в ручную.
dlinyj
Не хочу тут переходить в наезды и спор. Но у меня только один случай был, когда старинная AVR Studio некорректно ассемблеровскую мнемонику перевела в машкоды. В остальное что ассемблируешь, то и дизассемблируешь. Что не скажешь о языках высокого уровня.
Проще говоря, ассемблер — это идентично машкодам, только в языке удобном человеку.
Mike_soft
ну, первые си-компилеры тоже делали «понятно что». более того, они часто делали не исполняемый модуль, и не объектник — а ассемблерный.
но оптимизирующие компиляторы — они позволяют работать быстрее.
а с учетом того, что «железо» нынче дешево — ассемблеры пора оставить профессионалам.
dlinyj
Вам шашечки или ехать? Если рассуждать об оптимизации, то статье не хватает ассемблера.
А на счёт асма, бывают, бывают моменты когда он нужен, даже на очень шустром железе…
Mike_soft
бывают такие моменты. но это уже тема не для ардуинщиков.
Mogwaika
Ну вот как я понимаю с ws2812 на обычной ардуине без таких вставок не побаловаться, так что вполне себе тема.
ZEN_LS Автор
А можете откопать этот пример, я бы с удавольствием проверил это, на разных версиях тулчейна.
dlinyj
Это было 12-15 лет назад. Даже при желании не откопал бы.