All streams
Search
Write a publication
Pull to refresh
206
0.4
Send message

А почему бы у Claude не спросить как делать загрузчики?
Агенты такие вещи сейчас мгновенно делают

Вот, например, мне за день с учетом отладки Claude вот такой загрузчик по CAN сделал https://github.com/Indemsys/Landing_controller_LNDC_bootloader/blob/main/src/CAN_Bootloader/can_bootloader.c
Причем с глубокой трассировкой и исчерпывающими коментариями.

И еще полную спецификацию написал -
https://github.com/Indemsys/Landing_controller_LNDC_bootloader/blob/main/src/CAN_Bootloader/README.md

По этой спецификации он написал потом менеджер загрузки для центрального контроллера.
Там же моментом и скрипты для загрузки с ПК написал.

Шифрация , сжатие, и подпись по ECDSA (Elliptic Curve Digital Signature Algorithm) тоже были, но убраны.

В этом смысле мне очень нравится цитата из книги
Ha-Joon Chang "Economics:The User's Guide"

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


Так есть ли смысл умничать про деньги?

Тут вы просто противоречите повсеместному эмпирическому опыту.

Свой код от Claude я тоже могу объявить библиотекой и сказать какие у него незаменимые фичи типа: "поля можно объявить optional с дефолтами". Он ракетой такие либы умеет делать. Хуже. Что ни попроси, он всегда накидывает лишнего API, чтобы сразу полная либа получилась.

Вообще, где доказательства, что ваша либа не от Claude или чего-то подобного?
Бросайте это. Либы на коленке в ближайшие тысячу лет никому не будут нужны.
Лучше опубликуйте полезное приложение с применением JSON. Вот тогда будет понятно, что имеем дело с человеческим трудом.

Извините, не знал что вы разработчик всех "индустриальных MCU/RTOS-проектов".
Шучу.

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

Так вот  jansson избавляет от многих хлопот.

Я пишу исключительно на голом С и вот десериализатор сгенеренный целиком Claude на основе API jansson - https://github.com/Indemsys/MC80_4DC/blob/main/src/Parameters/Parameters_deserializer.c
А еще есть сериализатор, и еще есть куча мест где идет парсинг JSON.

А у тому клоню, что нет нынче никакой необходимости создавать обертки над такими эффективными и прозрачными либами как jansson.
Claude создаст весь прикладной код на лету на нативном API и под любой вкус. Была бы ему либа эта вся задокументрирована.

А вот когда одна либа поверх другой, а та поверх третьей, вот тут вы реально стреляете себе в ногу. Раздуваете контекст, усложняете работу агентам и запутываете их. Потом остается только пенять на заточенность под "STL, шаблоны и типичные C++-механизмы"

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

Код Jansson: ~5,3 КБ.

Глобальные данные / константы: ≈0 Б.

Куча: все JSON-объекты (json_object, json_array, строки и т.п.) аллоцируются через malloc. malloc надо портировать через свое API, поэтому тут свобода реализации. В ThreadX, например malloc умеет делать статистику и ожидать освобождения памяти заданное время.

Пример: пустой json_object ≈ 32–64 байта + хэш-таблица.

Каждая строка хранится отдельно (длина + копия текста). Сколько сырой JSON без пробелов занимает, столько памяти приблизительно и нужно будет

По стеку. Там рекурсивный парсинг. Одна функция разбора (parse_value/parse_object/parse_array) тянет локальные переменные порядка 16–32 байт. Глубина рекурсии = глубине вложенности JSON. Но это контролируется, потому что глубину разбора задает макрос.

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

Непонятно что тут означает "контролируемая работа с памятью".
Если есть неизвестный JSON в котором надо что-то выловить, то парсить дерево нужно. И без динамической памяти никак. И откуда там утечки если библиотека протестирована.
Динамическая память - это всегда фрагментация, и риск потери чистой памяти.
Но проблема решается элементарно просто наложением мьютека на выделение памяти другими задачами на время парсинга JSON.
Я бы конечно рекомендовал https://github.com/akheron/jansson
В современной реальности самые лучшие библиотеке - это те что понятны и доступны для кодирующих агентов.
Так вот с jansson агент Claude работает безукоризненно. Может построить парсигн и генерацию любого дерева. Делает практически безошибочно. Это то, что агенты с самого начала научились хорошо делать.

Чел забыл упомянуть, что свой SLIP он прогоняет через RP2040, а потом через PC чтобы достичь интернета.
Обкурился?

Это вот эта что-ли:


Это ни о чем.
Где сравнение с реальными GPS модулями. Где расходы трасивера на связь с облаком? Где расходы на работу процессора, шифрацию и прочие? А на джаминг?

Зыбко все это.

Там вся статья про это. Но где цифры? Где статистика?

Я только не понял где то самое потребление ради которого вся эта заваруха?

Есть тут лукавства.

Claude Sonnet в качестве агента стал нормально кодить всего несколько месяцев назад.
Функция делегирования агенту в облака на сам GitHub скажем в GitHub Copilot появилось вообще пару дней назад.

А главное - агенты еще очень медленно работают. Ожидание в пару минут на простые запросы просто тормозит работу. Никогда не угадаеш когда он тормознет.
Да и сборщики еще очень медленные.

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

Я считаю что ускорение с агентами реально достигает 5-10 раз. Но при условии отлаженного рабочего процесса и дорогого плана.

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

Но самая песня тут будет с беспроводной связью.
Говорят телеграмам на ладан дышит и во многих странах его собираются банить, сам телеграм может банить подозрительный нецелевой тафик. Как банят теперь емайлы.
Но это не самое больное. Самое больное - это зависания точек доступа.
Этому дивайсику следовало бы еще научится сбрасывать помимо котла еще и свою точку доступа. А еще научится как-то менять каналы W-Fi в поисках свободных. А лучше иметь резервные AP на объекте. Антенка тоже так себе, лучше бы внешнюю.
Самое то смешное что дивайс должен стабильно работать при сбоях в электросети, но эти сбои даже миллисекундные и никем не замеченные первыми убивают роутеры.

Ардуина просто избыточна и переусложнена.
У ардуин цель - образование. Поэтому там много лишнего в виде голых пинов, отдельных не адаптированых и не оптимальных плат и специфичных перенасыщенных абстрактных API библиотек.
Открываешь страницу проекта Arduino и тебя сразу встречает море разных платок и модулей.
С другой стороны экосистема ардуино скатывается в область индустриальных систем и там оказывается не имеет никаких преимуществ. Схема закрыта, микроконтроллер STM32H747XIH6 - сверхнавороченный, никакой ардуинщик не возьмется его изучать (а если возьмется, то перестанет быть ардуинщиком ).
Проще напрямик взять референс дизайны у ST и делать на них.

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

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

За плавное замедление отвечает частотный преобразователь. Контроллер лифта к нему отношения не имеет.

В этом сила гибридных схем. Да, они кажутся простыми и сразу понятными. Сразу ясно что там надо 100 строчек.
А к Муру у вас сразу притензии. Не там поставил видиш ли надписи. Надо их куда убирать. А это рассеивает внимание и т.д.

Но вот вам на самом деле скрипт кторый скрывается за простенькими условиями типа Wrong Direction на диаграмме StateFlow (там уже 253 строки)

Скрипт MATLAB
function [IsOverCurrent, IsAccV_good, IsSysV_good, IsPSRC_ON, IsDischarging, IsPGood, IsWrongDirection] = ...
    Charging_handler(CHRG_IN, CHRG_SETS)

% Charging_handler - Functions for charging system state monitoring
% This script implements the Stateflow functions for charging control
%
% Inputs:
%   CHRG_IN - Structure containing charging input signals:
%     .charge_current    - Current charging current value
%     .accum_voltage     - Accumulator voltage value
%     .system_voltage    - System voltage value
%     .power_src_current - Power source current value
%     .discharge_current - Current discharge current value
%     .charger_pgood     - Charger power good signal
%   CHRG_SETS - Structure containing charging settings:
%     .accum_capacity     - Accumulator capacity (Ah)
%     .accum_idle_voltage - Accumulator idle voltage (V)
%     .accum_max_voltage  - Maximum accumulator voltage (V)
%     .accum_max_current  - Maximum accumulator current (A)
%
% Outputs:
%   IsOverCurrent   - TRUE if charging current exceeds maximum allowed
%   IsAccV_good     - TRUE if accumulator voltage is within valid range
%   IsSysV_good     - TRUE if system voltage is above minimum threshold
%   IsPSRC_ON       - TRUE if power source current is detected
%   IsDischarging   - TRUE if discharge current exceeds charge current for specified time
%   IsPGood         - TRUE if charger power good signal is active for specified time
%   IsWrongDirection- TRUE if power flows in wrong direction (battery discharging while external power > 27V for 2 sec)

% --- Charging system settings (constants) ---
% Voltage thresholds
ACCUM_MIN_VOLTAGE = single(15.0);              % Minimum accumulator voltage
SYSTEM_MIN_VOLTAGE = single(24.0);             % Minimum system voltage

% Discharge detection settings
DISCHARGE_TIME_DELAY = int32(100);             % Time delay for discharge detection (in 10ms ticks, 100 = 1 second)

% PGood detection settings
PGOOD_TIME_DELAY = int32(50);                  % Time delay for PGood detection (in 10ms ticks, 50 = 0.5 second)

% Wrong direction power flow detection settings
WRONG_DIR_VOLTAGE_THRESHOLD = single(27.0);   % External power voltage threshold (V)
WRONG_DIR_TIME_DELAY = int32(200);            % Time delay for wrong direction detection (in 10ms ticks, 200 = 2 seconds)

% --- Persistent variables for discharge timing ---
persistent discharge_timer discharge_active
persistent pgood_timer pgood_active pgood_reset_timer pgood_reset_active
persistent wrong_dir_timer wrong_dir_active
if isempty(discharge_timer)
    discharge_timer = int32(0);
    discharge_active = false;
    pgood_timer = int32(0);
    pgood_active = false;
    pgood_reset_timer = int32(0);
    pgood_reset_active = false;
    wrong_dir_timer = int32(0);
    wrong_dir_active = false;
end

%-------------------------------------------------------------
% IsOverCurrent - Check if charging current exceeds maximum
%-------------------------------------------------------------
IsOverCurrent = false;
if single(CHRG_IN.charge_current) > (single(CHRG_SETS.accum_max_current) + single(2.0))
    IsOverCurrent = true;
end

%-------------------------------------------------------------
% IsAccV_good - Check if accumulator voltage is in valid range
%-------------------------------------------------------------
IsAccV_good = false;
if (single(CHRG_IN.accum_voltage) > ACCUM_MIN_VOLTAGE) && ...
   (single(CHRG_IN.accum_voltage) < (single(CHRG_SETS.accum_max_voltage) + single(2.0)))
    IsAccV_good = true;
end

%-------------------------------------------------------------
% IsSysV_good - Check if system voltage is above minimum
%-------------------------------------------------------------
IsSysV_good = false;
if single(CHRG_IN.system_voltage) > SYSTEM_MIN_VOLTAGE
    IsSysV_good = true;
end

%-------------------------------------------------------------
% IsPSRC_ON - Check if power source is active
%-------------------------------------------------------------
IsPSRC_ON = false;
if single(CHRG_IN.power_src_current) > single(0)
    IsPSRC_ON = true;
end

%-------------------------------------------------------------
% IsDischarging - Check if discharge current exceeds charge current for specified time
%-------------------------------------------------------------
persistent IsDischarging_state
if isempty(IsDischarging_state)
    IsDischarging_state = false;
end

IsDischarging = IsDischarging_state;

% Check current state based on which current is higher
if single(CHRG_IN.discharge_current) > single(CHRG_IN.charge_current)
    % Discharge current is higher - trending towards discharge state
    if ~IsDischarging_state
        % Currently in charging state, check if we should switch to discharge
        if ~discharge_active
            % Start timing for discharge state
            discharge_active = true;
            discharge_timer = int32(0);
        else
            % Increment timer (count 10ms ticks)
            discharge_timer = discharge_timer + int32(1);

            % Check if delay time has elapsed
            if discharge_timer >= DISCHARGE_TIME_DELAY
                IsDischarging_state = true;
                IsDischarging = true;
                discharge_active = false;
                discharge_timer = int32(0);
            end
        end
    else
        % Already in discharge state - stay there
        discharge_active = false;
        discharge_timer = int32(0);
    end
else
    % Charge current is higher - trending towards charging state
    if IsDischarging_state
        % Currently in discharge state, check if we should switch to charging
        if ~discharge_active
            % Start timing for charging state
            discharge_active = true;
            discharge_timer = int32(0);
        else
            % Increment timer (count 10ms ticks)
            discharge_timer = discharge_timer + int32(1);

            % Check if delay time has elapsed
            if discharge_timer >= DISCHARGE_TIME_DELAY
                IsDischarging_state = false;
                IsDischarging = false;
                discharge_active = false;
                discharge_timer = int32(0);
            end
        end
    else
        % Already in charging state - stay there
        discharge_active = false;
        discharge_timer = int32(0);
    end
end

%-------------------------------------------------------------
% IsPGood - Check if charger power good signal is active for specified time
%-------------------------------------------------------------
persistent IsPGood_state
if isempty(IsPGood_state)
    IsPGood_state = false;
end

IsPGood = IsPGood_state;

% Check if charger power good signal is active
if single(CHRG_IN.charger_pgood) > single(0)
    % Reset the reset timer when pgood signal is active
    pgood_reset_active = false;
    pgood_reset_timer = int32(0);

    if ~pgood_active
        % Start timing when signal becomes active
        pgood_active = true;
        pgood_timer = int32(0);
    else
        % Increment timer (count 10ms ticks)
        pgood_timer = pgood_timer + int32(1);

        % Check if delay time has elapsed
        if pgood_timer >= PGOOD_TIME_DELAY
            IsPGood_state = true;
            IsPGood = true;
        end
    end
else
    % Signal is inactive - reset pgood timer
    pgood_active = false;
    pgood_timer = int32(0);

    % Start reset timer only if currently in pgood state
    if IsPGood_state
        if ~pgood_reset_active
            % Start timing for reset
            pgood_reset_active = true;
            pgood_reset_timer = int32(0);
        else
            % Increment reset timer
            pgood_reset_timer = pgood_reset_timer + int32(1);

            % Check if reset delay time has elapsed
            if pgood_reset_timer >= PGOOD_TIME_DELAY
                IsPGood_state = false;
                IsPGood = false;
                pgood_reset_active = false;
                pgood_reset_timer = int32(0);
            end
        end
    end
end

%-------------------------------------------------------------
% IsWrongDirection - Check if power flows in wrong direction
% (battery discharging while external power > 27V for 2 seconds)
%-------------------------------------------------------------
persistent IsWrongDirection_state
if isempty(IsWrongDirection_state)
    IsWrongDirection_state = false;
end

IsWrongDirection = IsWrongDirection_state;

% Check if external power voltage > 27V and discharge current > 0
if (single(CHRG_IN.system_voltage) > WRONG_DIR_VOLTAGE_THRESHOLD) && ...
   (single(CHRG_IN.discharge_current) > single(0))

    if ~wrong_dir_active
        % Start timing when conditions are first met
        wrong_dir_active = true;
        wrong_dir_timer = int32(0);
    else
        % Increment timer (count 10ms ticks)
        wrong_dir_timer = wrong_dir_timer + int32(1);

        % Check if delay time has elapsed (2 seconds)
        if wrong_dir_timer >= WRONG_DIR_TIME_DELAY
            IsWrongDirection_state = true;
            IsWrongDirection = true;
        end
    end
else
    % Conditions not met - reset immediately if discharge current is zero
    wrong_dir_active = false;
    wrong_dir_timer = int32(0);

    % Reset state immediately when discharge current becomes zero
    if single(CHRG_IN.discharge_current) <= single(0)
        IsWrongDirection_state = false;
        IsWrongDirection = false;
    end
end

end

И тут сразу станет ясно, что на диаграмме изображена только вершина айсберга.
А на Муре пришлось бы весь айсберг рисовать. Т.е. заниматься сизифовым трудом.
Диаграмма Мура которую я дал, конечно не является таковой. В реале она должна стать монструозной и совершенно нечитаемой чтобы отразить в точности диаграмму StateFlow.

А вот управление лифта на контроллере проще чем Arduino

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

Ну сравните нотацию в стиле автомата Мура


И гибридную нотацию StateFlow того же алгоритма

Кто понятней?

1
23 ...

Information

Rating
2,062-nd
Registered
Activity