LOGO


Давным давно наткнулся на прекрасную статью (тык) — в ней автор достаточно наглядно показал разницу между использованием ардуиновских функций и работой с регистрами. Статей, как восхваляющих ардуино, так и утверждающих, что это все несерьезно и вообще для детей, написано множество, так что не будем повторяться, а попытаемся разобраться в том, что послужило причиной для результатов, полученных автором той статьи. И, что не менее важно, подумаем что можно предпринять. Всех, кому интересно, прошу под кат.


Часть 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. Смотрим ...


Test_1


… долго. Пытаемся вспомнить, от чего зависит скорость работы контроллера — точно, частота. Смотрим в 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 раза.


Test_2


Мы не получили желаемых результатов. Да и генератор все меньше и меньше напоминает меандр. Думаем дальше — теперь, наверное, язык плохой. Вроде как есть с, с++, но это сложно(в соответствии с эффектом Даннинга-Крюгера мы не можем осознать что уже пишем на с++), потому ищем альтернативы. Недолгие поиски приводят нас к BASCOM-AVR (тут неплохо про него рассказано), ставим, пишем код:


$Regfile="m328pdef.dat"
$Crystal=16000000
Config Portb.5 = Output

Do
Toggle Portb.5
Loop

Получаем:


Test_3


Результат намного лучше, к тому же получился идеальный меандр, но… бейсик в 2018м, серьезно? Пожалуй, оставим это в прошлом.


Часть 2 "Ответы"


Кажется, уже пора переставать валять дурака и начинать разбираться (а также вспомнить си и ассемблер). Просто скопируем "полезный" код из статьи, упоминавшейся в начале, в loop().


Здесь, полагаю, нужно пояснение: весь код будет писаться в проекте ардуино, но в среде Atmel Studio 7.0 (там удобный дизассемблер), скрины будут из неё же.


void setup() {
  DDRB |= (1 << 5);   // PB5
}

void loop() {
  PORTB &= ~(1 << 5); //OFF
  PORTB |= (1 << 5);  //ON
}

результат:


Test_4


Вот оно! Почти то, что нужно. Только форма не особо на меандр похожа и частота, хоть и уже ближе, но все равно не та. Также попробуем увеличить масштаб и обнаружим разрывы в сигнале каждую миллисекунду.


Test_5


Связано это со срабатыванием прерываний от таймера, отвечающего за 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
  }
}

Test_6


61 ns это максимум, соответствующий частоте работы контроллера. А можно ли быстрее? Спойлер — нет. Давайте попробуем понять почему — для этого дизасемблим наш код:


Code_asm_1


Как видно из скрина, для того чтобы записать в порт 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
  }
}

Test_end


Часть 3 "Выводы"


К сожалению, все что мы делали абсолютно бесполезно с практической точки зрения, потому что мы не можем больше исполнять никакой код. Так же в 99,9% случаев частот переключения портов вполне хватает для любых целей. Да и если нам очень нужно генерировать ровный меандр, можно взять stm32 с dma или внешнюю микросхему таймера вроде NE555. Данная статья полезна для понимания устройства работы mega328p и arduino в целом.


Тем не менее запись в регистры 8ми битных значений PORTB = 0b11111111; намного быстрее чем digitalWrite(13, 1); но за это придется заплатить невозможностью переноса кода на другие платы, потому что названия регистров могут отличатся.


Остался лишь один вопрос: почему использование более быстрых камней не дало результатов? Ответ очень прост — в сложных системах частота gpio ниже чем частота ядра. А вот насколько ниже и как её выставить всегда можно посмотреть в даташите на конкретный контроллер.


В публикации ссылался на статьи:



Комментарии (86)


  1. dlinyj
    03.09.2018 17:31
    -1

    Статья бы имела хоть какую-то ценность, хоть маломальскую, если бы автор писал на ассемблере, и отвязался от компилятора. А так, очередная поделка. Тут самое время пригласить olartamonov


    1. Vladimir_Feschenko
      03.09.2018 17:52
      -1

      Даже если на ассемблере… Можно оптимизировать даже программу в машинных кодах (сам, лично, делал чтение с дисковода на К580ВИ80 (радио 86 рк), не хватало чуть чуть, поэтому прога сама себя переписывала перед каждой операцией (так на пару тактов было быстрее). А с учётом всяких там STM32 на армовском ядре — я уже не смогу, компилятор умнее (


      1. dlinyj
        03.09.2018 17:54

        В чём принципиально тут будет разница между ассемблером и машинными кодами, кроме геммороя?


        1. Vladimir_Feschenko
          03.09.2018 18:19

          Практически ни в чём, я собственно на асме всё и делал, только в качестве данных у меня был кусочек программы, и даже после первого исполнения он не соответствовал ассемблерной мнемонике.


    1. smart_alex
      03.09.2018 19:06
      +2

      Не-не, не надо Олега, пока не начались очередные военные действия.


    1. ZEN_LS Автор
      04.09.2018 06:32

      Я не хочу вас расстраивать, но asm под avr тоже компилируется. И отвязаться от компилятора не возможно, если конечно не писать .bin в ручную.


      1. dlinyj
        04.09.2018 12:23
        +1

        Не хочу тут переходить в наезды и спор. Но у меня только один случай был, когда старинная AVR Studio некорректно ассемблеровскую мнемонику перевела в машкоды. В остальное что ассемблируешь, то и дизассемблируешь. Что не скажешь о языках высокого уровня.

        Проще говоря, ассемблер — это идентично машкодам, только в языке удобном человеку.


        1. Mike_soft
          04.09.2018 12:32

          ассемблер — это идентично машкодам
          сначала так. потом хочется локальных меток и макровычислений. потом — полноценных макроподстановок/препроцессора… а там уже и до хотения ЯВУ недалеко.
          ну, первые си-компилеры тоже делали «понятно что». более того, они часто делали не исполняемый модуль, и не объектник — а ассемблерный.
          но оптимизирующие компиляторы — они позволяют работать быстрее.
          а с учетом того, что «железо» нынче дешево — ассемблеры пора оставить профессионалам.


          1. dlinyj
            04.09.2018 12:33

            Вам шашечки или ехать? Если рассуждать об оптимизации, то статье не хватает ассемблера.

            А на счёт асма, бывают, бывают моменты когда он нужен, даже на очень шустром железе…


            1. Mike_soft
              04.09.2018 12:43

              бывают такие моменты. но это уже тема не для ардуинщиков.


              1. Mogwaika
                05.09.2018 18:16

                Ну вот как я понимаю с ws2812 на обычной ардуине без таких вставок не побаловаться, так что вполне себе тема.


        1. ZEN_LS Автор
          04.09.2018 14:06

          А можете откопать этот пример, я бы с удавольствием проверил это, на разных версиях тулчейна.


          1. dlinyj
            04.09.2018 14:24

            Это было 12-15 лет назад. Даже при желании не откопал бы.


  1. koldyr
    03.09.2018 17:39

    Можно быстрее. Запрещяете прерывания и пишите через всю память порт 0, порт 1. Счетчик команд циклический, а порт, если мне не изменяет память, по умолчанию — out. получаете меандр на половине тактовой частоты.


    1. ZEN_LS Автор
      04.09.2018 14:08

      Скорее всего не прокатит, счетчик команд (на сколько я помню) 16 битный, а размер памяти произвольный, поэтому он пойдет вперед когда память уже кончится. Также память нужна для кучи и стека.


      1. koldyr
        04.09.2018 20:25

        Счетчик 16 битный, но применяется по модулю размера памяти команд.
        Память команд и память данных у авра разные.
        И до кучи — нету на голом железе ни кучи ни стека.


        1. Ryppka
          04.09.2018 21:29

          Ну кучи нет — понятно. Но вот стека нет…


  1. technomancer
    03.09.2018 17:51
    +1

    Пришло время, когда люди на C пишут грамотнее, чем на русском. Не о таком киберпанке я мечтал. :-(
    Часто «для переноса кода на другие платы» аппаратно-зависимые вещи выделяют в отдельные (условно — «низкоуровневые») блоки, которые правят под конкретное железо. А «логика» портируется без изменений.


    1. Vladimir_Feschenko
      03.09.2018 17:54

      А о каком?


  1. smart_alex
    03.09.2018 19:06

    Хотелось бы отделить мух от котлет. Для 99% типичных задач, которые решаются на Ардуино, нет абсолютно никакой разницы с какой скоростью работает digitalWrite. А для тех задач, где принципиальна скорость — используем соответствующие решения — ассемблерные вставки, прямое программирование портов, мощные контроллеры или вообще уходим от парадигмы Ардуино и используем «профессиональные» решения.

    Не нужно создавать проблемы на ровном месте и противопоставлять Ардуино и «взрослые» решения.


    1. Vladimir_Feschenko
      03.09.2018 19:31

      всё верно, если 99% задач — помигать светодиодом.


      1. Mike_soft
        03.09.2018 20:16
        +2

        вентилятор, вентилятор в туалете забыли!!!


        1. Zombieff
          04.09.2018 13:04

          Если в туалете включён свет, и с мобильника по вайфаю пошёл трафик на хабр/реддит, то включаем вентилятор?

          Вот он, умный дом.


          1. IvanKor2017
            05.09.2018 16:49

            я пошел дальше :D
            сделал на arduine geomagnetic magnetometer
            github.com/IvanKor/geomagnetic-magnetometer
            который круче (полоса пропускания шире более чем в три раза ) чем используется здесь
            geodata.izmiran.ru


    1. Mike_soft
      03.09.2018 20:19
      +1

      если нужна скорость — нужно не «ассемблерные вставки», а выкидывать ардуину…


      1. ZEN_LS Автор
        04.09.2018 06:36

        Вот, вот, это статья как-раз и нацелена на то, чтобы никто не делал такое ошибочное суждение, ибо arduino это всего лишь uart загрузчик. Никто не просит использовать её IDE и тем более arduino core.


        1. Mike_soft
          04.09.2018 06:59
          -1

          тогда от дуйни ничего и не остаётся. если выкинуть ядро — выкинешь и все наработки, всё сообщество. а в этом и есть вся ценность дуйни для начинающих. ну и сейчас, в 201х, использовать ассемблер. тем более, устаревшего железа… зачем? начинающему проще перелезть на нуклео, а грамотный и без дуйни справится


          1. KislyFan
            04.09.2018 14:09

            Сообщество avr существовало задолго до появления arduino, и скажу вам по секрету — никуда не делось. Оно всё там же (где презирают arduino и пишут на c/asm).


            1. ZEN_LS Автор
              04.09.2018 14:09

              Ещё были парни каторые писали в bascom avr, эх славные времена были.


    1. AndrewRo
      03.09.2018 21:53
      +1

      В целом, вы просто процитировали статью.


    1. FDA847
      03.09.2018 21:53

      Совершенно верно! Каждый инструмент для своих задач. На ардуине быстро и легко создавать новые проекты. Под неё вон сколько библиотек есть. Я сам за вечер сделал с нуля термометр на балкон на базе датчика DS18B20 и матричного светодиодного индикатора. При этом с ардуино ранее вообще не работал!
      Но в то же время в какое-то серийное изделие на мой взгляд ардуина не особо вписывается.


      1. Mike_soft
        04.09.2018 08:55

        ровно так же вы могли сделать это же на STM по статье olartamonov


        1. FDA847
          04.09.2018 09:01
          +1

          Ну на STM, PIC, AVR я действительно мог бы и сам сделать, потому что работаю с ними уже давно. Просто однажды мне стало интересно поиграться с ардуиной. Оказалось, что порог вхождения там очень низкий, что меня весьма порадовало. Для своего сегмента это просто отличное решение!


          1. Mike_soft
            04.09.2018 09:30

            для mbed порог вхождения не выше (ну или не сильно выше).


            1. ZEN_LS Автор
              04.09.2018 14:12

              Mbed не набор либ, а операционная система. Сказать что и как она делает почти не реально. Поэтому все используют free rtos. Вспомнил вот что по этому поводу: habr.com/post/387299


              1. Mike_soft
                04.09.2018 14:36

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


        1. IvanKor2017
          05.09.2018 16:42

          на STM в среде arduino термометр на базе датчика DS18B20
          github.com/IvanKor/DS18B20_USART_DMA_STM32
          без «ногодрыга» в режиме реалтайм за пару вечеров :D


          1. iig
            06.09.2018 10:45

            Если учесть, что нет смысла очень часто температуру мерить (если например, температура на улице — раз в полчаса выше крыши), то ардуиновский модуль с ногодрыгом за 5 минут вполне годное решение. Пару вечеров можно и на что-то другое потратить.


      1. GipsyIF
        04.09.2018 14:01

        Согласен с Вами. Самый простой и быстрый путь проверить например какой-то новый экранчик, с которым ещё не работал — это Ардуина. У неё есть библиотеки почти под все устройства.


        1. ZEN_LS Автор
          04.09.2018 14:04

          Я заметел очень класную штуку. Года 4 для меня сказанное было неоспоримой истиной, но теперь после avr, stm, длайверов под linux, для меня зайвет одинаковое количество времени написать либу под новый дисплей что под arduino, что под avr, что под linux. Но писать под avr будет намного приятнее.


    1. ZEN_LS Автор
      04.09.2018 04:08

      Проблема не в качестве решения, проблема в том что 90% ардуинщиков не понимают что они пишут. Статья для того чтобы показать что код собирается не магией, а авровским тулчейном.


  1. farcaller
    03.09.2018 19:44
    +1

    Максимальная частота анализатора 24 MHz следовательно её необходимо уравнять с частотой контроллера — выставить 16MHz

    Но зачем? Частота анализатора должна быть выше чем частота сигнала, что бы снять его точно, нет?


    1. ZEN_LS Автор
      04.09.2018 04:41

      Тут вот какое дело, если частота будет 24 Мгц, то мы не сможем нормально померить время. Полученные результаты просто не будут пропорциональны времени такта. Пример: минимальное время полученное в статье соответствует времени между 2мя измерениями анализатора и это 62,5 нс, если мы поставим 24 Мгц то анализатор успеет сделать 2 измерения и время будет 83,3 нс, что не соответствует действительности. Так что нет, частота анализатора должна быть пропорциональна частоте контроллера для получения точных результатов.


  1. SergeyMax
    03.09.2018 20:17

    Да и если нам очень нужно генерировать ровный меандр, можно взять stm32 с dma или внешнюю микросхему таймера вроде NE555.
    Скажите, а вы слышали когда-нибудь о таймерах? Говорят, они даже в ардуине есть.

    Данная статья полезна для понимания устройства работы mega328p и arduino в целом.
    Хм, не уверен.


    1. ZEN_LS Автор
      04.09.2018 04:11

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


      1. SergeyMax
        04.09.2018 08:05
        +1

        Но ведь генерация меандра таймером не занимает тактов контроллера.


        1. ZEN_LS Автор
          04.09.2018 13:58

          Если только на этом таймере висит дма, а так нужен обработчик.


          1. SergeyMax
            04.09.2018 14:59

            Если только на этом таймере висит дма, а так нужен обработчик.
            Для генерации меандра таймеру не нужен ни DMA, ни обработчик.


            1. 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


  1. 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=127


    1. ZEN_LS Автор
      04.09.2018 04:13

      Про скорость это скорее шутка, я считал что очевидно что описанное в статье не имеет отношение к производительности (в контексте математических операций).


  1. AndrewRo
    03.09.2018 22:06
    +2

    Очень полезная статья. По-моему, для новичков очень важно знать, что высокоуровневый код никогда не даст такой скорости и точности, как низкоуровневый и масштабы этого явления. От себя добавлю, что примерно то же самое происходит и с памятью кода. Когда я решил сделать один из своих проектов не на С, как обычно, а на ардуиновском диалекте, для меня было большой неожиданностью, что ATMega2560 закончилась буквально на 400 строке. Насколько я понимаю, особенно прожорлива местная объектная модель.


    1. smart_alex
      04.09.2018 06:37

      Хочу заметить, что практическая полезность определяется не абстрактными «скоростью и точностью» (которые нужны только на специфических задачах), а решением насущных проблем, с которыми Ардуино справляется на ура (и тут её популярность говорит сама за себя).

      Что касается памяти, то её тоже «нужно уметь готовить» — на Меге в Ардуино нет никаких проблем с объёмными (как по оперативной, так и по флеш памяти) проектами. Чужие библиотеки действительно могут очень вольно обращаться с памятью, но это скорее проблема не объектной модели программирования, а уровня знаний и прилежания самого автора библиотеки.


    1. Mike_soft
      04.09.2018 07:25

      все нормальные люди знают, что низкоуровневый код [для всех систем] работает быстрее, но пишется дольше и сложнее. и наоборот. и что ЯВУ разменивают скорость разработки на скорость работы. людям, которым для осознания этого требуется статья — она уже не поможет.


      1. Hardcoin
        04.09.2018 09:31

        Они это знают с рождения? Или узнают в какой-то момент? Откуда?


        1. Mike_soft
          04.09.2018 09:44

          когда начинают читать про «процессоры, контроллеры...». некоторым это рассказывают в школах на уроках информатики.


  1. mksma
    03.09.2018 22:33

    Кажется можно сделать быстрее если вместо присвоения использовать xor на соответствующем бите порта B. При этом в идеале загрузить битовую маску в регистр нужно 1 раз, до начала цикла.


    1. ZEN_LS Автор
      04.09.2018 04:16

      Присвоение — один такт, по сути запись из регистра в порт, проводить xor и потом писать значение в порт как минимум 2 такта.


  1. HWman
    04.09.2018 08:40

    Спасибо за статью и за упоминание.


  1. gerasimenkoao
    04.09.2018 11:03

    С первой публикацией на хабре!


    Все конечно хорошо, но саму платформу arduino(как и любых других МК) рассматриваю как утилитарную вещь для решения определенных прикладных задач, пускай уже и тысячу раз реализованных.


    Поэтому за парктроник, пускай и на столе работающий — проголосовал, а за сферический blink в вакууме — увы — нет.


    Вот если с помощью ардуино квадрокоптеры сбивать, да хоть пуляя микроконтроллерами из рогатки — это был-бы FUN ;-)


    1. Mike_soft
      04.09.2018 11:21

      сын делал в 8 классе на конкурс по робототехнике стрелялку по вертолету. как раз на ардуине. сам спаял ее из фридуиновского набора.
      точность невелика — но довольно эффектно. но как раз перед демонстрацией сгорела катушка соленоида «электоспуска». было обидно.


    1. Peacemaker
      04.09.2018 11:48

      Вот если с помощью ардуино квадрокоптеры сбивать

      Думал над концепцией такого обвеса для автоматического оружия, которое позволит определять лазерным дальномером дистанцию до дрона, и имея прошитые данные по баллистике применяемого боеприпаса, а также данные с сенсоров температуры, давления и силы ветра (опционально) находить и показывать бойцу, в какое положение необходимо поставить оружие для максимальной вероятности поражения коптера. Такой себе баллистический компьютер для бедных.


      1. iig
        04.09.2018 12:03

        Добавить сервомоторы, турель… Человек тут лишний, пулять в зенит из ручного оружия очень неудобно, а роботу все равно.


  1. assad77
    04.09.2018 11:19

    видел подобное 4 года назад здесь


  1. IGR2014
    04.09.2018 12:15

    Простите, но то что Wiring Ардуиновский медленный — это уже даже баян не новость. Там ведь куча проверок с защитой от дурака новичка, которые тратят на себя драгоценные такты. Хочется скорости — Wiring в мусорку и вперёд. Он ведь именно на простоту рассчитан.


  1. VioletGiraffe
    04.09.2018 12:27

    Не понимаю, почему нельзя PORTA=value завернуть в макрос, который под каждую платформу будет правильно реализован?


    1. iig
      04.09.2018 13:59

      Кроме портов, в нутре контроллера есть еще много платформозависимого. Заворачивать все в правильно портируемые макросы… В результате будет еще одно arduino, только на макросах.


    1. ZEN_LS Автор
      04.09.2018 14:01

      Долго, дорого, лань, почти в каждом avr разные названия регистров, а если присмотрется то ардуинок в сотни раз меньше чем мег.


  1. d_nine
    04.09.2018 16:32

    Я вот честно вообще не понимаю таких заявлений, что дуина медленная. Там те же самые AVR и т.п. и естественно, если хотите выжать максимум, то все упирается в: тактирующий резонатор — это раз, в необходимое количество тактов на команду — это два и минимум мусора в коде — три. Берете АСМ и выжимаете максимум. Просто надо понимать, что есть задачи которые решаются на 51-й серии, а есть требующие серьезных ARM.

    З.ы. да я тот динозавр 25 Голиков пишушиший на АСМ(


    1. d_nine
      04.09.2018 16:42

      25 годиков пишущий на АСМ* (верните смартфоны с физической клавиатурой)


      1. IvanKor2017
        04.09.2018 20:48

        а смысл этого извращения? «C» с включенной оптимизацией все равно напишет лучше в том же ASM :D


        1. d_nine
          04.09.2018 21:04

          Ну насчёт лучше, это скорее всего нет, а вот то, что 90+% кода совпадет по итогу — реально. Просто мне, как инженеру АСМ ближе. Естественно речь не об ARM, там С и только местами АСМ.


        1. shiru8bit
          04.09.2018 21:41

          На Arduino в time critical задачах компилятор лучше не напишет, 100%. Хотя я регулярно встречаю в среде Arduino'щиков людей, без тени сомнения утверждающих, что напишет, но без примеров. Видимо была какая-то 'авторитетная' статья.


          1. IvanKor2017
            04.09.2018 22:15

            я вообще то начинал в 1975 году с фортрана, и с тех пор непрерывно пишу на всяких всячинах, и проверял многократно самолично. Что может быть проще, получаеш asm с С и пытаешся его улучшить. На DE0-Nano-SoC последний раз проверял.
            В этом году и на arduino попробывал, понравилось, очень удобно без напряга извилин, правда все же свалил на на stm32duino, там уже привычный бардак и мрак :D


            1. shiru8bit
              04.09.2018 22:21

              Не надо пытаться улучшить ассемблерный выхлоп компилятора. Разумеется, это тупиковый путь. Надо писать решение на ассемблере изначально, тогда будет заметная выгода.


              1. ZEN_LS Автор
                04.09.2018 23:30
                -1

                При выигрыше в производительности кода в 10%, проигрываем в производительности программиста в 1000% — отличный результат.


                1. shiru8bit
                  04.09.2018 23:40

                  Это совершенно случайные цифры, взятые с неизвестно какого потолка, с единственной целью доказать свою (оп)позицию. Они не имеют ничего общего с действительностью. Обратите внимание, это свойственно всей аргументации 'компилятор пишет лучше программиста'.

                  Переписать критичный ко времени участок кода на ассемблер (обычно внутренний цикл в тяжёлых вычислениях или небольшой обработчик прерывания) — недолго и ничем не сложнее написания реализации на C. Выигрыш измеряется не в процентах, а в решении задачи. Код не успевает — задача не решена (надо менять платформу и т.д.). Код успевает — задача решена. Решение задачи вполне стоит лишнего часа-двух работы.


                  1. ZEN_LS Автор
                    05.09.2018 17:39

                    Эх, на ходу меняем мнение.

                    Надо писать решение на ассемблере изначально
                    Речь о том что писать весь код — глупая затея. А если писать только, для улечшения производительности в отдельных местах — это и есть
                    улучшить ассемблерный выхлоп компилятора.
                    Если выбирать для решения большой задачи асм, то мы лишаем себя всех луществующих сишных либ. Если задача помигать светодиодом то разницы нет, а если нужно много сенсоров + обработка информации + цветной дисплей к этому всему, не думаю что это пару часов.


                    1. shiru8bit
                      05.09.2018 18:03

                      Я полагаю, что тут собрались опытные люди, понимающие, что в контексте time critical 'решение' — это именно time critical часть, а не весь проект. Очевидно же, что это не имеет никакого смысла, писать некритичный код вручную.

                      Я также полагаю, что это очевидно для опытных embedded программистов — ничего общего между написанием (критичного ко времени исполнения фрагмента!) кода на ассемблере и оптимизацией ассемблерного выхода компилятора ЯВУ нет. Компилятор понятия не имеет, какая задача решается, он предлагает просто рабочее решение в рамках формальной логики, и потом оптимизатор его оптимизирует на микроуровне. Но это решение изначально неоптимально. Когда человек делает то же самое на ассемблере, он знает, какая задача решается, где и какие углы можно срезать, и какие параметры в решении ему важнее.


    1. Mike_soft
      05.09.2018 05:00

      Дуйня-это не только AVR. Это и ядро, и IDE, и библиотеки, и сообщество — именно то, что обеспечивает начинающим лёгкий старт. Вы предлагаете оставить от дуйни лишь формфактор.


      1. d_nine
        05.09.2018 20:55

        Речь-то немного не про то. Просто заявление «дуина медленная» не совсем корректно, ибо медленным является именно код с использованием дуиновских средств разработки. И это нужно держать в уме. Ну и если не хочется отказываться от удобства дуины — паяльник в помощь =)


        1. Mike_soft
          06.09.2018 07:35

          да как раз про то. дуина — компромисс, как и любая техническая система. в данном случае сильной стороной является простота и низкий порох вхождения. а платой за это — некотрый объем ядра и некоторые тормоза.
          для начинающих дуйня — великолепный инструмент (хотя уже устаревший). если ее начинает не хватать — значит, ее пора выкидывать — это будет быстрее и проще, чем переписывать на ассемблере, и т.п.
          путей выкидывания много — от применения вместо «классической на AVR» на STM с той же средой «дуино» (если человек не планирует заниматься разработкой более-менее профессионально или часто), до нормального проектирования нормальных устройств (если он планирует двигаться в сторону профессионализма)