О реальном времени
-
Уважаемые Знатоки операционных систем, помогите разобраться. Нужен миникомпьютер, быстро и безотказно (с наивысшим приоритетом) обрабатывающий прерывание по одному-единственному входу. Несложную программу обработки я должен написать сам на ассемблере, чтобы время реакции было определено с точностью до одной команды. Эта программа должна создавать в памяти массив (не маленький) «сырых» результатов, предназначенных для неспешной обработки программным обеспечением высокого уровня в среде обычного Линукса, в «не очень реальном» времени.
Вопрос: Насколько Raspberry подходит для такого проекта? Нормально ли Raspbian или другая система и аппаратура отнесутся к «подселению» такого абсолютно независимого обработчика прерывания? -
Если коротко, то НЕТ. Линукс не система реального времени и даже в режиме ядра невозможно определить гарантированное время реакции системы, хотя его можно сделать весьма малым. Совет: используйте микроконтроллер с внешней памятью.
-
man2000 (2014-11-20 00:05:18):Если коротко, то НЕТ. Линукс не система реального времени и даже в режиме ядра невозможно определить гарантированное время реакции системы, хотя его можно сделать весьма малым. Совет: используйте микроконтроллер с внешней памятью. Тогда микроконтроллер должен быть соединён с Raspberry через двухпортовую память… (Нужна полнота математики и мониторирования процесса управления, поэтому в системе должен быть компьютер.) Существует ли подходящая двухпортовая память? Наверно, придётся выходить на международный форум…
-
Не совсем понятно, что есть «двухпортовая память».
Наверно разумно говорить: «память должна быть подключена к контроллеру и малине так что бы малине обеспечивался прямой доступ к памяти».
Но зачем?
В большинстве контроллеров есть достаточный объём встроенной памяти что бы организовать буфер для хранения данных пока они не будут переданы малине и достаточное быстродействие что бы успевать передавать накопленные данные через параллельный интерфейс.
То есть логика работы получается такая:
Контроллер в прерываниях обрабатывает события, вычисляет приход события с точностью до 1 одного своего такта, например, используя таймер, полученный результат записывает в буфер организованный в его памяти по принципу FIFO, а в моменты, когда прерываний нет отдаёт малине данные из буфера.
Если данные 8 бит, то потребуется всего 10 линий связи: 0...7=DATA, 8=RD, 9=READY.
Алгоритм передачи например такой:
Малина ставит лог1 на RD и ожидает на READY появление лог1, как только есть такое то считывает данные с линий DATA, сбрасывает RD в лог0 что является сигналом для контроллера перейти к следующей ячейке буфера, как только это сделано READY сбрасывается в лог0, далее процесс повторяется.
Если данных в буфере нет, то линия RD будет установлена в лог1 а линия READY так и будет с уровнем лог0, как только придёт первый же байт данных в буфер то READY будет установлена и данные будут считаны.Банальные AVR контроллеры обладают быстродействием под 16МГц и даже 20МГц, если и этого мало то можно применить STM32F103R8T6 а это 72МГц, то есть можно фиксировать события с точностью 1/72 000 000 секунды. Если и этого нехватает, то тогда да, потребуется применить DRAM и сделать всё на ПЛИС, тогда можно и 700МГц.
Возможно (зависит от задачи) есть вариант и более простого решения: зачем мучить малину, применять RAM, контроллеры, когда например событие происходит относительно редко — можно обойтись высокочастотным генератором и высокоскоростным счётчиком который засчёлкивается по событию и имеет некий интерфейс (I2C или SPI или параллельный) для считывания результата счёта, достаточно лишь будет по появлению события считывать результат с счетчика, сбрасывать его и далее пусть считает время до события хоть с точностью 1/5000 000 000 секунды (за это время электрический импульс в проводе успеет пробежать лишь 6 сантиметров). Подходящие счётчики можно найти в составе некоторых микросхем синтезаторов частоты.
-
Можно одно из ядер процессора сделать ядром реального времени, изолировав от планировщика задач операционной системы.
Для этого добавляем в /boot/cmdline.txt параметр isolcpus=x, где x - номер ядра от 1 до 4isolcpus= [KNL,SMP] Isolate CPUs from the general scheduler. Format: <cpu number>,...,<cpu number> or <cpu number>-<cpu number> (must be a positive range in ascending order) or a mixture <cpu number>,...,<cpu number>-<cpu number> This option can be used to specify one or more CPUs to isolate from the general SMP balancing and scheduling algorithms. You can move a process onto or off an "isolated" CPU via the CPU affinity syscalls or cpuset. <cpu number> begins at 0 and the maximum value is "number of CPUs in system - 1". This option is the preferred way to isolate CPUs. The alternative -- manually setting the CPU mask of all tasks in the system -- can cause problems and suboptimal load balancer performance.
Перезагружаемся, проверяем, что ядро изолировано:
cat /sys/devices/system/cpu/isolated
И потом через taskset запускаем нужный процесс на этом ядре:
taskset -c 3 /путь_до_файла, запускающего процесс