Многозадачность на Arduino

Тема в разделе "Arduino & Shields", создана пользователем ImrDuke, 19 дек 2016.

  1. UserDefUno

    UserDefUno Нерд

    Эм? Многозадачности все равно не добиться, в плане тут код будет все равно выполняться в 1 поток просто выполнение будет асинхронно, да и за потоки отвечает ОС. Если речь о потоках.
     
  2. ostrov

    ostrov Гуру

    Вот пример как можно просто организовать работу нескольких функций с разными интервалами. А так же легко менять эти самые интервалы. Разумеется, функций может быть великое множество. Я считаю очень удобно для некоторых случаев, например когда функций много. Для двух - трех функций проще все сделать классически.

    Код (C++):
    unsigned long timerUp[5];                               // массив таймеров
    unsigned int intUp[5] = {500, 1000, 1500, 2500, 5000};  // массив интервалов (значения можно менять в любой момент)


    // пример функций выполняемых через заданные интервалы
    void pr1 () {
      Serial.println("1");
    }
    void pr2 () {
      Serial.println(" 2");
    }
    void pr3 () {
      Serial.println("  3");
    }
    void pr4 () {
      Serial.println("    4");
    }
    void pr5 () {
      Serial.println("       5");
    }


    // массив указателей на функции
    void (*fun[5])() = {pr1, pr2, pr3, pr4, pr5};


    void setup() {
      Serial.begin(9600);
    }

    void loop() {
      prUpdate();                             // постоянный опрос таймеров
      intUp[0] = (millis() % 100) * 100;      // интервал функции pr1 меняется от 0 до 10000мс
    }


    void prUpdate () {                        // проверяем не пришла ли пора дергать ту или иную функцию
      for (byte i = 0; i < 5; i++) {
        if (timerUp[i] < millis()) {
          fun[i]();                           // дергаем если пришла
          timerUp[i] = millis() + intUp[i];   // заряжаем таймер
        }
      }
    }
    Само собой и это не многозадачность. Если в какой либо функции что то зависнет, то встанет вся программа. Настоящая многозадачность только через прерывания по таймеру. Тут уже поднимали тему.
     
    Последнее редактирование: 20 дек 2016
  3. qwone

    qwone Гик

    Не существует "настоящей" многозадачности. Ну разве что на отдельных компьютерах. Да же если организуете прерывание по таймеру, то всегда найдется способ завалить работу всей системы. Возьмите дорогу и много машин. Если все соблюдают правила, то все всегда приедут куда надо без опазданий. Но если найдется "мажор", которому ну очень надо, то он всегда может создать своими дейсвиями пробку на дороге. Да можно для таких выделить новую дорогу. Но и там им места будет мало, не считая что будет затрачено очень много ресурсов на дополнительную дорогу. Так что лучшее решение избавляться от таких "мажоров" на дороге. А применительно к программированию. То не пишите процессов, которые могут стопорнуть всю систему, как бы эффективно они выглядели.Они эффективны только за счет других В целом эта эффективность ведет к ущербу всей системы в целом.
     
  4. rkit

    rkit Гуру

    Почти все тут путают многозадачность и параллельные вычисления.
    Кооперативная многозадачность на ардуино реализуется на раз-два.
     
  5. ostrov

    ostrov Гуру

    По слухам они есть. Но вот те из готовых, что я протестировал, на этот статус не тянут. Например LeOS и leOS2 по сути представляют собой легкую инициализацию таймера прерываний. Задали периоды, привязали к ним функции и погнали. Более серьезная FreeRTOS на первый взгляд очень наворочена, да и места занимает четверть памяти у Атмеги328. Но увы и та и другая безнадежно зависают если в любом из потоков написать банальное while(1); а это значит, что грош цена таким операционкам - завис один поток, встало всё.
     
    Igor68 нравится это.
  6. ostrov

    ostrov Гуру

    Вот именно, а вытесняющая многозадачность уже на раз-два-три-четыре- и так фиг знает куда.
     
  7. Igor68

    Igor68 Гуру

    Для ухода от таких косяков - применять процессор с режимом MASTER(SUPERUSER) и USER, когда потоки в режиме USER и совсем напрямую не имеют доступ к железу... да и ко всей памяти тоже... а только через системные вызовы...
    Что верно... то верно! Но это уже не для AVR/