Comments 12
Автор - сомнительный эксперт.
Историю с IoT-датчиком для умного дома с 128 КБ ОЗУ, скорее всего, выдумал.
Какая может быть динамическая память при таком объёме? Откуда он это взял?
Первое, на что он должен был напороться, - переполнение стеков.
Его мечты про стеки в 4–16 КБ - это артефакты больших операционок. А в таких девайсах 1 КБ уже роскошь.
Если он брал опенсорсный сетевой стек, то в них всех уже есть пулы пакетов фиксированной длины. Он не должен был вообще притягивать сюда динамическую память. Надо было в первую очередь озаботится глубиной пула.
Потом о какой «предсказуемости важнее гибкости» он может говорить в IoT-девайсе, где в любое мгновение может отвалиться связь? Там нет никакой такой важной предсказуемости.
Первое, что он должен был сделать, - реализовать получение памяти с таймаутом, как в большинстве RTOS сделано. Его датчики могут и подождать, пока память недоступна. А если всё равно недоступна, то выполнять ресет. IoT-девайсы ресет должны воспринимать как штатную операцию. Им всё равно в Deep Standby нужно переходить периодически с возвратом через ресет.
Какая может быть динамическая память при таком объёме?
Разрешите напомнить, что функции языка C malloc()/free() появились в Unix ещё в те времена, когда на процесс выделяли максимум 64 КиБ.
P.S.
Преждевременная оптимизация нечасто снижает трудозатраты, скорее наоборот.
К тому же, эту конкретную проблему можно было решить, как мне кажется, проще и короче. Но, да, автор похоже решил продемонстрировать все известные ему способы оптимизации.
Unix vs Unikernel. Разные вещи. Для большей части выделений памяти обычных буферов с цикличными счётчиками хватило бы, размеры подогнать и всё (солить раздутые пулы не нужно).
Из задачи - там нет непредсказуемой динамики (как и во всех однозадачных системах).
P.S. посмотрел на сетевые структуры и кровь из глаз. Может ещё и из DMA области пакеты копирует. Как это развидеть. И думал я про себя, что быдлокодер на фронтенде, а тут микроконтрольщики такую дичь пишут, что даже мне стыдно просто смотреть на это. Всё равно, что в JS заниматься "чудесными" делами в виде `let a = {};`, `a[x] = y;`, потом `delete a[x];` и удивляться, что же пошло не так и почему v8 опускает руки.
P.P.S. все готовые сетевые стеки - хрень для однозадачных систем. Не нужна вся логика по сетевым стандартам такому устройству. Не нужна логика на базе дин. памяти коду с фикс. пулами, оно просто мешает и местами неоптимально. Плюс отсутствие модульности кода необходимых фич TCP/IP, фикс. шаблонов пакетов для DMA и т.д.
Статья очень похожа на то, что ChatGPT выдаёт на запрос "вот баг, предложи исправления". Такое же перечисление стратегий, сравнение преимуществ и недостатков. Да и текст отдаёт ИИ-душком.
Скорее всего, это и произошло.
Unix vs Unikernel. Разные вещи.
Как бы, это ж как посмотреть, в AT&T (телефония), в университете Беркли, в Курчатовском институте или в ИПК Минавтопрома, Unix часто использовали примерно для того же самого.
Как "переносимую" ("стабильную") альтернативу RT-11/РАФОС, RSX-11/ОСРВ и т.п. при наличии 128...256 КиБ ОЗУ. Потом уже появились всякие VxWorks и прочая, прочая.
Но на каждый malloc(), думаю, найдётся свой mallopt(), что тогда, что сейчас.
готовые сетевые стеки - хрень для однозадачных систем. Не нужна вся логика по сетевым стандартам такому устройству. Не нужна логика на базе дин. памяти коду с фикс.
Согласен.
Для устройств такого класса - только статическая алокация. MISRA C придумали лет уже 30 назад именно для таких вещей, где нужна надежная работа 24/7/365.
"malloc/free — неподходящий инструмент для встраиваемых систем"
Похоже, это ваше первое embedded изделие? Других причин для использования malloc я просто не могу представить.
>Ограничение: размер стека ограничен (обычно 4–16 КБ). Не следует распределять в стек большие буферы.
А хто сказал ? И почму это?
Стратегия 2: статическое распределение для сетевых буферов
Минус: ОЗУ используется, даже если не нужна, но для прошивки это обычно приемлемо.
Заблуждение. В какой-то момент времени может так совпасть, что память нужна сразу всем (сети, обновлениям, датчикам). Поэтому память надо распределять так, чтобы хватало всем. Если же что-то принципиально не может работать одновременно (например, в момент обновления датчики не опрашиваются), то им можно выделить общий массив памяти.
Автор в эмбедед наверно из программирования под PC пришел? Совершенно непонятно желание использовать кучу под все на микроконтроллере?! Помню, первые атмелы вообще ОЗУ не имели - 32 регистра общего назначения и пляши как хочещь.
Ооочень странные датчики. Откуда там такие объёмы памяти? Даже если предположить что на температуру нужен float, на влажность - тоже float, на качество воздуха (хрен с ним, 4 float значений) то получается - 24 байта! Там в 128 килобайтах можно ещё пол года хранить архив! И сетевой стек на килобайт - вы его из чего делаете? Из АТ команд? Даже если предположить, что запаковка данных идёт в json и передача по MQTT то наксребсти такой объем пэто постараться нужно! Или вы инфу в виде JPG или GIF картинки передаете?
Напишите производителя и модель этих датчиков, буду понимать что не стоит приобретать.
Структуры данных на практике. Глава 19: Управление памятью в прошивках