Re: Челендж - сделать версионированный конфиг
От: Qulac Россия  
Дата: 14.09.25 06:29
Оценка: +3
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Есть развесистые вложенные структуры. Хранится, допустим, просто в файле, как снимок памяти с корневой структурой. Всё структуры состоят из примитивных типов, вроде даже float'ов нет. Есть массивы, в тч и структур, исключительно фиксированного размера.


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

M>В общем, такое вот, историческое легаси.


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


M>Вроде бы, protobuf что-то умеет в версионность, но: нам нужно уметь для каждого поля любой структуры получить его смещение относительно начала файла, чтобы писать непоредственно по этому смещению.


M>Как вам такое?



M>ЗЫ Задача со звёздочкой — сделать на чистейшей сишечке.


M>ЗЫЫ Внешние инструменты не очень приветствуются, но можно попробовать написать что-то на питоне, и к питону наверное даже можно доустановить каких-то библиотек, помимо того, что идёт в базе, если это не слишком гемморно.


Конфиг один — начальная версия. Используем скрипты миграции, на каком ни будь формально языке, которые переводят конфиг со старой версии на новую.
Программа – это мысли спрессованные в код
Re: Челендж - сделать версионированный конфиг
От: Hоmunculus  
Дата: 14.09.25 07:10
Оценка: +3
Здравствуйте, Marty, Вы писали:

Надо сразу читать всю структуру в память?
Никак хитро не сделать. Читаешь первый флаг номера версии и в зависимости от него считываешь нужный размер в нужную структуру. А потом уже любую из этих структур конвертишь в последнюю версию с дефолтными значениями.
Какие еще «челенджи» тут могут быть?
Текстовые форматы типа джейсон для того и придумали, чтоб избежать этого гемора бинарных.
Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 14:25
Оценка: :)
Здравствуйте!

Есть развесистые вложенные структуры. Хранится, допустим, просто в файле, как снимок памяти с корневой структурой. Всё структуры состоят из примитивных типов, вроде даже float'ов нет. Есть массивы, в тч и структур, исключительно фиксированного размера.

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

В общем, такое вот, историческое легаси.

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

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

Как вам такое?


ЗЫ Задача со звёздочкой — сделать на чистейшей сишечке.

ЗЫЫ Внешние инструменты не очень приветствуются, но можно попробовать написать что-то на питоне, и к питону наверное даже можно доустановить каких-то библиотек, помимо того, что идёт в базе, если это не слишком гемморно.
Маньяк Робокряк колесит по городу
Re: Челендж - сделать версионированный конфиг
От: kov_serg Россия  
Дата: 13.09.25 14:52
Оценка: +1
Здравствуйте, Marty, Вы писали:

M>Есть развесистые вложенные структуры. Хранится, допустим, просто в файле, как снимок памяти с корневой структурой.

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

M>ЗЫ Задача со звёздочкой — сделать на чистейшей сишечке.

Дык написать можно на любом языке. Или вам надо уже готовое?

M>ЗЫЫ Внешние инструменты не очень приветствуются, но можно попробовать написать что-то на питоне, и к питону наверное даже можно доустановить каких-то библиотек, помимо того, что идёт в базе, если это не слишком гемморно.

Если надо на чистой сишечке, то нафиг питон используйте lua
Отредактировано 13.09.2025 14:53 kov_serg . Предыдущая версия .
Re[7]: Челендж - сделать версионированный конфиг
От: m2user  
Дата: 13.09.25 19:37
Оценка: +1
Pzz>>Конфиг — важная вещь. Вы потом потонете, когда у вас будет с десяток разных релизов и не будет никакой совместимости между конфигами.

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


А в чём проблема с конверторами? Я примерно так версионность конфигов и делал. Правда формат был XML, а не бинарный, но подход от этого не меняется.
У каждой структуры есть версия (я в namespace ее вписывал), соответственно версия конфига определяет версии всех внутренних структур.
Вместе с новой версией конфига добавляется конвертер из предыдущей. Т.о. можно прочитать из любой старой версии в последнюю.
Единственное неудобство, что новая версия любой внутренней структуры требует подъема версии структур ее включающих.
Ну и все предыдущие версии структур должны присутсвовать в коде.

И я исхожу из того, что алгоритм конвертации в новою версию должен явным образом описываться разработчиком.
Re[2]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 15:04
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Если снимок в памяти не имеет версии, придётся рядом ложить еще один файл с информацией о структуре или ссылку где можно эту информацию получить.


Гениально

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

И да, никаких json/yaml и тп, у нас памяти всего несколько десятков килобайт на всю программу.


M>>ЗЫ Задача со звёздочкой — сделать на чистейшей сишечке.

_>Дык написать можно на любом языке. Или вам надо уже готовое?

Лучше готовое, но можно и просто идей.


M>>ЗЫЫ Внешние инструменты не очень приветствуются, но можно попробовать написать что-то на питоне, и к питону наверное даже можно доустановить каких-то библиотек, помимо того, что идёт в базе, если это не слишком гемморно.

_>Если надо на чистой сишечке, то нафиг питон используйте lua

Питон уже используется, и все скажут, что нафик ещё что-то в проект присовывать
Маньяк Робокряк колесит по городу
Re: Челендж - сделать версионированный конфиг
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.09.25 15:12
Оценка:
Здравствуйте, Marty, Вы писали:

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


Хорошо иметь семантику полей, определенную таким образом, что пропущенное поле автоматически имеет разумное дефолтное значение.

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


JSON?

M>Вроде бы, protobuf что-то умеет в версионность, но: нам нужно уметь для каждого поля любой структуры получить его смещение относительно начала файла, чтобы писать непоредственно по этому смещению.


У вас там НАСТОЛЬКО памяти мало, что надо уметь всё делать in place?

IMHO, сам код protobuf сожрёт больше памяти, чем сэкономит на данных.

M>ЗЫ Задача со звёздочкой — сделать на чистейшей сишечке.


Ну мы ж не будем тебе прям тут код писать, так что какая разница, какой язык обсуждать?
Re[2]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 15:20
Оценка:
Здравствуйте, Pzz, Вы писали:

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


Pzz>Хорошо иметь семантику полей, определенную таким образом, что пропущенное поле автоматически имеет разумное дефолтное значение.


Хорошо там, где нас нет


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


Pzz>JSON?


Нет конечно


M>>Вроде бы, protobuf что-то умеет в версионность, но: нам нужно уметь для каждого поля любой структуры получить его смещение относительно начала файла, чтобы писать непоредственно по этому смещению.


Pzz>У вас там НАСТОЛЬКО памяти мало, что надо уметь всё делать in place?


Миикроконтроллер


Pzz>IMHO, сам код protobuf сожрёт больше памяти, чем сэкономит на данных.


M>>ЗЫ Задача со звёздочкой — сделать на чистейшей сишечке.


Pzz>Ну мы ж не будем тебе прям тут код писать, так что какая разница, какой язык обсуждать?


Разница большая.

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

Хотелось бы:
1) Идей, как вообще это сделать в условиях ограниченных ресурсов
2) Идей, как это сделать на плюсах
3) Идей, как плюсовую магию повторить на сишечке, или, хотя бы, жалкое подобие сделать. По этому пункту на самом деле решение может быть совсем не таким, как на плюсах, с учетом убогих возможностей сишечки.
Маньяк Робокряк колесит по городу
Re[3]: Челендж - сделать версионированный конфиг
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.09.25 15:30
Оценка:
Здравствуйте, Marty, Вы писали:

Pzz>>JSON?


M>Нет конечно


Почему?

Бывают бинарные форматы, по сути своей близкие к JSON-у. JSON, кстати, весьма компактен, если в одну строчку и без незначимых пробелов.

Pzz>>У вас там НАСТОЛЬКО памяти мало, что надо уметь всё делать in place?


M>Миикроконтроллер


Слушай, я вписывал полноценный стек TCP в резидент под DOS. Это десятка полтора K кода, и под пакеты я завёл себе 8К.

Мииии — это когда тебе обещали 128 байт памяти данных, а оказалось, что их там только 64, а ты, дурак, поленился вовремя проверить, и стек после буквально пары-тройки вложенных вызовов наехал на твои три с половиной статические переменные. И ты с изумлением узнаёшь, что gcc для AVR-ки стремится использовать все доступные регистры, и все их сохраняет в стеке при каждом вызове, сука. Потому, что у тебе нет столько стека, а регистров у AVR-ки много.

А десятки килобайт — это уже норм. Есть, где развернуться.

M>Хотелось бы:

M>1) Идей, как вообще это сделать в условиях ограниченных ресурсов

Как бинарный JSON.
Re[4]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 15:43
Оценка:
Здравствуйте, Pzz, Вы писали:


Pzz>Бывают бинарные форматы, по сути своей близкие к JSON-у. JSON, кстати, весьма компактен, если в одну строчку и без незначимых пробелов.


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


Pzz>>>У вас там НАСТОЛЬКО памяти мало, что надо уметь всё делать in place?


M>>Миикроконтроллер


Pzz>Слушай, я вписывал полноценный стек TCP в резидент под DOS. Это десятка полтора K кода, и под пакеты я завёл себе 8К.


Я писал HTTP-сервер на Turbo C, на TCP-стеке, который кем-то написал до меня, под 186ой процессор. Но я не хочу потратить несколько месяцев на сабжевую задачу.



Pzz>Мииии — это когда тебе обещали 128 байт памяти данных, а оказалось, что их там только 64, а ты, дурак, поленился вовремя проверить, и стек после буквально пары-тройки вложенных вызовов наехал на твои три с половиной статические переменные. И ты с изумлением узнаёшь, что gcc для AVR-ки стремится использовать все доступные регистры, и все их сохраняет в стеке при каждом вызове, сука. Потому, что у тебе нет столько стека, а регистров у AVR-ки много.


Pzz>А десятки килобайт — это уже норм. Есть, где развернуться.


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


M>>Хотелось бы:

M>>1) Идей, как вообще это сделать в условиях ограниченных ресурсов

Pzz>Как бинарный JSON.


Ну, хотелось бы более конкретных идей. При чем тут бинарный JSON, кстати, не очень понятно. Зачем вообще ориентироваться на какой-то существующий формат, если всё равно либо для его обработки с высокой степенью вероятности будет не втащить в проект?

Ну и "бинарный JSON" — это как-то не ответ. Хоть бинарный SQL. Он ничего не говорит, что хранить в этом бинарном JSON/SQL.
Маньяк Робокряк колесит по городу
Re: Челендж - сделать версионированный конфиг
От: DiPaolo Россия  
Дата: 13.09.25 16:20
Оценка:
Как вариант – такое https://kaitai.io

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

Окей, можно просто парсер свой написать, типа как для всяких протоколов/спецификаций.

Ты б хоть привел пример структур своих. А то не очень понятно, в чем сложность
Патриот здравого смысла
Re[3]: Челендж - сделать версионированный конфиг
От: kov_serg Россия  
Дата: 13.09.25 16:40
Оценка:
Здравствуйте, Marty, Вы писали:

M>Гениально

M>Осталось придумать, что и как хранить в метаданных, и как это описать, очень желательно не описать и нагенерить новое, а описать на базе существующего.
Тогда храни аля RIFF, LBM
TAG,SIZE [DATA]

Или asn.1

M>И да, никаких json/yaml и тп, у нас памяти всего несколько десятков килобайт на всю программу.

Фигасе и питон помещается?
Вам никто не мешает хранить метаданные например в kaitai на github
А версию указывать как url ссылку на используемую версию

M>Лучше готовое, но можно и просто идей.

Идея простая представь данные в самоописывающемся формате


M>Питон уже используется, и все скажут, что нафик ещё что-то в проект присовывать

lua это чистый C ~ 300кб. А python это лютый оверхед и потом еще и геморой с совместимостью на платформах которые питон не желает поддерживать.
Отредактировано 13.09.2025 16:44 kov_serg . Предыдущая версия .
Re[5]: Челендж - сделать версионированный конфиг
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.09.25 16:40
Оценка:
Здравствуйте, Marty, Вы писали:

Pzz>>Бывают бинарные форматы, по сути своей близкие к JSON-у. JSON, кстати, весьма компактен, если в одну строчку и без незначимых пробелов.


M>А кто разбор будет этого, пусть и бинарного, JSON? Ну, допустим, пять килобайт, пусть даже десять, под либу выделить можно. Что влезет в эти десять килобайт?


Ну, например, ты

Чего там париться, это работы на 1-2 дня. Ну или библиотеку готовую найди.

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


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

Pzz>>Как бинарный JSON.


M>Ну, хотелось бы более конкретных идей. При чем тут бинарный JSON, кстати, не очень понятно. Зачем вообще ориентироваться на какой-то существующий формат, если всё равно либо для его обработки с высокой степенью вероятности будет не втащить в проект?


Я имею ввиду, идею JSON-а: именованные, немного типизованные атрибуты, поддержка массивов и вложенных объектов.

Такой формат легко расширяется просто путём добавления новых аттрибутов.
Re[2]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 16:57
Оценка:
Здравствуйте, DiPaolo, Вы писали:

DP>Как вариант – такое https://kaitai.io


Не кажется хорошим вариантом:
1) Не умеет генерить в сишечку
2) Надо описывать структуры на этом языке, а не описывать существующие. У меня структуры описаны в сишечном хидере и в зависимости от разных дефайнов, которые задаются для проекта, поля многих структур определяются по разному, и могут вообще отсутствовать
3) Как я понял, в двоичную структуру он (де)сериализует, постоянно сериализовать всю здоровую структуру — совсем не вариант, разные части софта хотят писать в конкретные места, и очень часто, на сериализации всё умрёт.
4) Для сериализации используются плюсовые потоки. Даже если бы у меня были плюсы, потоков у меня всё равно бы не было.


DP>Ну и неясно, почему нельзя просто задефайнить структуру и читать ее прямо из памяти? Ну и разруливать разные версии ифами.


Что значит — нельзя? Именно так сейчас оно и сделано. И это боль. Проблема возникает при смене версии структур данных — когда в структурах что-то удаляется/добавляется/меняется. Новый софт должен уметь считать старую структуру и сконвертировать её в новую.


DP>Окей, можно просто парсер свой написать, типа как для всяких протоколов/спецификаций.


Можно. Есть какие-нибудь идеи?


DP>Ты б хоть привел пример структур своих. А то не очень понятно, в чем сложность


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

Да хоть бы как BMP-шные — https://formats.kaitai.io/bmp/
Представь, что раз в несколько месяцев они меняются, что-то вставляется, что-то удаляется или переезжает. И нет никаких полей, в которых лежит номер версии конкретной подструктуры, чтобы всякими if'ами в коде проверять (да и никто не будет имеющийся код дорабатывать, если что-то понадобилось — просто фигачат новое поле, а о совместимости со старой версией никто не думает).
Маньяк Робокряк колесит по городу
Re[4]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 18:00
Оценка:
Здравствуйте, kov_serg, Вы писали:

M>>Гениально

M>>Осталось придумать, что и как хранить в метаданных, и как это описать, очень желательно не описать и нагенерить новое, а описать на базе существующего.
_>Тогда храни аля RIFF, LBM
_>TAG,SIZE [DATA]

А TAG — что там?
Интересны как раз не общие рассуждения, а более конкретные мысли, как поступить в ситуации с существующими ограничениями


_>Или asn.1





M>>И да, никаких json/yaml и тп, у нас памяти всего несколько десятков килобайт на всю программу.

_>Фигасе и питон помещается?

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


_>Вам никто не мешает хранить метаданные например в kaitai на github

_>А версию указывать как url ссылку на используемую версию

И как это мне поможет?


M>>Лучше готовое, но можно и просто идей.

_>Идея простая представь данные в самоописывающемся формате

Но приходится работать с тем, что есть


M>>Питон уже используется, и все скажут, что нафик ещё что-то в проект присовывать

_>lua это чистый C ~ 300кб. А python это лютый оверхед и потом еще и геморой с совместимостью на платформах которые питон не желает поддерживать.

Тут не в размере дело. В любом случае, у меня в девайсе 256 Кб вообще на всё, если не меньше.

На питоне можно попробовать написать что-то вспомогательное для сборки, потому что он уже используется, и некоторые в команде с ним работали. Луа присунуть даже в сборку никто не даст.
Маньяк Робокряк колесит по городу
Re[6]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 18:11
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>>>Бывают бинарные форматы, по сути своей близкие к JSON-у. JSON, кстати, весьма компактен, если в одну строчку и без незначимых пробелов.


M>>А кто разбор будет этого, пусть и бинарного, JSON? Ну, допустим, пять килобайт, пусть даже десять, под либу выделить можно. Что влезет в эти десять килобайт?


Pzz>Ну, например, ты


Pzz>Чего там париться, это работы на 1-2 дня. Ну или библиотеку готовую найди.


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

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


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


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


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


Pzz>Я имею ввиду, идею JSON-а: именованные, немного типизованные атрибуты, поддержка массивов и вложенных объектов.


Pzz>Такой формат легко расширяется просто путём добавления новых аттрибутов.


Ну, такие общие идеи и у меня есть
Маньяк Робокряк колесит по городу
Re[4]: Челендж - сделать версионированный конфиг
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.09.25 18:12
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Или asn.1


Пошутил так пошутил.

M>>И да, никаких json/yaml и тп, у нас памяти всего несколько десятков килобайт на всю программу.

_>Фигасе и питон помещается?

Питон у них, я думаю, внешний (по отношению к железке).
Re[5]: Челендж - сделать версионированный конфиг
От: bnk СССР http://unmanagedvisio.com/
Дата: 13.09.25 18:14
Оценка:
Здравствуйте, Marty, Вы писали:

_>>Тогда храни аля RIFF, LBM

_>>TAG,SIZE [DATA]

M>А TAG — что там?


Тип блока данных. Тэг по которому программа узнает что там. RIFF в прошлом веке был очень популярным: дёшево и сердито. Есть в Вики, или любого бота спроси он объяснит что это такое.

Ещё можно версию структуры хранить вместе с размером, а в твоём коде уже разбираться. Микрософт так сто лет делает, правда они в основном добавляют поля, в этом случае меньше мороки и безопаснее это.
Отредактировано 13.09.2025 18:15 bnk . Предыдущая версия .
Re[5]: Челендж - сделать версионированный конфиг
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.09.25 18:18
Оценка:
Здравствуйте, Marty, Вы писали:

M>А TAG — что там?


TLV (Tag-Length-Value). Это стандартный паттерн.

https://en.wikipedia.org/wiki/Type%E2%80%93length%E2%80%93value

Сам tag может быть индикатором типа (ну там, int/string) или идентификатором атрибута.

_>>Вам никто не мешает хранить метаданные например в kaitai на github

_>>А версию указывать как url ссылку на используемую версию

M>И как это мне поможет?


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

Но тебе это никак не поможет.

M>Тут не в размере дело. В любом случае, у меня в девайсе 256 Кб вообще на всё, если не меньше.


Богатая железка. 256 Кб — совсем не мало. CM-4 имело 256 Кб, и тянула на себе целых класс студентов, которые чего-то там учились программировать на Фортране.
Re[6]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 18:41
Оценка:
Здравствуйте, Pzz, Вы писали:

M>>А TAG — что там?


Pzz>TLV (Tag-Length-Value). Это стандартный паттерн.


Pzz>https://en.wikipedia.org/wiki/Type%E2%80%93length%E2%80%93value


Да, я куда-то в эту сторону тоже думаю. Но за ссылку — спс, не знал, как это называется


Pzz>Сам tag может быть индикатором типа (ну там, int/string) или идентификатором атрибута.


Угу, тоже так думаю

M>>Тут не в размере дело. В любом случае, у меня в девайсе 256 Кб вообще на всё, если не меньше.


Pzz>Богатая железка. 256 Кб — совсем не мало. CM-4 имело 256 Кб, и тянула на себе целых класс студентов, которые чего-то там учились программировать на Фортране.


Я условно сказал. Железка такая: RISC-V К1986ВУ024 (NRTS32M)

Нашел его в инете. Памяти программ там даже 512, но там ППЦ сколько он тащит

32-битное ядро RISC-V (тип N308)
Максимальная рабочая частота 144 МГц
Операции с плавающей точкой
DSP-инструкции
512 КБ флэш-памяти
144 КБ ОЗУ
4 АЦП (12 бит с частотой 5 МВыб/сек)
4 операционных усилителя
7 компараторов
2 ЦАП (12 бит с частотой 1 МВ/сек)
UART, I2C, SPI, QSPI, CAN



ЗЫ Нашел на хабре в коментах:

Все равно чувствуется некое поклонение западу. КУНК-5 наш выбор.

RISC-V — reduced instruction set computer five.

КУНК-5 — компьютер с уменьшенным набором команд.


Сейчас придёт Музыченко, и скажет, что правильно называть не команда, а инструкция...

ЗЫ Кстати, не понял, товарищ Музыченко, чем обусловлен смайлик к стартовому сообщению?
Маньяк Робокряк колесит по городу
Отредактировано 14.09.2025 10:45 Marty . Предыдущая версия . Еще …
Отредактировано 13.09.2025 19:00 Marty . Предыдущая версия .
Re[5]: Челендж - сделать версионированный конфиг
От: kov_serg Россия  
Дата: 13.09.25 19:19
Оценка:
Здравствуйте, Marty, Вы писали:

M>А TAG — что там?

M>Интересны как раз не общие рассуждения, а более конкретные мысли, как поступить в ситуации с существующими ограничениями
Всё очень просто TAG это уникальный идентификатор типа данных, длинна это длинна значения (если не умеет просто может скипнуть)
И да можно кодировать не фиксированной длинной (особенно если мало памяти) хоть побитно.

_>>Или asn.1

M>
На самом деле там такая же схема, просто моного лишнего.


M>>>И да, никаких json/yaml и тп, у нас памяти всего несколько десятков килобайт на всю программу.

_>>Фигасе и питон помещается?
И что? Это более чем достаточно в ZX Spectrum было 48Кб и было норм
В некоторых контроллерах вообще десятки байт RAM

M>Нет, конечно, питон используется при сборке зачем-то, и если пилить какую-то тулзу самому, которая подготавливает метаданные для устройства, то лучше на питоне

Так ишо? Кто мешает еще м lua добавить, причем собрав из исходников.

_>>Вам никто не мешает хранить метаданные например в kaitai на github

_>>А версию указывать как url ссылку на используемую версию
M>И как это мне поможет?
Очень просто в начале храните номер версии или url ссылку или её часть или её-hash. По этим данным можете получить из своего хранилища полную информацию о строение файла или даже сам сериализатор.
Зависит от вашей фантазии.


M>>>Лучше готовое, но можно и просто идей.

_>>Идея простая представь данные в самоописывающемся формате
M>Но приходится работать с тем, что есть
Тогда внешний описатель или ссылка на него.


M>Тут не в размере дело. В любом случае, у меня в девайсе 256 Кб вообще на всё, если не меньше.

Так не надо это делать в контроллере. Вы можете получать конфиг и преобразовать его в заданный. Если это возможно :-P

M>На питоне можно попробовать написать что-то вспомогательное для сборки, потому что он уже используется, и некоторые в команде с ним работали. Луа присунуть даже в сборку никто не даст.

И очень зря. тогда perl
Re[6]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 19:26
Оценка:
Здравствуйте, kov_serg, Вы писали:

M>>А TAG — что там?

M>>Интересны как раз не общие рассуждения, а более конкретные мысли, как поступить в ситуации с существующими ограничениями
_>Всё очень просто TAG это уникальный идентификатор типа данных, длинна это длинна значения (если не умеет просто может скипнуть)
_>И да можно кодировать не фиксированной длинной (особенно если мало памяти) хоть побитно.


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


M>>Нет, конечно, питон используется при сборке зачем-то, и если пилить какую-то тулзу самому, которая подготавливает метаданные для устройства, то лучше на питоне

_>Так ишо? Кто мешает еще м lua добавить, причем собрав из исходников.

И то. Никто зоопарк разводить не будет


M>>И как это мне поможет?

_>Очень просто в начале храните номер версии или url ссылку или её часть или её-hash.

Это решает только задачу сравнения версий на эквивалентность, и всё


_>По этим данным можете получить из своего хранилища полную информацию о строение файла или даже сам сериализатор.

_>Зависит от вашей фантазии.

Сериализатор надо сделать. В этом задача. И не просто сериализатор, а мигратор



M>>Тут не в размере дело. В любом случае, у меня в девайсе 256 Кб вообще на всё, если не меньше.

_>Так не надо это делать в контроллере. Вы можете получать конфиг и преобразовать его в заданный. Если это возможно :-P

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


M>>На питоне можно попробовать написать что-то вспомогательное для сборки, потому что он уже используется, и некоторые в команде с ним работали. Луа присунуть даже в сборку никто не даст.

_>И очень зря. тогда perl

Перл особенно идёт далеко
Маньяк Робокряк колесит по городу
Re[8]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 20:23
Оценка:
Здравствуйте, m2user, Вы писали:

M>А в чём проблема с конверторами?


Хочется с минимальной болью это делать. Пока всё через жопу.


M>Единственное неудобство, что новая версия любой внутренней структуры требует подъема версии структур ее включающих.


А вот тут не очень понятно, нафига поднимать версии включенных структур? А если включенная структура ещё и в других местах включается, то там тоже у включающей структуры надо версию поднимать?


M>Ну и все предыдущие версии структур должны присутсвовать в коде.


Да, так наверное и надо сделать. Сейчас все версии только в истории в гите лежат.


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


Хотелось бы это сделать минимально просто
Маньяк Робокряк колесит по городу
Re[7]: Челендж - сделать версионированный конфиг
От: bnk СССР http://unmanagedvisio.com/
Дата: 13.09.25 20:28
Оценка:
Здравствуйте, Marty, Вы писали:

M>>>Тут не в размере дело. В любом случае, у меня в девайсе 256 Кб вообще на всё, если не меньше.


Если экономия будет несколько килобайт по сравнению с текстовым форматом, оно того точно стоит?
IMHO ты больше провозишься с написанием своего формата, с около нулевым выхлопом по сравнению с банальным JSON.
Впрочем энергии тебе не занимать

Парсер json на 200 строк
https://github.com/zserge/jsmn
Re[8]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 21:07
Оценка:
Здравствуйте, bnk, Вы писали:

M>>>>Тут не в размере дело. В любом случае, у меня в девайсе 256 Кб вообще на всё, если не меньше.


bnk>Если экономия будет несколько килобайт по сравнению с текстовым форматом, оно того точно стоит?

bnk>IMHO ты больше провозишься с написанием своего формата, с около нулевым выхлопом по сравнению с банальным JSON.

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


bnk>Впрочем энергии тебе не занимать





bnk>Парсер json на 200 строк

bnk>https://github.com/zserge/jsmn

Да, JSON не JSON — это дело десятое, мне нужно придумать, как миграцию сделать
Маньяк Робокряк колесит по городу
Re[9]: Челендж - сделать версионированный конфиг
От: m2user  
Дата: 13.09.25 21:07
Оценка:
M>А если включенная структура ещё и в других местах включается, то там тоже у включающей структуры надо версию поднимать?

Да, потому что это уже другой тип, т.к. набор/тип полей изменился


struct A1 {
 B1 b;
}

struct A2 {
 B2 b;
}


Но я делал так, что самая свежая версия была без номеров (при сериализации версия конфига конечно была), а исторические версии — номерные.
Чтобы вся эта нумерация была только в коде чтения/записи и конвертации.

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

M>Хотелось бы это сделать минимально просто

Есть логика агрейда, её автоматом никак не вывести. Но можно предоставить какие-то хелперы, для типовых ситуаций.
Re[9]: Челендж - сделать версионированный конфиг
От: bnk СССР http://unmanagedvisio.com/
Дата: 13.09.25 21:17
Оценка:
Здравствуйте, Marty, Вы писали:

M>Текстовый формат в любом случае не подходит. Различные подсистемы хотят на старте получить указатель на свою двоичную структуру, чтобы потом во время работы туда напрямую писать.

M>И конфиг хранится не во флеше, а епроме, там всего 16Кб

Так это тогда ни разу не "конфиг". RIFF (TLV) нормальный вариант, это работает десятилетиями, и проще сложно что-то придумать IMHO.

В тэг можно тип struct-а писать (StructX structY, etc), и номер ее версии например (X1, Y1, ну и т.п.)
Чтобы проще парсить, я бы запретил изменения, только дополнения полей.

Т.е. "Y2" это "Y1" с дополнительными полями.
Тогда код код который парсит Y1 можно использовать для парсинга Y2 тоже.
А если нужно поменять поле в структуре, заводишь новое.
Но в принципе опционально, просто код который это парсит должен быть сложнее.

Длина блока там нужна чтобы перепрыгивать "неизвестные" блоки.
Так код, читающий конфиг должен читать только то что понимает , а что не понимает — пропускать до следующего заголовка (тэга).
Т.е. старый код сможет прочитать "новый" конфиг и не упасть.
Отредактировано 13.09.2025 21:25 bnk . Предыдущая версия . Еще …
Отредактировано 13.09.2025 21:24 bnk . Предыдущая версия .
Отредактировано 13.09.2025 21:20 bnk . Предыдущая версия .
Отредактировано 13.09.2025 21:18 bnk . Предыдущая версия .
Re[10]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 21:27
Оценка:
Здравствуйте, m2user, Вы писали:

M>>А если включенная структура ещё и в других местах включается, то там тоже у включающей структуры надо версию поднимать?


M>Да, потому что это уже другой тип, т.к. набор/тип полей изменился


Вложенная структура — та же самая, не?


M>

M>struct A1 {
M> B1 b;
M>}

M>struct A2 {
M> B2 b;
M>}

M>


Не понял, что тут илллюстрируется?

Я тебя понял так:

Исходно:
struct Inner_v1
{
//...
};

struct A_v1
{
//...
int         i1;
Inner_v1    inner;
//...
};

struct B_v1
{
//...
Inner_v1    inner;
//...
};


Как я понял, ты, если сделал v2 версию для A, зачем-то делаешь Inner_v2, и тогда надо лезть в B_v1, менять там на Inner_v2, и также надо поднимать версию и у B/
struct A_v2
{
//...
char        ch1;
Inner_v1    inner; // Тут не надо повышать версию вложенной структуры
//...
};



M>Но я делал так, что самая свежая версия была без номеров (при сериализации версия конфига конечно была), а исторические версии — номерные.

M>Чтобы вся эта нумерация была только в коде чтения/записи и конвертации.

Ну, это решается организационно, либо последнюю версию перед изменением копируем и задаём ей номер, а изменения вносим в структуру без версии, либо сразу создаём новую структуру с новой версией, и делаем ей алиас без версии.


M>Есть логика агрейда, её автоматом никак не вывести.


Ну вот это как раз и хотелось бы сделать, чисто — сделал новую версию структуры, сделал описание layout'а новой версии, и оно само все делает
Маньяк Робокряк колесит по городу
Re[10]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.25 22:28
Оценка:
Здравствуйте, bnk, Вы писали:

M>>Текстовый формат в любом случае не подходит. Различные подсистемы хотят на старте получить указатель на свою двоичную структуру, чтобы потом во время работы туда напрямую писать.

M>>И конфиг хранится не во флеше, а епроме, там всего 16Кб

bnk>Так это тогда ни разу не "конфиг". RIFF (TLV) нормальный вариант, это работает десятилетиями, и проще сложно что-то придумать IMHO.


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

Да, мне уже подсказали, что надо копать в сторону TLV


bnk>В тэг можно тип struct-а писать (StructX structY, etc), и номер ее версии например (X1, Y1, ну и т.п.)

bnk>Чтобы проще парсить, я бы запретил изменения, только дополнения полей.

Сейчас думаю, как именам давать на автомате короткие стабильные идентификаторы. Хранить имена — слишком жирно — 10 структур по 10 полей, каждое 10 символов — это килобайт только на имена одной версии


bnk>Т.е. "Y2" это "Y1" с дополнительными полями.

bnk>Тогда код код который парсит Y1 можно использовать для парсинга Y2 тоже.
bnk>А если нужно поменять поле в структуре, заводишь новое.
bnk>Но в принципе опционально, просто код который это парсит должен быть сложнее.

Да по идее, удалять тоже не проблема, если в новой структуре нет поля, то из старой ничего не берётся просто.
Ну, и соответственно, менять местами тоже нет проблем.
Маньяк Робокряк колесит по городу
Re[3]: Челендж - сделать версионированный конфиг
От: DiPaolo Россия  
Дата: 14.09.25 00:55
Оценка:
DP>>Окей, можно просто парсер свой написать, типа как для всяких протоколов/спецификаций.

M>Можно. Есть какие-нибудь идеи?


  Ну на примере того же BMP
struct ACTUAL_FILE_HEADER;

struct FILE_HEADER_2025_04_04;
struct FILE_HEADER_2024_02_11;
struct FILE_HEADER_1999_09_08;

struct ACTUAL_BITMAP_HEADER;

struct BITMAP_HEADER_V1;
struct BITMAP_HEADER_V2;

int read_file(r *reader)
{
    ACTUAL_FILE_HEADER fh;

    FILE_HEADER_2025_04_04 *fh_2025_04_04 = 0;
    FILE_HEADER_2024_02_11 *fh_2024_02_11 = 0;
    FILE_HEADER_1999_09_08 *fh_1999_09_08 = 0;

    ACTUAL_BITMAP_HEADER bmp_hdr;

    BITMAP_HEADER_V1 *bmp_hdr_v1 = 0;
    BITMAP_HEADER_V2 *bmp_hdr_v2 = 0;

    fh_2025_04_04 = read_file_header_since_2025_04_04(r);
    if (fh_2025_04_04) {
        fh = map_from_2025_04_04(fh_2025_04_04);
    } else {
        fh_2024_02_11 = read_file_header_since_2024_02_11(r);
        if (fh_2024_02_11) {
            fh = map_from_2024_02_11(fh_2024_02_11);
        } else {
            fh = read_file_header_since_1999_09_08(r);
            if (fh) {
                fh = map_from_1999_09_08(r);
            } else {
                // error
            }
        }
    }

    if (fh.version == 1) {
        bmp_hdr_v1 = read_bitmap_header_v1(r);
        bmp_hdr = map_from_bitmap_header_v1(r);
    } else if (fh.version == 2) {
        bmp_hdr_v2 = read_bitmap_header_v2(r);
        bmp_hdr = map_from_bitmap_header_v2(r);
    }

    // ...
}

FILE_HEADER_2025_04_04 read_file_header_since_2025_04_04(r *reader)
{
    FILE_HEADER_2025_04_04 fh;

    fh.field1 = r.read_bytes(2);
    if (!fh.field1) {
        // error
        return 0;
    }

    fh.field2 = r.read_bits(2);
    if (fh.field2 != 0 || fh.field2 != 1) {
        // error
        return 0;    
    }

    fh.field3 = r.read_bits(1);
    if (!fh.field3) {
        // error
        return 0;
    }
}


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

Функции также можно объединить: сразу и читать и пробовать смаппить; yе получилось – идем к следующей. То есть не
    fh_2025_04_04 = read_file_header_since_2025_04_04(r);
    if (fh_2025_04_04) {
        fh = map_from_2025_04_04(fh_2025_04_04);
    } else {


а
    fh_2025_04_04 = map_file_header_since_2025_04_04(r);
    if (!fh_2025_04_04) {
        fh = map_from_2025_04_04(fh_2025_04_04);


Внутри конечно будут вложенные структуры и их же вложенный парсинг.

Ну короче – это обычный парсинг битстрима, коих миллионы. Можно для примера посмотреть тот же FFmpeg — любой файл, оканчивающийся на dec. К примеру вот https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/ac3dec.c
Патриот здравого смысла
Re[11]: Челендж - сделать версионированный конфиг
От: m2user  
Дата: 14.09.25 07:56
Оценка:
M>Как я понял, ты, если сделал v2 версию для A, зачем-то делаешь Inner_v2, и тогда надо лезть в B_v1, менять там на Inner_v2, и также надо поднимать версию и у B/

Нет, я говорил про сценарий, когда требуется новая версия для Inner. И в этом случае нужно повышать версии всех типов использующих Inner, напрямую (A и B) или опосредованно.
Объем необходимых изменений начинает зависеть от "развесистости" структур.

M>Ну, это решается организационно, либо последнюю версию перед изменением копируем и задаём ей номер, а изменения вносим в структуру без версии, либо сразу создаём новую структуру с новой версией, и делаем ей алиас без версии.


Да, как-то так, просто не во всех ЯП есть алиасы типа typedef.

M>Ну вот это как раз и хотелось бы сделать, чисто — сделал новую версию структуры, сделал описание layout'а новой версии, и оно само все делает


В моих задачах как правило новые поля выводились из старых по некоему нетривиальному алгоритму.
Например раньше значение было в виде строки, а теперь бинарный формат или новое значение нужно вывести из нескольких других полей (+ что-нибудь из окружения, типа текущей локали).
Терять старые данные было нельзя.
Re[7]: Челендж - сделать версионированный конфиг
От: DiPaolo Россия  
Дата: 14.09.25 08:13
Оценка:
M>Потонете, хаха. Уже буль-буль. Этому легаси не первый год, и, возможно, не первый даже десяток лет. Уже два с лишним десятка версий, и для каждой вручный с болью написанный конвертер. Поэтому и есть желание это как-то сделать не так больно, но расхреначивать существующую системы и переделывать всё с нуля никто не даст. В том числе и потому, что сишечка. Если плюсы просто не скомпилировали бы, сишечка кушает и причмокивает.

Ну то есть раз в полгода-год пишется новый конвертер. И так уже 10-20 лет. Сдается мне, что проще и дешевле оставить все как есть и тратить 1-2 дня или неделю раз в полгода-год, чем мучиться сейчас писать "универсальный" конвертер, имея риск вообще все поломать, что уже много лет работает.
Патриот здравого смысла
Re[12]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.09.25 08:33
Оценка:
Здравствуйте, m2user, Вы писали:

M>>Как я понял, ты, если сделал v2 версию для A, зачем-то делаешь Inner_v2, и тогда надо лезть в B_v1, менять там на Inner_v2, и также надо поднимать версию и у B/


M>Нет, я говорил про сценарий, когда требуется новая версия для Inner. И в этом случае нужно повышать версии всех типов использующих Inner, напрямую (A и B) или опосредованно.

M>Объем необходимых изменений начинает зависеть от "развесистости" структур.

Не так значит понял. Да, само собой, повышать надо версию везде, где используется вложенная структура
Маньяк Робокряк колесит по городу
Re[8]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.09.25 08:36
Оценка:
Здравствуйте, DiPaolo, Вы писали:

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


DP>Ну то есть раз в полгода-год пишется новый конвертер. И так уже 10-20 лет. Сдается мне, что проще и дешевле оставить все как есть и тратить 1-2 дня или неделю раз в полгода-год, чем мучиться сейчас писать "универсальный" конвертер, имея риск вообще все поломать, что уже много лет работает.


Ну не знаю, народ прям вот задолбался. И проблема не только написать конвертер, проблема — не накосячить при написании конвертера
Маньяк Робокряк колесит по городу
Re[8]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.09.25 11:54
Оценка:
Здравствуйте, DiPaolo, Вы писали:

DP>Ну то есть раз в полгода-год пишется новый конвертер. И так уже 10-20 лет. Сдается мне, что проще и дешевле оставить все как есть и тратить 1-2 дня или неделю раз в полгода-год, чем мучиться сейчас писать "универсальный" конвертер, имея риск вообще все поломать, что уже много лет работает.


Похоже, про десятки лет я загнул
  Новость про недавно выпущенную отладочную плату для МК К1986ВУ024, датирована декабрём 23го


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

Но, похоже, таки почаще трахаться придётся
Маньяк Робокряк колесит по городу
Re: Челендж - сделать версионированный конфиг
От: watchmaker  
Дата: 15.09.25 10:32
Оценка:
Здравствуйте, Marty, Вы писали:


M>Вроде бы, protobuf что-то умеет в версионность, но: нам нужно уметь для каждого поля любой структуры получить его смещение относительно начала файла, чтобы писать непоредственно по этому смещению.



Дикое требование, лучше от него попробовать избавиться.
Protobuf широко использует varint, и даже найдя смещение, не факт, что получится по нему записать новое число, так как для него при кодировании может понадобится больше места, что потребует сдвинуть память, идущую следом. Но можно в protobuf использовать только fixed-size типы — у них длина всегда одинакова.

Впрочем у protobuf есть достойный конкурент — FlatBuffers. В нём внутри всё построено на операции "дай смещение в памяти для этого поля". И писать по полученному смещению тоже можно, если делать аккуратно. Хотя и не рекомендуется, потому что при неаккуратном использовании можешь задеть и испортить какие-то структуры самого flatbuffers, например.
Re: Челендж - сделать версионированный конфиг
От: Chorkov Россия  
Дата: 16.09.25 08:35
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Есть развесистые вложенные структуры. Хранится, допустим, просто в файле, как снимок памяти с корневой структурой. Всё структуры состоят из примитивных типов, вроде даже float'ов нет. Есть массивы, в тч и структур, исключительно фиксированного размера.


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


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

Это было бы проблемой и для текстового конфига.


Нужно уметь версионность на самом контролере, или можно иметь скрипты обновления конфигов на десктопе?
Сколько у нас вообще есть памяти под хранение мета информации о предыдущих версиях?
Re: Челендж - сделать версионированный конфиг
От: Miroff Россия  
Дата: 16.09.25 09:02
Оценка:
Здравствуйте, Marty, Вы писали:

M>ЗЫ Задача со звёздочкой — сделать на чистейшей сишечке.


Забить на реалтайм и генерить код в зависимости от настроек при сборке. Для микроконтроллера то что доктор прописал.
Re: Челендж - сделать версионированный конфиг
От: sergii.p  
Дата: 16.09.25 10:01
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Есть развесистые вложенные структуры. Хранится, допустим, просто в файле, как снимок памяти с корневой структурой. Всё структуры состоят из примитивных типов, вроде даже float'ов нет. Есть массивы, в тч и структур, исключительно фиксированного размера.


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


M>В общем, такое вот, историческое легаси.


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


M>Вроде бы, protobuf что-то умеет в версионность, но: нам нужно уметь для каждого поля любой структуры получить его смещение относительно начала файла, чтобы писать непоредственно по этому смещению.


M>Как вам такое?


хранить смещение поля и версию в constexpr справочниках. Дальше функцию трансформации написать с помощью ИИ

исходная структура
enum class Type {
    b8,   // bool
    i8,   // int8_t
    u8,   // uint8_t
    u32,  // uint32_t
    f32   // float
};

struct Entry {
    std::string_view name;
    Type type;
};

constexpr size_t NumFields = 3;
constexpr size_t NumVersions = 2;

constexpr std::array<Entry, NumFields> fields = {
    Entry{"id", Type::u8},
    Entry{"timestamp", Type::u32},
    Entry{"value", Type::f32}
};

constexpr std::array<std::array<std::optional<size_t>, NumVersions>, NumFields> offsets = {{
    {0, 0},             // id
    {std::nullopt, 4},  // timestamp (в старой версии поля не было, теперь появилось)
    {4, 8}              // value
}};


код от ИИ:

// 🔹 Получение размера типа
constexpr size_t typeSize(Type t) {
    switch (t) {
        case Type::b8:  return 1;
        case Type::i8:  return 1;
        case Type::u8:  return 1;
        case Type::u32: return 4;
        case Type::f32: return 4;
    }
    return 0;
}

// 🔹 Получение дефолтного значения
void writeDefault(std::ostream& out, Type t) {
    switch (t) {
        case Type::b8:  { bool v = false; out.write(reinterpret_cast<char*>(&v), sizeof(v)); break; }
        case Type::i8:  { int8_t v = 0; out.write(reinterpret_cast<char*>(&v), sizeof(v)); break; }
        case Type::u8:  { uint8_t v = 0; out.write(reinterpret_cast<char*>(&v), sizeof(v)); break; }
        case Type::u32: { uint32_t v = 0; out.write(reinterpret_cast<char*>(&v), sizeof(v)); break; }
        case Type::f32: { float v = 0.0f; out.write(reinterpret_cast<char*>(&v), sizeof(v)); break; }
    }
}

// 🔹 Основная функция трансформации
void transformRecord(size_t sourceVersion, std::istream& in, size_t targetVersion, std::ostream& out) {
    for (size_t i = 0; i < NumFields; ++i) {
        const auto& entry = fields[i];
        const auto& sourceOffset = offsets[i][sourceVersion];
        const auto& targetOffset = offsets[i][targetVersion];

        if (!targetOffset.has_value()) continue; // поле не входит в целевую версию

        // Перемещаемся в целевой поток на нужное место
        out.seekp(targetOffset.value(), std::ios::beg);

        if (sourceOffset.has_value()) {
            // Читаем из исходного потока
            in.seekg(sourceOffset.value(), std::ios::beg);
            size_t size = typeSize(entry.type);
            char buffer[8] = {}; // максимум 8 байт
            in.read(buffer, size);
            if (!in) throw std::runtime_error("Failed to read field: " + std::string(entry.name));
            out.write(buffer, size);
        } else {
            // Пишем дефолтное значение
            writeDefault(out, entry.type);
        }
    }
}
Re: Челендж - сделать версионированный конфиг
От: ksandro Мухосранск  
Дата: 19.09.25 15:30
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Есть развесистые вложенные структуры. Хранится, допустим, просто в файле, как снимок памяти с корневой структурой. Всё структуры состоят из примитивных типов, вроде даже float'ов нет. Есть массивы, в тч и структур, исключительно фиксированного размера.


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


M>В общем, такое вот, историческое легаси.


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


M>Вроде бы, protobuf что-то умеет в версионность, но: нам нужно уметь для каждого поля любой структуры получить его смещение относительно начала файла, чтобы писать непоредственно по этому смещению.


M>Как вам такое?



M>ЗЫ Задача со звёздочкой — сделать на чистейшей сишечке.


M>ЗЫЫ Внешние инструменты не очень приветствуются, но можно попробовать написать что-то на питоне, и к питону наверное даже можно доустановить каких-то библиотек, помимо того, что идёт в базе, если это не слишком гемморно.


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

Но вообще бинарныой конфиг это жуткий гемор. Я бы рекомендовал действовать радикально и разом переписать в какой-то текстовый формат.
Re[2]: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 19.09.25 19:04
Оценка:
Здравствуйте, ksandro, Вы писали:

K>Но вообще бинарныой конфиг это жуткий гемор. Я бы рекомендовал действовать радикально и разом переписать в какой-то текстовый формат.


У меня 16 Кб на всё про всё, а полей несколько сотен
Маньяк Робокряк колесит по городу
Re: Челендж - сделать версионированный конфиг
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 06.10.25 20:31
Оценка:
Здравствуйте, Marty, Вы писали:

Почти сделал.

Использовал CastXML.

Для фана сгенерил GraphViz'ом визуализацию структур конфига

  Скрытый текст


Маньяк Робокряк колесит по городу
Отредактировано 06.10.2025 21:21 Marty . Предыдущая версия .
Re: Челендж - сделать версионированный конфиг
От: Слава  
Дата: 07.10.25 08:18
Оценка:
Здравствуйте, Marty, Вы писали:

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


Вот здесь @RONrussian в телеграме поищите по запросу RDX. Вопросы именно хранения на глупом чипе там не рассматривают, но всё версионирование есть.
Отредактировано 07.10.2025 8:23 Слава . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.