All streams
Search
Write a publication
Pull to refresh
88
0
Вадим Дерябкин @Vadimatorikda

Инженер-программист

Send message
Не понимал ModbusTCP и FTP на МК. Для остального:
LWIP — сам по себе отжирает 1 поток в «стандартной поставке».
ModbusRTU — у меня живет в прерываниях + 1 поток для ответов (на каждого клиента, понятное дело)
HTTP — т.к. это по сути TCP, то 1 поток. Суммарно я смогу даже с учетом 4-х клиентов выделить около 10.
Удачно было бы привести пример, когда пихают под сотню потоков на решение задачи, которая без кучи уровней абстракции решалась бы в пару десятков строк внутри нескольких прерываний (подобный пример был написан здесь).
Ну а так же, что «не бесплатная». Именно поэтому нужно понимать, когда стоит их включать, а когда нет. В конечном продукте (в идеале) они бесполезны и их можно отключать. Само собой, если просчитаны всевозможные случаи и гарантируется, что стек не будет переполнен ни при каких обстоятельствах.
Вот только нужны ли в микроконтроллере «под сотню» задач — вопрос отдельный.
Ну и из-за того, что у нас «отвалился кварц» надо произвести инициализацию по другому алгоритму. Например, без этого кварца уже нельзя использовать ETH, но можно технологический UART и т.д.
Не совсем. Статья о том, что не надо пихать ОС везде, куда лезет. Просто пример подобрал не самый удачный.
Я часто практикую следующий метод:
  • в main команда " в сон";
  • вся логика в прерываниях от более чем 50 линий.

Звучит страшно, да. Однако на деле, при правильном подходе, выходит достаточно компактно и красиво. Главное красиво описать конечный автомат.
Про запутанность отписал ниже. Это пример с недооцененным загрузом процессора.
Ну а вообще да. Не вина ОС, что ее используют через одно место. Сам использую ОС периодически. Проблема в том, как ее МОЖНО при КРИВЫХ РУКАХ использовать. Что и происходит периодически.
Касательно же запутанности. Встречал задачу, которая в принципе решалась одним конечным автоматом в прерывании. Вместо этого создавался отдельный поток для каждого состояния. И прерывание отдавало симафор соответствующему потоку (чтобы началась обработка). А вот разблокированный поток уже мог отправлять аналогичные семафоры для разблокировки соседних потоков (как в случае, если бы пришло событие по прерыванию для его разблокировки). В таком коде нельзя было адекватно сказать, произошла разблокировка из другого потока, или же из прерывания.
Согласен. Данный пример только дает возможность выбрать между методами. Но к сожалению, кода аналогичного тому, с которым сталкиваюсь в прадакшене под рукой не нашлось. Но если вкратце, то сталкивался со следующим:
Принимаемые данные с последовательного порта клались в очередь, а затем раз в 20 мс выдавались пачкой по другому интерфейсу. Проблема в том, что это нагружало процессор очень значительно. Поскольку прием велся по DMA на частоте примерно 1 мегабит, вызывались прерывания, там вызывалось добавление в очередь ресурсом до 50к элементов, а затем другой поток раз в 20 мс извлекал в массив данные и по DMA отправлял в другой порт. А ведь можно было убрать этот уровень абстракции с очередью и просто использовать кольцевые буферы. Поскольку никакой проверки на корректность не производится (по ТЗ).
Аааааа… Ну тут конечно же от задачи. Просто у нас так проектируют схемы, что в случае если МК умрет, то все линии по умолчанию не должны ничего натворить (если только внутри МК не произойдет замыкание на питание). Иногда даже закладываем на такие штуки декодеры на логике. Если нужный код — можно реле открыть… Любое иное — закрыть.
Мы выделяем 1 задачу как раз. С самым низким приоритетом (выше idle). Если ее вытеснили на сильно долгое время, то что-то выжирает сильно много ресурса. Обычно МК берется с сильно большим запасом (потому что дешевые). Перезагрузка гарантирует, что МК будет инициализирован заново как положено и продолжит свою работу и вертолет не упадет от того, что сервопривод перегрелся и отвалился кварц, например. Будет сделана попытка запуститься без него и жить дальше.
Событие собаки никто не обрабатывает. Собака все убивает, если ее не сбросить.
Надо отметить, что в устройствах с которыми я работаю — нет надобности в «закрытии сессии» (за исключением пары случаев, но они блокируются при нормальной работе).
Мы используем для этого submodule в git. Можно просто не обновлять субмодуль — и ничего не сломается. Или обновиться на новую версию и посмотреть, что поменялась. Обычно просто производится проверка устройства тестами и в продакшен. Так во всех поддерживаемых устройствах одна база.
Ну и настройка MPU — это далеко не тривиальная задача. Чего стоит только выравнивание.
Тут еще до меня использовался подход «поток должен решить все проблемны аппаратки». То есть да, ловятся прерывания, но их обслуживает поток. То есть что можно — в прерывании, а что-то значительное и серьезное (например, сбросить модуль заново) — в потоке. Мне остается лишь поддерживать эту архитектуру.
Поздно заметил… Ниже уже приложили ссылку. Сам я перешел на CLion + GCC давно.
Ну так я и не говорю, что ОС в этом виновата. Я лишь отметил, что при таком стечении обстоятельств разобраться без ОС было бы проще. Поскольку в pc-регистре было бы чуть более адекватное значение, чем функция переключения контекста. А про библиотеку — требование заказчика. У них эта библиотека использовалась для цветного экрана прошлым программистом. И в ТЗ она была обязательной. А т.к. с закрытым кодом, то пришлось еще и писать авторам и выяснять, что да почему (они лишь давали .a + .h под разные архитектуры).
Да, про фатальность получилось не сильно ярко. Я привел пример с UART-ом. Это можно сказать «из реального прадакшена». Просто чуть упрощенный, чтобы ко мне не было вопросов. Там видно, что код становится неявным. Поток данных почему-то засовывается в очередь. Из этой очереди потом идет отправка обратно. Какое-то накопление байт зачем-то в буфере…
По моему опыту — не всегда помогает. Увы. Например работал с одной GUI библиотекой, которая позиционировала себя «как для МК», а на деле там был ад. Так вот. Она отжирала порядка 40 кб для 128 на 64 пикселя монохромного экрана (как потом выяснилось). При этом еще и умудрилась успеть залезть на кусок переменных планировщика и структур описания потоков и других внутренних штук. Это было очень сложно отлавливать, потому что в hard я падал именно при попытке сменить задачу)

Information

Rating
Does not participate
Location
Красноярск, Красноярский край, Россия
Date of birth
Registered
Activity

Specialization

Software Developer, Embedded Software Engineer
Lead
From 250,000 ₽
C++
STM32
Linux
Circuitry
Python
Assembler
Programming microcontrollers
Embedded system
Software development
Object-oriented design