Добрый день! Хотелось бы поговорить на тему архитектуры embedded приложений. К сожалению, книг по этой теме очень мало, а в связи с тем, что, в последнее время, интерес к embedded и IoT растет, хочется уделить внимание этому вопросу. В этой статье, я бы хотел описать один из возможных вариантов того, как можно проектировать такие приложения.

Вопрос этот дискуссионный! Поэтому предлагают поделиться своим виденьем в комментариях!
Для начала определимся с областью: в рамках данной статьи, под embedded разработкой будем понимать разработку ПО под микроконтроллеры (далее МК, напр. STM32) на языке C / Asm.
Проекты для систем на базе МК условно можно разделить на не требующие и требующие многозадачности. Что касается решений первого типа, они, как правило, не очень сложные (со структурной точки зрения). Например, простой проект, в рамках которого необходимо считывать данные с датчика и показывать их на экране, не требует многозадачности, здесь достаточно реализовать последовательное выполнение перечисленных операций.



Если же приложение более сложное: в рамках которого необходимо считывать данные как с цифровых датчиков, так и с аналоговых, сохранять полученные значения в память (например, на sd-карту), обслуживать пользовательский интерфейс (дисплей + клавиатура), предоставлять доступ к данным через цифровой интерфейс (например, RS-485 / Modbus или Ethernet / TCP/IP) и максимально быстро реагировать на определенные события в системе (нажатие аварийных кнопок и т.п.), то в этом случае будет тяжело обойтись без многозадачности. Существует два способа решения вопроса многозадачности: реализовывать ее самому, либо воспользоваться какой-то операционной системой (далее ОС). На сегодняшний день, одной из самых популярных ОС реального времени для встраиваемых систем является FreeRTOS.

Попробуем представить, как должна выглядеть архитектура “сложного” embedded приложения, выполняющего достаточно большое количество разнородных операций. Я допускаю, что можно предложить еще более сложный вариант, который предполагает решение вопросов обработки звука, криптографию и т.п., но остановимся на варианте, который был описан чуть выше.

Поставим задачу более четко, пусть в рамках нашего приложения необходимо:

  • Считывать данные с датчиков на шине RS-485/Modbus.
  • Считывать данные с датчиков на шине I2C.
  • Считывать данные с дискретных входов.
  • Управлять релейным выходом.
  • Обслуживать пользовательский интерфейс (дисплей + клавиатура).
  • Предоставлять доступ к данным по шине RS-485/Modbus.
  • Сохранять данные на внешний носитель.

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

Если проанализировать задачу, то можно увидеть, что разные компоненты системы используют одни и те же данные. Например: данные с датчиков необходимо получить, отобразить на экране, записать на носитель и предоставить внешним системам для считывания. Это наводит на мысль, что нужна какая-то база данных реального времени (RTDB) для хранения и для предоставления самых актуальных данных различным подсистемам.

Задачи, выполняющиеся в системе (считывание данных, запись, отображение и т.п.), могут иметь различные требования к частоте их вызова. Нет смысла обновлять данные на дисплее с частотой 1 раз в 100 мс, т.к. для человека это не критично, а вот считывать данные с датчиков (особенно, если необходимо выдавать по ним управляющие воздействия) нужно часто (хотя в зависимости от ТЗ может и нет). Еще один важный момент связан с решением задачи доступа к одним и тем же данным на чтение и запись. Например: поток, опрашивающий датчики записывает полученные значения в RTDB, а в этот момент поток, отвечающий за обновление информации на дисплее, их считывает. Здесь нам помогут механизмы синхронизации, которые предоставляет операционная система.

Начнем проектировать архитектуру нашего приложения!

База данных реального времени




В качестве такой базы может выступать обычная структура, содержащая необходимый набор полей или массив. Для доступа к “RTDB” будем использовать API, который позволит записывать и считывать данные из базы. Синхронизацию доступа к данным внутри функций API можно построить на мьютексах, предоставляемых ОС (либо использовать какой-то другой механизм).



Работа с датчиками на шинах


Работа с датчиками предполагает следующее:

  • считывание данных;
  • обработка данных (если это необходимо), которая включает:
    • проверку на достоверность;
    • масштабирование;
    • фильтрацию;
    • проверку на допустимые значения;

  • запись полученных данных в RTDB.

Всю эту работу можно сделать в рамках одной задачи.



“Port” — реальный порт МК;
“Protocol driver” — драйвер протокола (например, Modbus). К такому драйверу желательно сделать свой интерфейс и работать через него. В рамках такого интерфейса можно реализовать управление доступом к ресурсу через мьютексы, так как это было сделано для “RTDB”. Некоторые разработчики предлагают это делать на уровне порта, чтобы быть уверенным в том, что никто другой в этот порт записывать ничего не будет, пока мы через него передаем свои Modbus пакеты.
“Sensor reader” — задача (task), которая опрашивает датчики, приводит в порядок полученную информацию и записывает ее в ”RTDB”.

“RTDB” — база данных реального времени, описанная выше, в соответствующем разделе.
Надпись “Pr: 1” над задачей означает приоритет, суть в том, что у каждой задачи может быть приоритет, если у двух задач, ожидающих процессорное время, разный приоритет, ресурс получит та, у которой приоритет выше. Если у задач приоритет одинаковый, то запустится та, у которой дольше время ожидания.

Работа с дискретными входами


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



Помимо быстрого срабатывания на изменение состояния конкретного входа, дополнительно можно поставить задачу “DI reader” для считывания состояния дискретных входов. Эта задача может быть как самостоятельной, так и вызываться по таймеру.

Работа “Interrupt handler’а” и “Relay controller’а” в виде диаграмм представлена ниже.



Запись данных на внешний носитель


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



Мы читаем из “RTDB” и записываем через “Store driver” во внешний носитель — это может быть SD карта, USB-флешка или что-нибудь ещё. Опять-таки, не забываем в функции интерфейса помещать мьютекс-обертки (или какие-либо другие инструменты для организации доступа к ресурсу)!

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


Важным является момент предоставления данных из “RTDB” для внешних систем. Это могут быть практически любые интерфейсы и протоколы. В отличии от ряда рассмотренных подсистем, ключевым отличием этой является то, что некоторые из протоколов, широко применяемых в системах автоматизации, предъявляют особые требования ко времени ответа на запрос, если ответ не приходит в течении определенного времени, то считается, что с данным устройством нет связи, даже если он (ответ) придет через некоторое время. А т.к. доступ к “RTDB” в нашем примере может быть временно заблокирован (по мьютексу) необходимо предусмотреть защиту внешнего master-устройства (master — это устройство, которое пытается прочитать данные из нашего) от такой блокировки. Также стоит предусмотреть защиту самого устройства от того, что master будет опрашивать его с большой частотой, тем самым тормозя работу системы постоянным чтением из ”RTDB”. Один из вариантов решения — это использовать промежуточный буфер.



“Data updater” читает данные из “RTDB” с заданной периодичностью и складывает, то, что прочитал в “Protocol cache”, из которого “Protocol handler” будет данные забирать. В данном случае возникает проблема блокировки на уровне протокольного кэша, для ее решения можно завести ещё один кэш, в котором “Protocol handler” будет хранить данные на случай, если не смог прочитать из заблокированного “Protocol cache”, дополнительно можно:
— сделать для “Protocol handler” более высокий приоритет;
— увеличить период чтения из “RTDB” для “Data updater” (что так себе решение).

Работа с пользовательским интерфейсом


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



UI worker занимается тем, что считывает нажатия клавиш, забирает данные из “RTDB” и обновляет дисплей, который видит пользователь.

Общая структура системы


Теперь взглянем на то, что получилось в итоге.



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

P.S.
В качестве литературы я бы посоветовал “Making Embedded Systems: Design Patterns for Great Software” Elecia White и статьи Андрея Курница “FreeRTOS — операционная система для микроконтроллеров”

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


  1. kababok
    09.08.2018 13:38

    Хм, а вы какими иностранными языками владеете?

    Т.к., например, на немецком, архитектура часто применительно к конкретной практической области рассматривается.

    Ну, и англоязычная литература широка и глубока. :)


  1. AssMoFun
    09.08.2018 13:42

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

    Может поменять местами?


    1. marat_ab Автор
      09.08.2018 14:12

      Спасибо! Поменял)


  1. Keroro
    09.08.2018 13:58

    Архитектура — это конечно хорошо, но хотелось бы немного конкретики. Что такое, к примеру, эта самая RTDB? Может быть у автора есть пример реализации подобной БД, применительно к миру МК?


    1. Makc_K
      09.08.2018 14:06

      Как я понял из статьи — это организация хранения каких-либо данных в оперативной памяти, например — структура или массив (или массив структур).


    1. marat_ab Автор
      09.08.2018 14:36

      Случайно ответил отдельной веткой, смотрите ниже))


  1. marat_ab Автор
    09.08.2018 14:35

    Самый простой вариант.
    Cоздаем массив, например такой:

    int16_t rtdb[5];

    Но работаем с ним только через функции, например так:
    void write_rtdb(int16_t* data)
    {
      if(xSemaphoreTake(mutex_name, (TickType_t)portMAX_DELAY))
      {
        for(uint8_t i = 0; i < 5; i++)
        {
          rtdb[i] = data[i];
        }    
        xSemaphoreGive(mutex_name);    
      }
    }

    Пара моментов:
    — в примере, для синхронизации доступа используется мьютекс из FreeRTOS;
    — функция чтения тоже должна использовать тот же мьютекс;
    — работу с данными можно сделать более оптимально, если это критично.


  1. SadAngel
    09.08.2018 14:59
    +1

    Elecia White также записывает подкасты по Embedded: www.embedded.fm


    1. marat_ab Автор
      09.08.2018 15:10

      Не знал! Спасибо огромное!!!


    1. Punk_Joker
      09.08.2018 16:10

      А русскоязычных подкастов но эту или родственную тематику случаем нет?


      1. SadAngel
        09.08.2018 16:45

        к сожалению, не видел.

        P.S. также интересные подкасты, но на анг: thesparkgap.net


      1. SadAngel
        09.08.2018 16:46

        Подборка подкастов по программированию на русском и английском языках:
        habr.com/post/308532


  1. I_Soba
    09.08.2018 20:05
    +1

    Всегда приятно читать статьи подобного рода, фундаментально и все по полочкам, и я уверен, найдется куча людей кому это будет полезно, но в целом я не считаю такой подход правильным и вот почему:

    Говоря о подходе, я имею ввиду выбор в пользу использование ОС на STM32 и других Cortex. Использование ОС может быть оправдано, когда количество задач переваливает за несколько сотен. И я тут говорю о более менее алгоритмически объемных задачах, а не просто записать какую-либо настройку в регистр.

    Мне сложно представить проект, где использование той же FreeRTOS обеспечит реальное преимущество в скорости и тайминге, конечно при условии должного знания архитектуры используемого процессора, языка программирования (в том числе и ассемблера) и уровне оптимизации -O3. Зато повсеместно встречаются обратные примеры, когда вся многозадачность, к примеру, заключается лишь в считывании входов (цифра), выдаче результата на выходы и передаче по какому нибудь интерфейсу, с навешанными OS и HAL, конечно же без оптимизации как таковой.

    Например, в статье описано, что на изменение состояния кнопки нужно реагировать максимально быстро. А это сколько? Даже запихнув все задачи из статьи последовательно в while(1) общее время выполнения цикла едва ли превысит несколько миллисекунд, это много меньше времени механического нажатия. На кнопку же, если это принципиально, можно просто поставить EXTI да и все.

    По базе данных реального времени. Я бы просто выделил структуру/массив, а все возможные перемещения данных повесил бы на DMA, и думать о перемещении, распределении, достоверности и целостности не приходится вообще.

    Основное заявляемое преимущество RTOS в том, что она может выполнять задачи строго нужное время по приоритетам. Но с ней код разбухает (имею ввиду количество машинных инструкций), и это теряет смысл, так как грамотно написав код напрямую, можно добиться гораздо лучших результатов вообще об этом не думая учитывая что перечисленные задачи в статье не имеют строгой привязки ко времени. Также не стоит забывать, что команды безусловных и условных переходов нарушают конвейерность процессора fetch/decrypt/execute, что при каждом вызове задачи и куче добавочных переходов в целом, превращает один такт в три.

    В общем, я считаю что гораздо профитнее курить саму архитектуру процессора и научиться грамотно использовать ее фичи. Это принесет и другие плюсы, разработка любой неизвестной ранее периферии будет все проще и быстрее, а также, вопреки расхожему мнению, будет легко перебраться, например, с STM на LPC или Infenion.

    И замечу, что я не против ОС вообще и на серьезных проектов использование ее рационально, но серьезные проекты требуют настоящих процессоров, а 99.9% того, что реализуют на МК Cortex Mx даже профессиональные разработчики, совсем не подходит под это и в частности приведенном в статье примере я не вижу оснований для использования ОС.


    1. DuMOHsmol
      09.08.2018 21:37

      Использование ОС может быть оправдано, когда количество задач переваливает за несколько сотен.

      Co FreeRTOS так точно не получится — на каждую задачу требуется относительно много ресурсов. Я бы сказал, что RTOS рулит там, где есть какие-то долгие и сложные расчёты, которые нужно прозрачно прерывать более короткими и более приоритетными задачами.


    1. marat_ab Автор
      09.08.2018 21:38

      Лично для меня, в данный момент, тема «использовать или нет RTOS» относится больше к вопросу удобства, которое я получу в итоге. Если решить задачу можно без RTOS и это будет приемлемо по срокам, сложности, требованиям по масштабируемости и времени реакции, то выбор будет в пользу этого решения.
      Написать код без RTOS, который бы учитывал приоритетность задач, синхронизировал доступ к ресурсам и т.п. можно, но это требует большего профессионализма, нежели, чем использование возможностей, предоставляемых RTOS. Конечно – это не причина, чтобы останавливаться в развитии! Но на определенном этапе может быть вынужденной необходимостью. Вряд ли с первого раза получится сделать «хорошо» без соответствующего опыта.
      По части ресурсов, насколько я понимаю, та же FreeRTOS не сильно прожорливая, планировщик, если верить статьям занимает порядка 250 байт в ОЗУ, задача — 64 байта плюс ее стэк. К тому же, мы получаем дополнительные плюшки, опять-таки, если верить интернет источникам (сам не проверял), например, работа с динамическим выделением памяти (malloc, free и т.п.): для ряда МК может вообще отсутствовать, либо быть очень громоздкой, в FreeRTOS есть функции (pvPortMalloc(),vPortFree()), которые позволяют это делать эффективно (но, как уже сказал выше, не тестировал этот момент).


      1. I_Soba
        10.08.2018 17:30

        Если решить задачу можно без RTOS и это будет приемлемо по срокам, сложности, требованиям по масштабируемости и времени реакции, то выбор будет в пользу этого решения.

        В том и суть, что распространено мнение, что FreeRTOS и ей подобные системы делают построение архитектуры системы удобнее, быстрее и проще. Но если потратить столько же времени на освоение архитектуры МК, то разница будет несущественной.

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

        Я не совсем понимаю вопрос по приоритетам. А какой смысл в вашем примере учитывать приоритет задач. Что поменяется, если при нажатии кнопки вы потратите, допустим 5 миллисекунд на уже выполняемые задачи и затем по очереди попадете в обработку кнопки?

        Но на определенном этапе может быть вынужденной необходимостью. Вряд ли с первого раза получится сделать «хорошо» без соответствующего опыта.

        Я тоже думаю, что с первого раза не получится сделать так. Но если же не начать так делать, то никогда не получится.

        По части ресурсов, насколько я понимаю, та же FreeRTOS не сильно прожорливая, планировщик, если верить статьям занимает порядка 250 байт в ОЗУ, задача — 64 байта плюс ее стэк.

        По поводу прожорливости по памяти, я сделал такой вывод, так как все проекты, что мне попадали с OS были раз как минимум раз в 15-20 больше по объему памяти. Если то, что вы написали правда, то это действительно пустяки, и этот минус я для себя снял, спасибо.


      1. I_Soba
        10.08.2018 18:17

        Почитал еще комментарии и хочу дополнить свой ответ. Я заметил, что вы смотрите на МК как на комплекс:

        мьютексов, семафоров, очередей, и обеспечивать быструю работу с динамической памятью

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


    1. Dima_Sharihin
      10.08.2018 10:09

      количество задач переваливает за несколько сотен

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


      ОС может быть оправдано, когда

      ОС оправдана, когда мы хотим развязать отдельные модули устройства, не превращая его в запутанный клубок.


      о перемещении, распределении, достоверности и целостности не приходится вообще.

      Если у вас не атомарная запись/чтение величин, то думать придется. Видите ли, даже голый МК с прерываниями — уже не "однопоточная" система. Голый МК без прерываний тоже может быть не однопоточной системой, поскольку периферия тоже умеет делать что-то сама по себе.


      с ней код разбухает

      Код вообще разбухает с повышением сложности ПО. От кооперативной многозадачности, которую часто ставят как альтернативу вытесняющей — код разбухает не меньше, а на некоторых архитектурах изобилие ветвлений (switch/case) убивает всю производительность на корню.


      перечисленные задачи в статье не имеют строгой привязки ко времени

      Потому что 90% статей по ембедедду рассматривают совершенно неправдивые примеры. RTOS применяют когда у нас есть несколько классов задач, выполнение которых явно важнее других задач. Грубо говоря, "RTOS" можно сделать на контроллере прерываний (NVIC), с включенным вытеснением прерываний. Но программная обертка над планировщиком будет поудобнее, нежели ручной контроль приоритетов и порядка выполнения.


      безусловных и условных переходов нарушают конвейерность процессора fetch/decrypt/execute

      Это говорит лишь о том, что желательно просто снижать частоту поступающих на CPU событий. Использование/неиспользование RTOS тут ничего не решает. Опять же, никто не заставляет на каждый чих заводить по отдельному потоку.


      гораздо профитнее курить саму архитектуру процессора и научиться грамотно использовать ее фичи

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


      будет легко перебраться, например, с STM на LPC или Infenion.

      С Cortex M3 на Cortex M3 — это не "перелазить". Но даже при смене вендора внезапно оказывается, что периферия порой кардинально отличается (а в случае с ST, так и между сериями), так что процесс ее изучения начинается с начала.


      совсем не подходит под это
      Мы забыли отдельный класс RTOS — операционки с собственными сетевыми стеками/драйверами/POSIX-совместимыми. Внезапно позволяют переносить добрую часть кода между процессорами в случае модернизации. Но FreeRTOS не из этой серии, это просто планировщик


      1. I_Soba
        10.08.2018 18:00

        Полно вам, это же мегабайты оперативки нужны только на стеки, у микроконтроллеров редко бывает столько. И где может быть задача контроля «сотен алгоритмических процессов», которых нельзя кинуть на рабочую очередь?

        Я и написал в последнем абзаце, что такие задачи на МК обычно не решаются.

        ОС оправдана, когда мы хотим развязать отдельные модули устройства, не превращая его в запутанный клубок.

        И при чем тут ОС? Никто не мешает НЕ делать запутанный клубок и без нее, ОС — НЕ панацея.

        Если у вас не атомарная запись/чтение величин, то думать придется. Видите ли, даже голый МК с прерываниями — уже не «однопоточная» система. Голый МК без прерываний тоже может быть не однопоточной системой, поскольку периферия тоже умеет делать что-то сама по себе.

        Есть понятие о том, что такое DMA и как именно оно работает? Понимае того, как именно чтение и запись раскладываются на ассемблере на Cortex, и что реально происходит в МК при прерывании? Осведомленность о «внутреядерной» возможности битовых масок практически для всей используемой периферии и SRAM? Это все к тому, что замечание не к месту, без понимаю сути процессов обсуждать нету смысла.

        Потому что 90% статей по ембедедду рассматривают совершенно неправдивые примеры. RTOS применяют когда у нас есть несколько классов задач, выполнение которых явно важнее других задач. Грубо говоря, «RTOS» можно сделать на контроллере прерываний (NVIC), с включенным вытеснением прерываний. Но программная обертка над планировщиком будет поудобнее, нежели ручной контроль приоритетов и порядка выполнения.

        Вот тут плюс. Тоже хотел бы посмотреть на реальную систему подобного рода, в которой RTOS реально спаситель, а не просто прихоть программиста.

        Это говорит лишь о том, что желательно просто снижать частоту поступающих на CPU событий. Использование/неиспользование RTOS тут ничего не решает. Опять же, никто не заставляет на каждый чих заводить по отдельному потоку.

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

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

        Вопрос в уровне «вкуривания». Я не говорю, что нужно задротить абсолютно любую мелочь, но когда ты знаешь все реальные процессы, происходящие в твоем МК, разрабатывать ПО становиться много легче.

        Но даже при смене вендора внезапно оказывается, что периферия порой кардинально отличается (а в случае с ST, так и между сериями), так что процесс ее изучения начинается с начала.

        А вот и нет. Контроллеры очень похожи между собой, в т.ч. и разные ядра(даже на просто си именно ядро ты вообще почти не видишь). Отлично зная одно, без труда освоишь и другое. Также, когда постоянно копаешься в даташитах, найти что-то нужное в новом — легко. и еще, После STM32f2xx структура периферии устоялась, например, перетаскивая CAN1&2 и USB, я просто скопировал модули и получил рабочую систему…

        С Cortex M3 на Cortex M3 — это не «перелазить».

        И ради чего это придирка? Я такого и не писал. Могу также ответить: Если для тебя это новость, то даже у STM32 ядро не только CORTEX-M3.


  1. Boroda1
    09.08.2018 20:33

    Касательно применения или неприменения ОСРВ — при проектировании архитектуры основным требованием является время реакции системы.
    Пример:
    -Есть асинхронные задачи, требующие реакции в пределах, допустим, 10 мкс.
    -В системе есть атомарные функции (условно «потоки»), занимающие более 10 мкс.
    При таком раскладе просто необходимо делать вытеснение и переключение контекстов, требуется реалтайм-планировщик.

    Если же системе достаточно реакции в 1 мс, и при этом в ней 10 «потоков», любой из которых выполняется менее чем за 100 мкс — нет никакого смысла городить планировщик из FreeRTOS. Вполне достаточно в основном цикле просто «ездить» по кольцу своих задач.

    Для разработчика знать ОСРВ и уметь ей пользоваться — несомненный плюс.
    Но не нужно это применять, только чтобы помигать светодиодом.


  1. lingvo
    10.08.2018 00:38
    -1

    Прежде чем разрабатывать архитектуру встроенного приложения ответьте себе на простой вопрос — в вашем описании приложения нигде не написано, что оно должно работать в реальном времени. Так какого вы применяете ОСРВ и даже рассказываете про какие-то базы данных реального времени? Только потому, что "реальное время" — это модно? И раз эмбеддед, то обязательно real-time хардкор?


    Вы, похоже, даже не понимаете, что такое работа в реальном времени и чем простое встроенное приложение отличается от такого же, но работающего в реальном времени.


    1. lingvo
      10.08.2018 11:44

      А минус за что?
      Определитесь для начала насчет ваших задач:


      Поставим задачу более четко, пусть в рамках нашего приложения необходимо:
      • Считывать данные с датчиков на шине RS-485/Modbus.
      • Считывать данные с датчиков на шине I2C.
      • Считывать данные с дискретных входов.
      • Управлять релейным выходом.
      • Обслуживать пользовательский интерфейс (дисплей + клавиатура).
      • Предоставлять доступ к данным по шине RS-485/Modbus.
      • Сохранять данные на внешний носитель.

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


      Ну а потом уже рассуждайте об архитектуре.


      1. marat_ab Автор
        10.08.2018 13:07

        У вас, кстати, написано, что приложение управляющее, а сама управляющая задача в списке не представлена.

        Вы имеете ввиду задачу «Управлять релейным выходом»? Если да, то посмотрите, пожалуйста, раздел «Работа с дискретными входами», там написано про работу с релейным выходом.


    1. marat_ab Автор
      10.08.2018 13:02

      Да, все верно, нигде не написано, что приложение должно работать в реальном времени. В данном случае ОСРВ использовалась в большей степени для организации архитектуры приложения, которое требует IMHO многозадачности. Если у вас есть информация об ОС для МК, которая позволяет решать вопросы синхронизации, работы с приоритетами задач, предоставлять возможность использования мьютексов, семафоров, очередей, и обеспечивать быструю работу с динамической памятью, но при этом не будет иметь приставки «Реального времени» поделитесь, пожалуйста, ибо я такой не знаю)))


      1. lingvo
        10.08.2018 13:14
        +1

        Если у вас есть информация об ОС для МК, которая позволяет решать вопросы синхронизации, работы с приоритетами задач, предоставлять возможность использования мьютексов, семафоров, очередей,

        Если у вас есть потребность в данной функциональности, то значит у вас есть задачи, требующие реального времени, только вы о них не знаете или не пишите. Поэтому я советую еще раз подумать об этом — требуют у вас задачи реального времени или нет.
        Например, "предоставлять доступ к данным по шине RS-485/Modbus" — если ваше устройство является "слейвом", то у вас сразу появляется непременное требование реального времени — вы должны быть способны принимать сообщения от мастера в любой момент времени, обрабатывать принятые команды в течении установленного Modbus стандартом времени и выдать ответное сообщение согласно стандарту и все это независимо от того, чем еще в данный момент занимается ваше устройство.
        А вот например "Сохранять данные на внешний носитель" — какая там разница, будет это сделано за 10мс или 300мс, правда? Т.е. тут выполнение в реальном времени не требуется.
        Определитесь с другими задачами также. Вы тогда не только узнаете зачем вам ОСРВ (ну и зачем в МК только ОСРВ и применяют), но и получите более важный результат — избежите ошибок в проектировании архитектуры своего встраиваемого устройства, которые потом могут принести много проблем и сопутствующего переписывания всей программы.


        1. marat_ab Автор
          10.08.2018 13:23

          ОК, спасибо! Согласен с тем, что вы говорите.


          1. lingvo
            10.08.2018 13:56

            Определитесь и распишите. Я во многом не согласен с вашей архитектурой, и имею опыт проектирования подобных систем, но не хочу комментировать, пока вы сами не сделаете свою оценку.