From 4c78383edf4e9f0655d4ca83fcd964490616cb01 Mon Sep 17 00:00:00 2001 From: Razvalyaev Date: Mon, 16 Jun 2025 00:28:13 +0300 Subject: [PATCH] =?UTF-8?q?=D1=87=D1=83=D1=82=D1=8C=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B3=D0=BE=20=D0=BD=D0=BE=20=D0=BD=D0=B0=D0=B4=D0=BE=20?= =?UTF-8?q?=D0=B5=D1=89=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit перенести работу с конфигом в отдельную папку и реализовать конфиг для всего симулятора. Чтобы можно было легко переносить настройки оболочки --- McuLib/lib/McuLib.slx | Bin 23010 -> 22922 bytes McuLib/m/compiler.m | 2 +- McuLib/m/periphConfig.m | 521 +++++++++++++++++++--------------------- 3 files changed, 248 insertions(+), 275 deletions(-) diff --git a/McuLib/lib/McuLib.slx b/McuLib/lib/McuLib.slx index 7aa79c6315614cbe968ab7401d988a4e7619f737..422bd2b7eb684abcd6d905066b9691ce1c818b4d 100644 GIT binary patch delta 11269 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 delta 11313 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 diff --git a/McuLib/m/compiler.m b/McuLib/m/compiler.m index dc05feb..2a0f39f 100644 --- a/McuLib/m/compiler.m +++ b/McuLib/m/compiler.m @@ -55,7 +55,7 @@ classdef compiler % Записываем результат res = compiler.updateRunMexBat(wrapperSrcText, wrapperIncText, ':: APP WRAPPER BAT'); % Всё прошло успешно - + periphConfig.updatePeriphRunMexBat(); end diff --git a/McuLib/m/periphConfig.m b/McuLib/m/periphConfig.m index c5c6e9a..528fce5 100644 --- a/McuLib/m/periphConfig.m +++ b/McuLib/m/periphConfig.m @@ -56,7 +56,7 @@ classdef periphConfig periphConfig.create_all_code_storage_params(blockPath, config); % periphConfig.cleanup_obsolete_code_params(blockPath, config); - periphConfig.update_all(); + periphConfig.update(); % Восстанавлиperiph = allTabNamesваем таблицы customtable.restore_all_tables(tableNames, columns_backup); @@ -70,6 +70,146 @@ classdef periphConfig % end end + function update() + blockPath = gcb; + mask = Simulink.Mask.get(blockPath); + + config = periphConfig.read_config(blockPath); + containerName = 'configTabAll'; + container = mask.getDialogControl(containerName); + paramsAll = mcuMask.collect_all_parameters(container); + % Получаем все имена в кладок из container (у вас должен быть container) + allTabs = container.DialogControls; + allTabNames = arrayfun(@(t) t.Name, allTabs, 'UniformOutput', false); + + fieldsConfig = fieldnames(config); + % Цикл по всем вкладкам в контейнере + for i = 1:length(allTabNames) + periph = fieldsConfig{i}; + + % Попытка найти параметр чекбокса Tab__Enable + checkboxName = ['Tab_' periph '_Enable']; + if ismember(checkboxName, paramsAll) + % Чекбокс есть - проверяем его состояние + paramObj = mask.getParameter(checkboxName); + val = paramObj.Value; + + try + tab = container.getDialogControl(periph); + if strcmpi(val, 'off') + tab.Enabled = 'off'; + % Рекурсивно очищаем связанные скрытые параметры + periphConfig.clear_tab_params(mask, config.(periph), periph); + else + tab.Enabled = 'on'; + periphConfig.sync_tab_params(mask, config.(periph), periph); + end + catch + warning('Вкладка с именем "%s" не найдена.', periph); + end + + else + % Чекбокса нет — просто пытаемся включить вкладку, если она есть + try + tab = container.getDialogControl(periph); + tab.Enabled = 'on'; + % Опционально можно синхронизировать параметры, если есть config поле + if isfield(config, periph) + periphConfig.sync_tab_params(mask, config.(periph), periph); + end + catch + % Можно не выводить предупреждение — вкладка может быть необязательной + % warning('Вкладка с именем "%s" не найдена.', periph); + end + end + end + + end + + function periphParamCallback(paramName) + blockPath = gcb; + mask = Simulink.Mask.get(blockPath); + hObj = mask.getParameter(paramName); + config = periphConfig.read_config(blockPath); + container = mask.getDialogControl('configTabAll'); + + % === Проверка на Tab__Enable === + exprTab = '^Tab_(\w+)_Enable$'; + tokensTab = regexp(paramName, exprTab, 'tokens'); + + if ~isempty(tokensTab) + periph = tokensTab{1}{1}; + + try + tab = container.getDialogControl(periph); + paramVal = hObj.Value; + + if strcmpi(paramVal, 'off') + tab.Enabled = 'off'; + if isfield(config, periph) + periphConfig.clear_tab_params(mask, config.(periph), periph); + end + else + tab.Enabled = 'on'; + if isfield(config, periph) + periphConfig.sync_tab_params(mask, config.(periph), periph); + end + end + catch + warning('Ошибка обработки вкладки "%s".', periph); + end + return; + end + + % === Проверка на параметр, связанный с Sources/Includes === + % Проверка: это параметр, у которого есть соответствующий Hidden__Sources или Hidden__Includes + nameBase = paramName; + + paramNames = string({mask.Parameters.Name}); + hasSources = any(paramNames == "Hidden_" + nameBase + "_Sources"); + hasIncludes = any(paramNames == "Hidden_" + nameBase + "_Includes"); + + + if hasSources || hasIncludes + useVal = hObj.Value; + + % Получаем содержимое config по nameBase — возможно, вложенное + try + valueStruct = periphConfig.get_field(config, nameBase); + catch + warning('Не удалось найти путь %s в config.', nameBase); + return; + end + + if strcmpi(useVal, 'on') + try + periphConfig.store_single_periph_code(mask, nameBase, valueStruct); + catch + warning('Не удалось сохранить параметры для %s.', nameBase); + end + else + periphConfig.clear_single_periph_code_param(mask, nameBase); + end + + return; + end + + + % === Если не подошло ни под одно из условий === + % warning('Объект "%s" не поддерживается универсальным коллбеком.', paramName); + end + + function updatePeriphRunMexBat() + % Запись run_mex.bat + blockPath = gcb; + CodeStruct = periphConfig.restore_periph_code_from_mask(blockPath); + periphPath = mcuPath.get('periphPath'); + [periphPath, ~, ~] = fileparts(periphPath); + + periphConfig.addCodeBat(CodeStruct, periphPath); + end + + function config = update_config(blockPath, config) if isempty(config) return; @@ -159,158 +299,7 @@ classdef periphConfig fclose(fid); end - function update_all() - blockPath = gcb; - mask = Simulink.Mask.get(blockPath); - config = periphConfig.read_config(blockPath); - containerName = 'configTabAll'; - container = mask.getDialogControl(containerName); - paramsAll = mcuMask.collect_all_parameters(container); - % Получаем все имена в кладок из container (у вас должен быть container) - allTabs = container.DialogControls; - allTabNames = arrayfun(@(t) t.Name, allTabs, 'UniformOutput', false); - - fieldsConfig = fieldnames(config); - % Цикл по всем вкладкам в контейнере - for i = 1:length(allTabNames) - periph = fieldsConfig{i}; - - % Попытка найти параметр чекбокса Tab__Enable - checkboxName = ['Tab_' periph '_Enable']; - if ismember(checkboxName, paramsAll) - % Чекбокс есть - проверяем его состояние - paramObj = mask.getParameter(checkboxName); - val = paramObj.Value; - - try - tab = container.getDialogControl(periph); - if strcmpi(val, 'off') - tab.Enabled = 'off'; - % Рекурсивно очищаем связанные скрытые параметры - periphConfig.clear_tab_params(mask, config.(periph), periph); - else - tab.Enabled = 'on'; - periphConfig.sync_tab_params(mask, config.(periph), periph); - end - catch - warning('Вкладка с именем "%s" не найдена.', periph); - end - - else - % Чекбокса нет — просто пытаемся включить вкладку, если она есть - try - tab = container.getDialogControl(periph); - tab.Enabled = 'on'; - % Опционально можно синхронизировать параметры, если есть config поле - if isfield(config, periph) - periphConfig.sync_tab_params(mask, config.(periph), periph); - end - catch - % Можно не выводить предупреждение — вкладка может быть необязательной - % warning('Вкладка с именем "%s" не найдена.', periph); - end - end - end - - periphConfig.getWrapperCode(); - end - - - - - - - function update_callback(paramName) - blockPath = gcb; - mask = Simulink.Mask.get(blockPath); - hObj = mask.getParameter(paramName); - config = periphConfig.read_config(blockPath); - container = mask.getDialogControl('configTabAll'); - - % === Проверка на Tab__Enable === - exprTab = '^Tab_(\w+)_Enable$'; - tokensTab = regexp(paramName, exprTab, 'tokens'); - - if ~isempty(tokensTab) - periph = tokensTab{1}{1}; - - try - tab = container.getDialogControl(periph); - paramVal = hObj.Value; - - if strcmpi(paramVal, 'off') - tab.Enabled = 'off'; - if isfield(config, periph) - periphConfig.clear_tab_params(mask, config.(periph), periph); - end - else - tab.Enabled = 'on'; - if isfield(config, periph) - periphConfig.sync_tab_params(mask, config.(periph), periph); - end - end - catch - warning('Ошибка обработки вкладки "%s".', periph); - end - - periphConfig.getWrapperCode(); - return; - end - - % === Проверка на параметр, связанный с Sources/Includes === - % Проверка: это параметр, у которого есть соответствующий Hidden__Sources или Hidden__Includes - nameBase = paramName; - - paramNames = string({mask.Parameters.Name}); - hasSources = any(paramNames == "Hidden_" + nameBase + "_Sources"); - hasIncludes = any(paramNames == "Hidden_" + nameBase + "_Includes"); - - - if hasSources || hasIncludes - useVal = hObj.Value; - - % Получаем содержимое config по nameBase — возможно, вложенное - try - valueStruct = periphConfig.get_field(config, nameBase); - catch - warning('Не удалось найти путь %s в config.', nameBase); - return; - end - - if strcmpi(useVal, 'on') - try - periphConfig.store_single_periph_code(mask, nameBase, valueStruct); - catch - warning('Не удалось сохранить параметры для %s.', nameBase); - end - else - periphConfig.clear_single_periph_code_param(mask, nameBase); - end - - periphConfig.getWrapperCode(); - return; - end - - - % === Если не подошло ни под одно из условий === - % warning('Объект "%s" не поддерживается универсальным коллбеком.', paramName); - end - - - - - - - function getWrapperCode() - blockPath = gcb; - CodeStruct = periphConfig.restore_periph_code_from_mask(blockPath); - periphPath = mcuPath.get('periphPath'); - [periphPath, ~, ~] = fileparts(periphPath); - - periphConfig.addCodeBat(CodeStruct, periphPath); - - end end @@ -372,39 +361,6 @@ classdef periphConfig end end - - function short = get_final_name_from_prefix(prefix) - % Берёт последнее имя после "_" (читаемое имя) - parts = strsplit(prefix, '_'); - short = parts{end}; - end - - - function value = get_field(configStruct, targetConfig) - value = []; - fields = fieldnames(configStruct); - - for i = 1:numel(fields) - key = fields{i}; - if strcmp(key, targetConfig) - value = configStruct.(key); - return; % нашли и возвращаем - elseif isstruct(configStruct.(key)) - value = periphConfig.get_field(configStruct.(key), targetConfig); - if ~isempty(value) - return; % нашли во вложенной структуре - end - end - end - - % Если не нашли, можно выбросить ошибку или вернуть пустое - if isempty(value) - % error('Поле "%s" не найдено в структуре.', targetConfig); - end - end - - - function create_all_code_storage_params(blockPath, config) mask = Simulink.Mask.get(blockPath); @@ -454,26 +410,6 @@ classdef periphConfig end - - function addHiddenParam(mask, containerName, nameBase, kind, existingParams) - % Преобразуем к красивому имени - prettyName = strrep(nameBase, '_', ' '); - paramName = ['Hidden_' nameBase '_' kind]; - if ismember(paramName, existingParams) - return; - end - - mask.addParameter( ... - 'Name', paramName, ... - 'Type', 'edit', ... - 'Prompt', ['Hidden ' prettyName ' ' kind], ... - 'Value', '', ... - 'Visible', 'off', ... - 'Container', containerName ... - ); - fprintf('Создан скрытый параметр: %s\n', paramName); - end - function cleanup_obsolete_code_params(blockPath, config) mask = Simulink.Mask.get(blockPath); maskParams = mask.Parameters; @@ -552,66 +488,38 @@ classdef periphConfig codeStruct.Includes = allIncludes; end - function clear_single_periph_code_param(mask, periph) - % Формируем имена параметров - paramNames = { - ['Hidden_' periph '_Sources'], - ['Hidden_' periph '_Includes'] - }; - for i = 1:numel(paramNames) - paramName = paramNames{i}; - try - param = mask.getParameter(paramName); - param.Value = ''; - catch - % Параметр не существует — ничего не делаем - end + function clear_all_from_container(mask, containerName) + % allControls = mask.getDialogControls(); + container = mask.getDialogControl(containerName); + if isempty(container) + warning('Контейнер "%s" не найден.', containerName); + return; end - end - - function store_single_periph_code(mask, periph, code) - % Сохраняем Sources, если они есть - if isfield(code, 'Sources') - paramName = ['Hidden_' char(periph) '_Sources']; + + % Рекурсивно собрать все параметры (не вкладки) + paramsToDelete = mcuMask.collect_all_parameters(container); + + % Удаляем все параметры + for i = 1:numel(paramsToDelete) try - param = mask.getParameter(paramName); - param.Value = periphConfig.convert_code_value(code.Sources); + mask.removeParameter(paramsToDelete{i}); catch - mcuMask.disp(0, ['Параметр ' paramName ' не найден']); + warning('Не удалось удалить параметр %s', paramsToDelete{i}); end end - % Сохраняем Includes, если они есть - if isfield(code, 'Includes') - paramName = ['Hidden_' periph '_Includes']; - try - param = mask.getParameter(paramName); - param.Value = periphConfig.convert_code_value(code.Includes); - catch - mcuMask.disp(0, ['Параметр ' paramName ' не найден']); - end - end - end - - - function value = convert_code_value(codeField) - % Преобразует значение поля Options в строку - if ischar(codeField) - value = codeField; - elseif isstring(codeField) - value = char(codeField); - elseif iscell(codeField) - value = strjoin(codeField, newline); - else - % warning('Неподдерживаемый тип данных: сохранено как пустая строка'); - value = ''; - end + % Рекурсивно удалить все вкладки внутри контейнера + mcuMask.delete_all_tabs(mask, container); end + + + function res = addCodeBat(codeConfig, codePath) + % Добавить сурсы и пути в батник % Возвращает 0 при успехе, 1 при ошибке try % Формируем строки @@ -626,8 +534,8 @@ classdef periphConfig end end - function res = addUserFunctions(userCodeConfig) + % Добавить функции и дефайны в исходный код wrapper % userCodeConfig — структура config.UserCode initFuncsText = ''; @@ -652,12 +560,11 @@ classdef periphConfig deinitFuncsText = strjoin(strcat('\t', deinitFuncs, ';'), '\n'); end - res = periphConfig.updateWrapperCode(initFuncsText, simFuncsText, deinitFuncsText); + res = periphConfig.writeWrapperCode(initFuncsText, simFuncsText, deinitFuncsText); end end - - function res = updateWrapperCode(initFuncsText, simFuncsText, deinitFuncsText) + function res = writeWrapperCode(initFuncsText, simFuncsText, deinitFuncsText) % Входные параметры: % srcText - текст для записи set code_... % incText - текст для записи set includes_... @@ -686,7 +593,7 @@ classdef periphConfig error('Ошибка: неудачная запись в файл при записи файла: %s', ME.message); end end - + function addConfig(mask, containerName, periphName, defPrompt, def, rowCountMap, rowWidth) % mask — объект маски Simulink.Mask.get(blockPath) % containerName — имя контейнера, в который добавляем параметр (например, 'configTabAll') @@ -791,33 +698,99 @@ classdef periphConfig end end - callback = sprintf('periphConfig.update_callback("%s");', paramName); + callback = sprintf('periphConfig.periphParamCallback("%s");', paramName); param.Callback = callback; end - function clear_all_from_container(mask, containerName) - % allControls = mask.getDialogControls(); - container = mask.getDialogControl(containerName); - if isempty(container) - warning('Контейнер "%s" не найден.', containerName); - return; - end + + %% ELEMENTARY - % Рекурсивно собрать все параметры (не вкладки) - paramsToDelete = mcuMask.collect_all_parameters(container); + function clear_single_periph_code_param(mask, periph) + % Очистка кода одного поля конфига + paramNames = { + ['Hidden_' periph '_Sources'], + ['Hidden_' periph '_Includes'] + }; - % Удаляем все параметры - for i = 1:numel(paramsToDelete) + for i = 1:numel(paramNames) + paramName = paramNames{i}; try - mask.removeParameter(paramsToDelete{i}); + param = mask.getParameter(paramName); + param.Value = ''; catch - warning('Не удалось удалить параметр %s', paramsToDelete{i}); + % Параметр не существует — ничего не делаем + end + end + end + + function store_single_periph_code(mask, periph, code) + % Запись кода одного поля конфига + % Сохраняем Sources, если они есть + if isfield(code, 'Sources') + paramName = ['Hidden_' char(periph) '_Sources']; + try + param = mask.getParameter(paramName); + param.Value = periphConfig.convert_code_value(code.Sources); + catch + mcuMask.disp(0, ['Параметр ' paramName ' не найден']); end end - % Рекурсивно удалить все вкладки внутри контейнера - mcuMask.delete_all_tabs(mask, container); + % Сохраняем Includes, если они есть + if isfield(code, 'Includes') + paramName = ['Hidden_' periph '_Includes']; + try + param = mask.getParameter(paramName); + param.Value = periphConfig.convert_code_value(code.Includes); + catch + mcuMask.disp(0, ['Параметр ' paramName ' не найден']); + end + end + end + + function value = get_field(configStruct, targetConfig) + % получить targetConfig структуру из конфига (для глубоко вложенных) + value = []; + fields = fieldnames(configStruct); + + for i = 1:numel(fields) + key = fields{i}; + if strcmp(key, targetConfig) + value = configStruct.(key); + return; % нашли и возвращаем + elseif isstruct(configStruct.(key)) + value = periphConfig.get_field(configStruct.(key), targetConfig); + if ~isempty(value) + return; % нашли во вложенной структуре + end + end + end + + % Если не нашли, можно выбросить ошибку или вернуть пустое + if isempty(value) + % error('Поле "%s" не найдено в структуре.', targetConfig); + end + end + + function short = get_final_name_from_prefix(prefix) + % Берёт последнее имя после "_" (читаемое имя) + parts = strsplit(prefix, '_'); + short = parts{end}; + end + + function value = convert_code_value(codeField) + % Преобразует значение поля Options в строку + if ischar(codeField) + value = codeField; + elseif isstring(codeField) + value = char(codeField); + elseif iscell(codeField) + value = strjoin(codeField, newline); + else + % warning('Неподдерживаемый тип данных: сохранено как пустая строка'); + value = ''; + end end function res = ternary(cond, valTrue, valFalse)