Когда-то мне довелось делать программу для управления процессом измерения в мониторе артериального давления (АД). Хочу на этом примере разобрать и продемонстрировать что нужно для решения задач реального времени. Наверно на этом примере можно понять, в том числе, когда нужно использовать RTOS.

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

Постановка задачи

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

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

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

В принципе проблема, которая приводила к сбоям, была в общем известна, это нарушение периода измерений – считывания значений с датчика, дело в том, что на основе этих значений строился некоторый алгоритм расчета АД, который понятным образом не работал, когда нарушался период поступления отсчетов с датчика давления.

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

Аппаратные ограничения или когда начинаются поиски RTOS

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

Рассмотрим структурную схему, по которой построена аппаратная система (та ее часть, которая нас интересует):

Все очень просто, надо с заданной частотой считывать данные с АЦП, проводить текущие вычисления по полученным с АЦП отсчетам (сэмплам) и каким-то образом в промежутках успевать записывать данные во Флэш по той же SPI шине, на которой висит АЦП!

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

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

Временные диаграммы, задача планировщика операций

Так вот чтобы сформулировать задачу математически точно, надо рассмотреть время выполнения каждой операции и расположить эти времена на оси времени так чтобы они не пересекались-не накладывались, исключение таких накладок как раз и сделает нашу систему абсолютно предсказуемой – надежной!

Вот такая картинка у меня сформировалась в голове.

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

Тут надо пояснить как определяются времена операций, итак:

Тацп – это время чтобы выполнить АЦП и получить результат, это две операции на SPI шине: послать команду на запуск и потом послать команду на чтение, которая и является операцией чтения. Я уже не помню деталей реализации, но для нашего анализа нам достаточно знать, что эта активность занимает достаточно мало времени от периода обращений к АЦП (насколько я помню там было что-то меньше даже 10% от периода), а САМОЕ ГЛАВНОЕ, это время практически не изменяется, то есть Тацп это константа.

ВАЖНО обратить внимание все времена мы должны соотносить со временем периода АЦП! Так как период АЦП должен выдерживаться с максимально возможной точностью, которая обеспечивается тактовой частотой процессора, потому что алгоритмы анализа (обработки) сигнала очень чувствительны к погрешности установки этого периода.

Таким образом мы определяем:

«Период от одного АЦП до другого» (до следующего преобразования, далее Тсистемы или Tsyst) как константу, которая определяется в теории обработки сигналов (здесь такая чтобы «увидеть» биение сердца на графике давления. Это что-то в районе 100 Герц- 10 миллисекунд период).

Далее следует:

Т вычислений – это время, которое процессор тратит на обработку сигнала. Когда накачивается манжета для измерения давления, процессор должен рассчитать оценочное значение давления, при котором надо перейти в режим стравливания и более точного измерения давления. Тут можно заметить, что задачи обработки сигналов достаточно ресурсоемки, а в моем случае этот алгоритм рассматривался как черный ящик с неизвестным временем выполнения. Собственно, именно эта неопределенность времени:

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

диаграмма с наложением операций
диаграмма с наложением операций

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

«Т на сохранение» - это время которое необходимо на сохранение отсчетов АЦП во флэш на SPI шине, тоже абсолютно детерминированное, обозначим как Tsave, для дальнейшего использования. Отсчеты сохраняются блоками, скажем 128 отсчетов за одну операцию -транзакцию записи во флэш. Это значит, что сохранение происходит один раз на 128 АЦП преобразований, то есть на диаграмме приведен период с максимальным количеством операций за период. Другим последствием этого факта является то, что сохранение можно отложить. Например у нас накопилось 128 отсчетов и мы готовы произвести транзакцию сохранения во флэш, но выясняется что на данный период случилась особенно длительная операция вычисления-обработка сигнала (очередного отсчета), и так как данные все равно пишутся во второй 128-байтный буфер (простейшая двойная буферизация была реализована), мы можем подождать до 128 периодов когда обработка сигнала окажется достаточно короткой чтобы успеть провести и закончить транзакцию записи во флэш до того как придет время в очередной раз запустить АЦП.

Оказывается, проблема заключается в том, что в исходной прошивке процессора не контролировалось время обращений к разным устройствам на SPI шине! Соответственно иногда происходила ситуация, изображенная на второй диаграмме, задержка операции вычисления приводила к тому, что транзакция сохранения во флэш перекрывает момент запуска АЦП. Что происходит в этом случае в программе нет смысла анализировать, это в любом случае не чего хорошего не дает, стратегия должна быть в том, чтобы не допустить такой ситуации, в крайнем случае аварийным прекращением измерения. Но на самом деле описанное мной отложенное выполнение транзакции совершенно решает эту проблему (в той железке, на которой мне пришлось работать), и сохранение во флэш всегда начинается так чтобы успеть закончить его до момента запуска очередного АЦП.

Техника измерения времени, которое остается до момента запуска очередного АЦП после завершения вычислений мне, кажется совершенно очевидной.

Решение одной из проблем наложения операций во времени

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

Tsyst – (Tend – Tstart) = T-до-конца-системного-периода, то есть до момента запуска очередного АЦП, обозначим как Т остатка периода после вычислений = Тост.

Тогда, чтобы решить можно ли запускать транзакцию записи во флэш нам надо просто проверить условие:

unsigned int Tend = getTicks();
        unsigned int Tcalc = Tend - Tstart;
        if (Tsyst - Tcalc > Tsave)
        {//
            if (BufferReadyFlag)
            {
                BufferReadyFlag = false;
                ЗапуститьТранзакциюСохраненияВоФлеш();
            }
        }
        else
        {
            if (BufferReadyFlag)
            {
            //здесь логика ожидания отложенной записи
            //и генерация ошибки в случае недопустимого поведения
            }
        }

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

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

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

Вторая проблема наложения операций во времени

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

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

Итак, вот диаграмма, на которой вопросом отмечен участок с недопустимым наложением операций.

И давайте сразу приведем диаграмму с решением.

Решением является разделение операций на те которые выполняются в прерываниях и те, которые выполняются в фоновой программе. Из приведенной диаграммы мы видим, что операция выполнения АЦП должна прерывать операцию вычисления (обработки очередного отсчета с АЦП)! Я не помню подробностей реализации на той конкретной аппаратной системе, но вполне очевидно, что мы можем разместить операцию выполнения АЦП в таймерном прерывании и назначить этому прерыванию (таймеру) период размером Тсист.

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

Тут есть не точность в имени переменной которая может ввести в заблуждение: Tcalc это относительное время окончания измерения (это Тацп+Т измерения), а не время только измерения. Константы взяты с потолка, но в правильном соотношении что Tsyst больше чем Tsave.

volatile bool BufferReadyFlag;
volatile unsigned int Tstart;
const unsigned int Tsyst = 0x777;//ticks in Tsyst period
const unsigned int Tsave = 0x333;//ticks in Tsave period
void mainLoop()
{
...
    while (1)
    {
        //это аналог семафора в какой нибудь Опер.Системе который здесь
        //открывается из прерывания Таймера после 
        //получения результата АЦП!
        WaitNextAdcResult();
        //выполнить Операцию Вычисления и произвести необходимые Манипуляции 
        // По Управлению измерительной Системой();
        ExecuteCalculations();
        unsigned int Tend = getTicks();
        unsigned int Tcalc = Tend - Tstart;
        if (Tsyst - Tcalc > Tsave)
        {//
            if (BufferReadyFlag)
            {
                BufferReadyFlag = false;
                ЗапуститьТранзакциюСохраненияВоФлеш();
            }
        }
        else if (Tcalc > (Tsyst + Tsyst / 2))
        {// Если Tcalc > (1.5*Nsyst) 
            Error("недопустимо большое время обработки отсчета АЦП!");
            MesureEnd();
        }
        else
        {//ничего не надо делать, мы по циклу вернемся на выполнение операции вычисления
            // любом случае! Если Tcalc < Nsyst будем ждать в WaitNextAdcResult()
    //следующего АЦП, Если (1.5*Nsyst) > Tcalc >= Nsyst  WaitNextAdcResult() должна
            //будет нас сразу пропустить к обработке результата АЦП
        }
        if (BufferReadyFlag)
        {
            //здесь логика ожидания отложенной записи
            //и генерация ошибки в случае недопустимого поведения
        }
...
}

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

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

Заключение

По поводу вопроса, который подразумевается в заголовке “а нужна ли RTOS для решения такого типа задач?” я думаю так:

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

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

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

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


  1. progchip666
    17.11.2022 14:03
    +3

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

    Хотя неаккуратное использование RTOS само по себе может вызывать крайне сложно отлавливаемые баги и вызывает определённые коллизии для исключения которых необходимо глубоко понимать саму "идеологию RTOS". Приходится менять стиль программирования. Ну и задачи пожирают большое количество оперативной памяти.

    По хорошему её использование раскрывает себя на микроконтроллерах начиная с ядра Cortex M4 с большим количеством параллельных процессов.

    Я начал применять RTOS пар лет назад и поначалу периодически сталкивался с вводящими меня в тупик ситуациями достаточно часто.


    1. rukhi7 Автор
      17.11.2022 14:44
      -2

      RTOS применяют не для того, чтобы

      По моему опыту RTOS применяют не потому что решили ее применить, а потому что она идет в комплекте с аппаратной платформой!

      По хорошему её использование раскрывает себя на микроконтроллерах начиная с ядра Cortex M4

      просто на Cortex M4, наверно проще разбираться с РТОС, чем с аппаратно реализованной моделью прерываний-исключений, управления памятью, ... , я подозреваю. Это такого уровня процессор что там уже сложно без какого-то промежуточного уровня софта, насколько я знаю. То есть на такого уровня процессорах наличие ОС действительно может упрощать задачу анализа программно-аппаратной платформы, поскольку не придется лазить глубже интерфейса к ОС во многих случаях, если ОС достаточно профессиональная.


  1. progchip666
    17.11.2022 14:16
    +2

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

    Мне кажется что ваша статья родилась из того факта, что у вас мало опыта работы с RTOS, использования фишек, которые она предоставляет и главное общей идеологии - переходя на RTOS приходится менять стиль программирования точно не в меньшей степени как в случае перехода на компонентную модель С++ с "классического" С.


    1. rukhi7 Автор
      17.11.2022 14:24
      +1

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

      Если бы вы привели хоть один пример того что они делают очень удобным, было бы очень интересно прочитать.


      1. progchip666
        17.11.2022 15:27
        +2

        Все свои программы на Cortex M0 и половину на M3 я до сих пор пишу на основе бесконечного цикла.

        Не считаю себя высокопрофессиональным пользователем RTOS чтобы приводить примеры своего кода, но RTOS отлично справляется у меня даже на STM32F103 c обработкой приёма и дешифрирования данных по CAN, общении с TFT панелью c сенсорным тачскрином по SPI, запись и считывания из FLASH.

        В STM32F407, который работает в паре с TFT контроллером происходит обслуживание общение по CAN, дав RS232, 10 входов цифровых 12 каналов ДельтаСигма 24 битное АЦП от ADI(SPI) к которым подключены аналоговые датчики, 2DAC 16 битных по SPI, внешняя FLASH и такие мелочи как RTС, и BACKUP SRAM память.

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

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


        1. rukhi7 Автор
          17.11.2022 16:02

          Вполне понятно, теперь, что вы имеете ввиду, хоть читаемость кода понятие достаточно субъективное. Но я и не говорил что RTOS совсем не нужны!

          Они не помогают предварительно выяснить-спланировать работающюю последовательность операций, но они вполне могут помочь реализовать нужную-уже-известную последовательность операций.

          Вроде как основное что я хотел рассказать в статье это как и откуда берется эта "нужная-правильная-правильно-организованная последовательность операций".

          Может быть действительно дело в не совсем корректном заголовке статьи.


      1. lamerok
        17.11.2022 21:03

        Да, много примеров можно привести, вот нужно будет вам на индикатор графический вывести результат, вы что тут делать будете?

        А в РТОС, заводите низко приоритетную задачу и делайте, там что хотите.


        1. rukhi7 Автор
          17.11.2022 21:34

          вот нужно будет вам на индикатор графический вывести результат, вы что тут делать будете?

          А в чем проблема то? Рассмотрим добавление еще одной операции по времени, и добавим эту операцию с нужной частотой в нужном по времени месте. Я же не могу в одной статье расписать все что там было.

          Там кстати индикатор был! Но я не помню уже никаких проблем с ним - все работало.

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


          1. lamerok
            18.11.2022 14:57

            Ну например, расчет вывода на индикатор занимает скажем 1 секунду, измерять АЦП нужно каждые 50мс и делать расчет чего-то на основе АЦП (фильтровать скажем) за 30мс.

            На идикатор остается 20мс, как разбить задачу расчета, которая занимает 1секнуду на 20 мс? Придется дробить задачу расчета вывода на индикатор?


            1. rukhi7 Автор
              18.11.2022 15:36

              Ну например, расчет вывода на индикатор занимает скажем 1 секунду,

              что то вы загнули с 1 секундой, мне кажется, я специально такую тормозную функцию не напишу, если только нарочно задержек наставить! Уж извините это из моего опыта работы и с индикаторами и целыми high definition экранами.

              Но даже если 1 секунда, в принципе надо просто ответить на вопрос что сложнее:

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

              как вы написали:

              дробить задачу расчета вывода на индикатор

              Задача, в-общем (!), не решается! все зависит от существующего окружения.

              Как вы считаете что сложнее?


              1. lamerok
                18.11.2022 18:04

                что то вы загнули с 1 секундой, мне кажется, я специально такую тормозную функцию не напишу, если только нарочно задержек наставить! Уж извините это из моего опыта работы и с индикаторами и целыми high definition экранами.

                Ну почему же, у нас датчик работает на 962 кГц, и отрисовывает экран 128 на 128, как раз около 0.5 секунд. А полевые датички они все на низких частотах работают, им питания не хватит на большей частоте работать. 3.4 мА на 9 вольтах. А помимо вывода на графику, еще нужно измерительные параметры считать и по полевой шине общаться.

                Вот например, https://www.youtube.com/watch?v=VhUcUpYbtMY датчик от токовой петли 4-20мА питается.

                Задача, в-общем (!), не решается! 

                Как раз решается, за счет РТОС. То, что вы делает руками, там это делается автоматом. Есть свободное время - работает низкоприоритная задача, нет, работает выскокприоритетная, микроконтроллер не простаивает, использует все свое время. За это платим, небольшими накладными на переключение контекста.

                Как вы считаете что сложнее?

                Проще использовать РТОС (ну или хотя бы планировщик вытесняющий) - и задача в общем решается и проще.


                1. rukhi7 Автор
                  18.11.2022 20:05
                  -1

                  А! Так вы тут с рекламой. Добро пожаловать.


                  1. lamerok
                    19.11.2022 16:58

                    Причём тут реклама? Это американский датчик, в России продаж нет и не будет. Я вам пример просто привёл.

                    А наш специально не тащу, чтобы не рекламировать.


              1. lamerok
                18.11.2022 19:05

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

                Кстати несколько стеков можно не тащить. Можно на одном все сделать. RunToComplition вытесняющий - очень просто.

                https://habr.com/ru/post/506414/


  1. Albert2009ru
    17.11.2022 14:54
    +4

    Сразу обращаясь к заголовку статьи. Микроконтроллеры, прерывания и т.п. вещи сильно старше RTOS.

    • Как же тогда, в те времена, люди без шедулера и семафоров жили, раз?

    • Можете подсказать ресурс с кодом RTOS для микроконтроллера PIC16F675 (именно для него, более мощные не надо), например?

      Я это написал потому, что заголовок "Можно ли решить задачу реального времени без RTOS, разберем реализованную задачу" - очень "кликбейтный". Ответом на него будет: "Можно, всегда так делали".


    1. rukhi7 Автор
      17.11.2022 15:10

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


  1. staticmain
    17.11.2022 16:08

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

    6502


    1. semennikov
      18.11.2022 18:43
      -2

      Так ему же за 50 лет!


  1. victor_1212
    17.11.2022 18:54
    +2

    статья интересна достаточно грамотным системным анализом, насколько знаю примерно так проектировались все ранние системы реального времени, в том числе sage, естественно не было никакой RTOS, и само понятие OS появилось позже в процессе разработки, но временных диаграмм и схем подобных приведенным в статье использовалось много, интересные фотографии того времени (1956), на первой программисты sage Al Shoolman, Herb Benington обсуждают подобную диаграмму, вторая относится к технологии программирования того времени, на третьей процесс отладки:


    1. rukhi7 Автор
      17.11.2022 19:21

      Конечно спасибо за положительную оценку, но что уж очень далеко вы меня отослали (если не сказать послали :) с моим подходом, аж в 1956 год. Мне всего то 50 лет ... будет в следующем году :).

      Вряд ли в 1956 году кто то оперировал понятиями прерывания, таймеры... планирование операций.


      1. victor_1212
        17.11.2022 21:51
        +2

        > уж очень далеко вы меня отослали

        по важности технологии (особенно real time) sage это примерно как manhattan project для физики, так что скорее комплимент, другое дело что не особенно много писали долгое время по понятным причинам,

        > Вряд ли в 1956 году кто то оперировал понятиями прерывания, таймеры... планирование операций

        было многое, если не все, но несколько в другой форме, вообще система прерываний там использовалась для обмена сигналами между двумя машинами которые работали в спарке и общались через магнитные барабаны, модемы первые для sage были сделаны, также впервые ферритовая память (до 256KB), графические дисплеи и пр., на картинке стойка модемов


      1. UstasAlex
        18.11.2022 05:00

        Совсем не далеко. Не скажу за 1956, но в начале 70-х у нас исходя из аналогичных идей разрабатывали системы реального времени. И достаточно сложные, расчитанные на циклическое исполнение десятков задач, многие из которых решались существенно дольше цикла. И состав задач был не фиксированным, а определялся по функционалу. И длительность цикла при этом выдерживалась с точностью до 1 мкс.


        1. rukhi7 Автор
          18.11.2022 08:09

          Все таки мне не совсем понятна эта отсылка к разным годам прошлого века.

          Вы скажите тогда уж:

          вы считаете что рисовать, анализировать, расчитывать временные диаграммы это несовременно что ли? Технология устарела? Такие задачи как то по другому теперь надо анализировать? Как?


          1. UstasAlex
            18.11.2022 09:27

            Да нет. Это о том, что такой способ традиционный. Особенно для специализированных аычислителей.


          1. victor_1212
            18.11.2022 14:34
            +1

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

            конечно нет, здравый смысл не может устареть в принципе, просто надо знать чужой опыт, занимаюсь real time супер долго, на разных операционных системах, но к примеру детали как именно была сделана sage мне были супер интересны


            1. rukhi7 Автор
              18.11.2022 15:06

              неужели вы имеете ввиду вот эту вот SAGE:

              The Semi-Automatic Ground Environment (SAGE) was a system of large computers and associated networking equipment that coordinated ...

              Тогда ужасно интересно, с чем в описании этой космической системы перекликается то что я написал! И как найти это место с чем то подобным в космического масштаба описании.


              1. victor_1212
                18.11.2022 16:57
                +1

                конечно sage, другой такой нет, то что интересно - это естественно, в сети достаточно ссылок, но к сожалению большая часть лабуда, написанная студентами или около того, то что перекликается с Вашим проектом - это применение здравого смысла разработчиков и системный анализ, они типа делали буквально с нуля, даже терминологии нормальной в части sw не было, были только мозги и сравнительно короткий срок готовности, т.е. они первые прошли по пути системного анализа примерно как Вы только в другом масштабе, интересно что когда сделали первую сборку - по времени не просто не влезало в рабочий цикл, а примерно в 3-4 раза, доводили методом итераций, обучаясь по ходу дела, в результате сделали рабочую систему, которая была в деле примерно до конца 80х, хотя и со многими модификациями, как побочный эффект научили IBM mainframe делать, что стало доминирующим фактором на следующие 15-20 лет, если есть вопросы можно в личку


  1. JackKatch
    17.11.2022 19:09

    Думаю, было бы неплохо поставить возле АЦП свой контроллер за два доллара, который бы мог хранить 2, 3, ... n измерений. Таким образом период измерений ни когда не будет нарушен. А основной контроллер пусть его опрашивает, считает, и сохраняет в память когда хочет. Вот и нет никаких костылей в виде, как правило, притянутых за уши RTOS. PS: Считаю что большинство вопросов решаются административно, а не при помощи "волшебной кнопки".


    1. rukhi7 Автор
      17.11.2022 19:46

      Думаю, было бы неплохо поставить возле АЦП

      ну да переразвести, заказать изготовление новой платы, по новой отладить железку, ...

      Вы это серьезно?

      Потом там и был поставлен контроллер, он же DSP процессор примерно как бы за 2 доллара, хотя может и за 20 я точно не знаю. Это был какой то TMS, с 16 битной шиной, кажется, но с поддержкой 32 битной арифметики в АЛУ.


  1. JackKatch
    17.11.2022 21:06

    Я это серьёзно, и об этом надо думать сразу, а не потом. Прекрасно понимаю вашу логику, сейчас так весь мир живет. Зачем шить новые штаны по размеру? Портного напрягать, швею! Вот есть штанишки на два размера меньше. Ну ни чего, сейчас по шву распорем, приложим, скотчем приклеим и готово. Делов та на копейку! Вот только лично мне такие брюки не по душе. О чём и написал.


    1. rukhi7 Автор
      17.11.2022 21:46

      об этом надо думать сразу, а не потом

      Вы думаете кто то будет с вами спорить по поводу такого глобального утверждения? Вы совершенно правы, но я бы посоветовал вам внимательно послушать, например, монолог Архитектора из фильма Матрица, в его разговоре с Нео.

      Может это позволит вам осознать что истина далеко не так примитивна, что бы ее можно было выразить одной фразой или даже абзацем.


  1. gatal121
    18.11.2022 04:54
    +2

    Всю статью ждал когда на сцене появится DMA и освободит процессор от ненужной работы с периферией.


    1. rukhi7 Автор
      18.11.2022 08:00

      В том процессоре модуля ДМА не было в принципе, процессор был 16-битный насколько я помню, хотя и с поддержкой 32-битной арифметики в АЛУ.

      Потом ДМА нужно использовать когда надо исключить прерывания, а тут прерывания нужны не только для чтения регистров переферии, тут еще некоторую логику в них приходится иметь.

      С ДМА у меня есть текущий работающий проект - высокоскоростной конвертор SPI To Ethernet, там для обеспечения скорости, прям вот пришлось исключить прерывания, потому что вход и выход из прерывания это добавленнное время между SPI посылками. Может как нибудь соберусь, распишу как так получилось.


      1. nixtonixto
        18.11.2022 08:36

        DMA не запрещает пользоваться прерываниями — он реагирует на прерывания только той периферии, на работу с которой настроен. Используют его не столько ради скорости, сколько ради разгрузки процессора от лишних прерываний и сокращения кода. Подключать логику для обработки прочитанных регистров можно по завершению цикла чтения, если конечно не приходится экономить каждый такт какого-нибудь маломощного PIC16… И даже если DMA активирован на работу с SPI-памятью, вам никто не запрещает через тот же порт SPI общаться с ADC программно, на прерываниях — для этого даже не надо выключать сам DMA, нужно только перенастроить один регистр периферии.


        1. rukhi7 Автор
          18.11.2022 08:52

          DMA ... Используют ... ради разгрузки процессора от лишних прерываний 

          Я вам про это и написал! В той задаче которая описана в статье "лишних прерываний" нет!


          1. sami777
            19.11.2022 12:20

            В контексте разговоров про SPI DMA как раз таки запрещает использование прерываний.


      1. gatal121
        18.11.2022 10:17

        Потом ДМА нужно использовать когда надо исключить прерывания

        Не совсем согласен, мне кажется цель ДМА освобождение полезного времени работы процессора в общем смысле, не важно от прерываний или поллинга.

        Например, в вашем псевдокоде сохранение данных во флеш происходит в основном цикле. То есть лишних прерываний нет, но есть лишний поллинг силами процессора. Это накладывает определенные ограничения на время операции вычислений. Что случится в вашей программе если условие Tsyst - Tcalc > Tsave не выполнялось более 256 раз подряд и новые данные записывать некуда? Пришлось бы переходить на прерывания, а так как данных много, прерываний было бы несколько.

        Реализация на ДМА выглядит максимально просто:

        1. По прерыванию таймера стартовали ДМА транзакцию чтения АЦП.

        2. По прерыванию завершения ДМА транзакции проверили нужно ли записать данные, если да - стартовали ДМА транзакцию записи во флеш.

        3. В основном цикле вычисления и проверка недопустимо большого времени.


  1. Sun-ami
    18.11.2022 07:04

    RTOS для микроконтроллеров существуют с 80-х годов, они появились не сильно позднее самих микроконтроллеров, например для Intel 8051, который появился в 80-м, была разработана RTOS от Intel ещё в середине 80-х. Но их назначение — упрощение разработки в системах с десятками параллельных задач, для 2-3 задач вполне можно обойтись распараллеливанием на прерываниях, это требует меньше оперативной памяти под стэк процессов, если многозадачность — вытесняющая.


  1. man55
    18.11.2022 10:30

    Противоречивые чувства от статьи. Вроде бы все верно написано, но на самом деле все в разы проще. Проблема не в RTOS/baremetal, а в ложном мнении, что RTOS - это панацея от необходимости архитектурного понимания / планирования синхронизации функций в устройстве.

    При проектировании системы и выборе аппаратной платформы делается анализ, хватит ли производительности (в широком смысле - вычислительная мощность, объем памяти, пропускная способность шин и т.п.). Очевидно что платформа подбирается под "хватит".

    Затем весь реалтайм вешается на прерывания с учетом приоритетом, где возможно - прикручивается DMA (но есть нюансы), остальное в конечный автомат в фоне. А RTOS может помочь только в обеспечении вытеснения менее приоритетных задач вместо ручной реализации разбиения длительных процессов на "псевдотакты" для кооперативного выполнения.

    Применительно к описанной задаче:
    1. Старт и обработка АЦП - вешаем старт на прерывание таймера
    Пока АЦП работает, можно что-то повычислять, либо сидеть поллингом ждать окончание преобразования
    2. Пришло прерывание / поднялся флаг что АЦП закончил преобразование - запускаем транзакцию записи во внешнюю память по SPI. Записываться должны уже заранее подготовленные данные, которые должны быть посчитаны на предыдущем шаге. Пока идет транзакция в память - вычисляем еще что-нибудь, либо ожидаем поллингом завершение работы с SPI-памятью.
    Если вдруг оказалось, что записывать пора, а данных для записи нет, значит не записываем. Считать это ошибкой или нет - определяется на этапе анализа требований.
    3. Все оставшееся время до следующего прерывания таймера для АЦП что-то считаем и готовим для следующего цикла записи в память.

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

    Если дизайн таков, что транзакция в память длиннее чем период АЦП, то разбиваем транзакцию SPI на несколько тактов, отслеживая атомарность и контроль целостности всей записи.

    Вопрос применения / неприменения RTOS: RTOS может облегчить механизм синхронизации тасков, может избавить от написания некоторых драйверов на аппаратные узлы платформы, может предоставить библиотечные сервисы какого-нибудь UDP и т.п., но не заменит архитектора системы.


    1. victor_1212
      18.11.2022 14:53

      неплохо написано, можно сказать RTOS = glue, может все соединить если спроектировано правильно, но типов клея как известно достаточно много, дело архитектора выбрать правильные компоненты и правильный клей по возможности "from the shelf", недостающие части качественно изготовить, собрать и испытать по правильной технологии, это если проект не слишком сложный, для сложных проектов бывает, что и клей специальный нужен, а иногда даже стандарты новые с которых приходится начинать


    1. rukhi7 Автор
      18.11.2022 15:21

      Пришло прерывание / поднялся флаг что АЦП закончил преобразование - запускаем транзакцию записи во внешнюю память по SPI. Записываться должны уже заранее подготовленные данные, которые должны быть посчитаны на предыдущем шаге. Пока идет транзакция в память - вычисляем еще что-нибудь, либо ожидаем поллингом завершение работы с SPI-памятью.

      Все бы хорошо только вы выкинули обработку отсчета с АЦП, а обработка сигнала с этим новым отсчетом одна из приоритетных задач, если ее вовремя не выполнить система не имеет права дальше работать потому что может руку пациенту оторвать (маленько утрируя).

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

      Поэтому надо железно гарантировать и то и другое, а вы просто взяли и выкинули одно условие.

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


      1. man55
        19.11.2022 14:35

        ... вы выкинули обработку отсчета с АЦП, а обработка сигнала с этим новым отсчетом одна из приоритетных задач ...

        ... запись во флеш имеет тот же приоритет по другой причине ...

        Я не выкидывал ничего, я приоретизировал описанные Вами процессы. Обработка отсчета АЦП производится все время, свободное от обслуживания периферии, и про это я в явном виде написал.

        Совершенно очевидно, что если нет посчитанных данных, то записывать во флэш нечего (если это конечно не сырые отсчеты АЦП, но это тривиальный случай получили - записали). При этом не менее очевидно что жизнь пациента имеет наивысший приоритет.

        Вам имеет смысл разобраться в требованиях, а не в реализации, расставьте запятые в "казнить нельзя помиловать". Процессор выполняет одну инструкцию (грубо) в один момент времени.


        1. rukhi7 Автор
          19.11.2022 16:56

          если это конечно не сырые отсчеты АЦП

          Это именно сырые (первичные) данные, я же написал: "если они не сохраняются, измерять, имеется ввиду продолжать процедуру расчетов и измерения, не имеет смысла, потому что не выполнено требование медицинского стандарта, и результатам расчетов нельзя будет доверять, и значит их нельзя использовать"

          и поэтому с точки зрения продолжения измерения

          не менее очевидно что жизнь пациента имеет наивысший приоритет

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

          Это знаете как называется:

          Смотрю в то что написано, но читаю что то свое.


          1. man55
            19.11.2022 17:09

            Если все так, как Вы описали, то проблема вообще отсутствует при условии что в железо не упираетесь. Запустили АЦП, пришло прерывание об окончании - запустили на прерываниях и/или DMA транзакцию во флэш, все оставшееся время до и после прерываний в фоне считайте свои вычисления, где проблема-то вообще??? На картинке у Вас время сохранения и время вычисления последовательны, а в тексте Вы пишете, что работа по прерываниям.
            Есть конечно еще шанс, что тормоза из-за неучтенного времени стирания сектора флэш, особенно если это не NOR FLASH, а чтото SSD-подобное, которое прячет от Вас проблемы со стиранием.


            1. rukhi7 Автор
              19.11.2022 19:13

              вы наверно пропустили что все это делалось больше 15 лет назад, такие буквы: DMA, NOR FLASH, SSD были, но в каких то космических далях.

              То есть все действительно упиралось в железо.

              Потом, нельзя, например, получить прерывание от АЦП когда АЦП висит через SPI, можно получить только прерывание SPI. И на том же (!) SPI висит флэш, соответственно это то же самое прерывание SPI в конечном итоге, куда бы писало DMA по прерыванию SPI, в АЦП или во флэш, как вы себе это представляете?

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

              А вообще я бы хотел чтобы читатель сосредоточился на методе анализа подобного рода задач во времени, а не на том почему такая задача возникла. Вот она возникла в таком виде - так бывает!


              1. man55
                19.11.2022 20:19

                вы наверно пропустили что все это делалось больше 15 лет назад, такие буквы: DMA, NOR FLASH, SSD были, но в каких то космических далях

                Я в embedded 25+ лет, начиная с середины 90-х и 8051, так что рассказывать и сам много могу, и были проекты когда на ассемблере пару байт памяти не хватало, как в той известной байке

                Надо просто разрулить обращения к шине по времени

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

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

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

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


              1. Sun-ami
                20.11.2022 13:51

                куда бы писало DMA по прерыванию SPI, в АЦП или во флэш, как вы себе это представляете?
                DMA может писать туда, куда ему задаст процедура запуска измерений — то есть из SPI в буфер АЦП. А потом генерить прерывание, которое запустит запись во флэш через SPI, которая тоже может идти через DMA — но DMA нужно каждый раз перепрограммировать. И по окончании транзакции команды и данных во флэш также генерировать прерывание. Кстати, ADUM на ядре 5051 позволял делать это задолго до STM32, уже 15 лет назад. Правда, ему и внешний АЦП не особо-то нужен, разве что, для гальванической развязки.


    1. UstasAlex
      18.11.2022 20:38

      При проектировании системы и выборе аппаратной платформы делается анализ, хватит ли производительности

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


      1. man55
        19.11.2022 17:14

        К счастью бывают такие задачи. Иначе и embedded-прогрммисты "ожирели" бы в своих творениях, как WEB-сайты и подобное. Да, иногда бизнес ставит "невпихуемые" задачи и приходится и оптимизировать и жертвовать.


  1. eurol
    18.11.2022 10:33

    Мне кажется, тут надуманные проблемы рассматриваются.

    АЦП настраиваем на чтение по сигналу от таймера с сохранением результата в массив, и нам становится все равно, сколько что времени занимает. Лишь бы успевали обрабатывать очередь измеренных значений.

    Если АЦП не умеет класть в массив (нет ПДП), реализуем то же самое программным путем: по прерыванию от таймера запускаем АЦП на измерение, по прерыванию от АЦП вынимаем данные и кладем в очередь.

    АЦП не умеет генерировать прерывание? Ну что ж, выбираем время, за которое АЦП точно успеет измерить значение и настраиваем таймер (тот же или другой) на этот период времени, по прерыванию спокойно записываем данные в очередь. Нам все равно, что там делает основная программа - мы отработали строго через заданный интервал времени.

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


    1. rukhi7 Автор
      18.11.2022 11:25

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

      Вот именно что может быть реализован что с RTOS, что без нее! Вы даже ответ дали, а говорите что вам вопрос не понятен! Статья то, в общем, о том что,

      есть у вас RTOS или нет RTOS, вам все равно нужно анализировать временную диаграмму операций и RTOS вам в этом не поможет.


      1. eurol
        18.11.2022 11:56

        Если уж придираться к заголовку...

        Он как бы рисует следующую картину. Есть задача, которую надо решать в реальном времени. И RTOS всегда для этого используется, потому что без нее никак. В крайнем случае без нее ОЧЕНЬ сложно.

        В действительности же очевидно, что RTOS нужна не для возможности работы с задачами реального времени, а для упрощения программирования сложных систем РВ. Если же задачи сами по себе простые, использование RTOS - лишняя трата ресурсов. А главное - да, думать всегда полезно. И более того - при использовании RTOS думать, возможно, придется гораздо больше.


  1. rukhi7 Автор
    18.11.2022 13:19

    В действительности же очевидно, что RTOS нужна не для возможности работы с задачами реального времени, а для упрощения программирования сложных систем РВ

    вот и получается противоречие, потому что в конце вы написали:

    И более того - при использовании RTOS думать, возможно, придется гораздо больше.

    Дело в том что это противоречие действительно существует, это суровая реальность:

    RTOS создаются чтобы жизнь упростить, но очень часто ее усложняют!

    Можно проанализировать в каких случаях они ее усложняют, например

    Если мы должны портировать RTOS на вновь созданную аппаратную платформу а потом поверх этой портированной RTOS реализовать свою задачу,

    этот путь может оказаться гораздо длиннее чем

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

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


  1. beeptec
    18.11.2022 15:03

    Можно ли решить задачу реального времени без RTOS, разберем реализованную задачу

    Можно, да еще как. К примеру транспортные средства SpaceX оснащены двухъядерными процессорами x86.

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


    1. rukhi7 Автор
      18.11.2022 15:39

      Там же нет знака вопроса! вопрос риторический, зачем же отвечать на риторический вопрос?


      1. beeptec
        18.11.2022 21:45

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


  1. Indemsys
    19.11.2022 13:29

    Если автор ведёт речь об этом дивайсе, и о микроконтроллераx типа MSP430, то картина в целом ясна. Они свои библиотеки поставляют без RTOS.
    А RTOS, которые раньше позиционировались для MSP430 перестали существовать.
    А ведь я в свое время на MSP430 c 2 КБ памяти! запускал uC/OS-II и получались отличные охранные централи с подключением к стационарным телефонным линиям (теперь такие никто не помнит) , GSM, GPRS ...
    Мало того, uC/OS-II RTOS рекомендовалась для такого типа микроконтроллеров.
    А теперь спланировать тайминги на такте считается подвигом.
    В старые добрые времена делали АОН на компараторе с процессором на 2 МГц.


    1. sim2q
      19.11.2022 20:02

      В старые добрые времена делали АОН на компараторе с процессором на 2 МГц.

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