2 Commits

Author SHA1 Message Date
Razvalyaev
041322a62e pre-release 1.03 2025-06-28 16:20:28 +03:00
Razvalyaev
1aa3c5b955 pre-release 1.02 2025-06-19 13:29:33 +03:00
11 changed files with 547 additions and 174 deletions

Binary file not shown.

View File

@@ -2,12 +2,24 @@
function install_my_library()
libDir = fileparts(mfilename('fullpath'));
% Путь к файлу-флагу, указывающему, что установка уже была
flagFile = fullfile(libDir, '.library_installed.mat');
% Если библиотека уже установлена просто выходим
if isfile(flagFile)
return;
end
% 1. Добавляем библиотеку и m-файлы в путь
addpath(fullfile(libDir, 'lib'));
addpath(fullfile(libDir, 'm'));
savepath;
% 3. Обновляем Library Browser
% 2. Обновляем Library Browser
rehash;
sl_refresh_customizations;
% 3. Сохраняем флаг установки
installedOn = datetime('now');
save(flagFile, 'installedOn');
end

Binary file not shown.

View File

@@ -63,7 +63,7 @@ classdef appWrap
block = gcb;
% Получаем имя функции и путь к файлам
filename = appWrap.getAbsolutePath(mcuMask.getAppWrapperUserFile(block));
filename = mcuPath.getAbsolutePath(appWrap.getAppWrapperUserFile(block));
if exist(filename, 'file') == 2
% Формируем команду без кавычек
cmd = sprintf('rundll32.exe shell32.dll,OpenAs_RunDLL %s', filename);
@@ -75,14 +75,14 @@ classdef appWrap
errordlg('Файл не найден');
end
end
end
%% SPECIFIC TOOLS
methods(Static, Access = private)
function [filename, section, tool, example] = getAppWrapperUserFile(block)
sel = get_param(block, 'appWrapperFunc');
function [filename, section, tool, example] = getAppWrapperUserFile(block, sel)
if (nargin < 2)
sel = get_param(block, 'appWrapperFunc');
end
basePath = mcuPath.get('appWrapperPath');
if isempty(basePath)
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
@@ -150,7 +150,5 @@ classdef appWrap
end
end
end
end

143
McuLib/m/configJs.m Normal file
View File

@@ -0,0 +1,143 @@
classdef configJs
methods(Static)
function config = update(blockPath, config)
if isempty(config)
return;
end
mask = Simulink.Mask.get(blockPath);
maskParams = mask.Parameters;
paramNames = arrayfun(@(p) p.Name, maskParams, 'UniformOutput', false);
% Обработка остальных секций (с дефайнами)
periphs = fieldnames(config);
for i = 1:numel(periphs)
periph = periphs{i};
% Проверяем есть ли Defines
if ~isfield(config.(periph), 'Defines')
continue;
end
defines = config.(periph).Defines;
defNames = fieldnames(defines);
for j = 1:numel(defNames)
defPrompt = defNames{j};
paramName = matlab.lang.makeValidName(defPrompt);
% Проверка, существует ли параметр с таким именем
if ismember(paramName, paramNames)
param = mask.getParameter(paramName);
valStr = param.Value;
% Проверяем, существует ли элемент defPrompt в структуре defines
if isfield(defines, defPrompt)
% Преобразуем строку в соответствующий тип
if strcmpi(defines.(defPrompt).Type, 'checkbox')
config.(periph).Defines.(defPrompt).Default = strcmpi(valStr, 'on');
elseif strcmpi(defines.(defPrompt).Type, 'edit')
valNum = str2double(valStr);
if isnan(valNum)
config.(periph).Defines.(defPrompt).Default = valStr;
else
config.(periph).Defines.(defPrompt).Default = valNum;
end
end
end
end
end
end
end
function config = read(blockPath)
mask = Simulink.Mask.get(blockPath);
pathparam = mask.getParameter('periphPath');
config_path = pathparam.Value;
if ~isempty(config_path)
jsonText = fileread(config_path);
config = jsondecode(jsonText);
else
config = [];
end
end
function write(config)
if isempty(config)
return
end
blockHandle = gcbh;
mask = Simulink.Mask.get(blockHandle);
pathparam = mask.getParameter('periphPath');
config_path = pathparam.Value;
jsonText = jsonencode(config, 'PrettyPrint', true);
fid = fopen(config_path, 'w', 'n', 'UTF-8');
if fid == -1
error('Не удалось открыть файл periph_config.json для записи.');
end
fwrite(fid, jsonText, 'char');
fclose(fid);
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 = configJs.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
end
methods(Static, Access=private)
end
end

277
McuLib/m/mainConfig.m Normal file
View File

@@ -0,0 +1,277 @@
classdef mainConfig
methods(Static)
function config = export()
blockPath = gcb;
mask = Simulink.Mask.get(blockPath);
wrapParamToExport = {'wrapperPath', 'enableDebug', 'mcuClk', ...
'threadCycles', 'enableThreading', 'enableDeinit', ...
'periphPath'};
portParamToExport = {'inNumb', ...
'in_port_1_name', 'in_port_1_width', ...
'in_port_2_name', 'in_port_2_width', ...
'in_port_3_name', 'in_port_3_width', ...
'in_port_4_name', 'in_port_4_width', ...
'in_port_5_name', 'in_port_5_width', ...
'outNumb', ...
'out_port_1_name', 'out_port_1_width', ...
'out_port_2_name', 'out_port_2_width', ...
'out_port_3_name', 'out_port_3_width', ...
'out_port_4_name', 'out_port_4_width', ...
'out_port_5_name', 'out_port_5_width',};
appParamToExport = {'appWrapperPath', 'srcTable', 'incTable', 'userDefs'};
config = struct();
for i = 1:numel(wrapParamToExport)
paramName = wrapParamToExport{i};
def = mainConfig.exportParamToConfig(mask, paramName);
config.(paramName) = def;
end
for i = 1:numel(portParamToExport)
paramName = portParamToExport{i};
def = mainConfig.exportParamToConfig(mask, paramName);
config.(paramName) = def;
end
for i = 1:numel(appParamToExport)
paramName = appParamToExport{i};
def = mainConfig.exportParamToConfig(mask, paramName);
config.(paramName) = def;
end
jsonStr = jsonencode(config, 'PrettyPrint', true); % 'PrettyPrint' для форматирования
% Диалог сохранения файла
[file, path] = uiputfile('*.json', 'Сохранить конфигурацию как', 'WrapperConfig.json');
if isequal(file, 0) || isequal(path, 0)
disp('Сохранение отменено пользователем.');
return;
end
filepath = fullfile(path, file);
% Сохраняем в файл
fid = fopen(filepath, 'w');
if fid == -1
mcuMask.disp(0, 'Не удалось открыть файл для записи: %s', filename);
end
fwrite(fid, jsonStr, 'char');
fclose(fid);
end
function import()
% Получаем путь к текущему блоку
blockPath = gcb;
mask = Simulink.Mask.get(blockPath);
% Выбор JSON-файла через диалоговое окно
[file, path] = uigetfile('*.json', 'Выберите файл конфигурации');
if isequal(file, 0)
mcuMask.disp(0, 'Импорт отменён пользователем.');
return;
end
fullpath = fullfile(path, file);
% Чтение и декодирование JSON
try
jsonStr = fileread(fullpath);
config = jsondecode(jsonStr);
catch err
mcuMask.disp(0, 'Ошибка при чтении или разборе JSON: %s', err.message);
end
% Применение параметров из конфигурации
paramNames = fieldnames(config);
for i = 1:numel(paramNames)
paramName = paramNames{i};
def = config.(paramName);
try
mainConfig.applyDefToMask(mask, paramName, def);
catch err
mcuMask.disp(0, 'Ошибка при применении параметра "%s": %s', paramName, err.message);
end
end
mcuMask.disp(0, 'Конфигурация успешно импортирована.');
mcuMask.periphUpdate();
end
end
methods(Static, Access=private)
function def = exportParamToConfig(mask, paramName)
% mask объект Simulink.Mask.get(blockPath)
% paramName имя параметра (как в mask.Parameters.Name)
param = mask.getParameter(paramName);
if isempty(param)
mcuMask.disp(0, 'Параметр "%s" не найден в маске.', paramName);
def = [];
return;
end
def = struct();
% Prompt
def.Prompt = param.Prompt;
% Тип параметра
def.Type = param.Type;
% Значение по умолчанию
val = param.Value;
switch lower(param.Type)
case 'checkbox'
def.Default = strcmp(val, 'on');
case {'edit', 'spinbox'}
num = str2double(val);
if ~isnan(num)
def.Default = num;
else
def.Default = val;
end
case 'customtable'
def.Default = customtable.parse(param.Name); % или можно попытаться распарсить значение позже
case 'text'
def.Default = ''; % или можно попытаться распарсить значение позже
otherwise
def.Default = val;
end
% Alias, если есть
if ~isempty(param.Alias)
def.Def = param.Alias;
end
% % Row (new/current)
% try
% rowSetting = param.DialogControl.Row;
% def.NewRow = strcmp(rowSetting, 'new');
% catch
% def.NewRow = false;
% end
end
function applyDefToMask(mask, paramName, def)
% mask объект Simulink.Mask.get(blockPath)
% paramName имя параметра маски
% def структура, полученная из extractDefFromMask
% Получаем параметр
param = mask.getParameter(paramName);
if isempty(param)
mcuMask.disp(0, 'Параметр "%s" не найден в маске.', paramName);
return;
end
if isempty(def)
mcuMask.disp(0, 'Параметр "%s" не найден в конфиге.', paramName);
return;
end
switch lower(def.Type)
case 'checkbox'
% Логическое значение true/false
if islogical(def.Default)
param.Value = mainConfig.ternary(def.Default, 'on', 'off');
else
mcuMask.disp(0, 'Ожидалось логическое значение для checkbox "%s".', paramName);
end
case {'edit', 'spinbox'}
% Строка или число
if isnumeric(def.Default)
param.Value = num2str(def.Default);
elseif ischar(def.Default) || isstring(def.Default)
param.Value = char(def.Default);
else
mcuMask.disp(0, 'Некорректный формат значения для edit "%s".', paramName);
end
case 'customtable'
% Массив строк
if iscell(def.Default)
customtable.collect(paramName, def.Default);
else
mcuMask.disp(0, 'customtable "%s" требует cell-массив строк.', paramName);
end
case 'text'
% Просто текстовая строка
if ischar(def.Default) || isstring(def.Default)
param.Value = char(def.Default);
else
mcuMask.disp(0, 'text-параметр "%s" должен быть строкой.', paramName);
end
case 'popup'
% popup установить значение, если оно есть в списке
if ischar(def.Default) && isfield(def, 'Def') && any(strcmp(def.Default, def.Def))
param.Value = def.Default;
else
mcuMask.disp(0, 'popup-параметр "%s" имеет неверное значение или список.', paramName);
end
otherwise
% По умолчанию просто устанавливаем строковое значение
if ischar(def.Default) || isstring(def.Default)
param.Value = char(def.Default);
elseif isnumeric(def.Default)
param.Value = num2str(def.Default);
else
mcuMask.disp(0, 'Неизвестный формат значения параметра "%s".', paramName);
end
end
% Применение Prompt, если нужно
if isfield(def, 'Prompt')
param.Prompt = def.Prompt;
end
% Применение Alias, если есть
if isfield(def, 'Def') && ischar(def.Def)
param.Alias = def.Def;
end
% % Установка Row, если поддерживается
% if isfield(def, 'NewRow')
% try
% if def.NewRow
% param.DialogControl.Row = 'new';
% else
% param.DialogControl.Row = 'current';
% end
% catch
% % Некоторым типам параметров Row может быть неприменим
% end
% end
end
function result = ternary(cond, a, b)
if cond
result = a;
else
result = b;
end
end
end
end

View File

@@ -175,10 +175,10 @@ classdef mcuMask
return;
end
modelName = bdroot(gcb); % получить имя верхнего уровня модели
blockName = gcb;
mgr = asynchManage(modelName, blockName); % создать объект класса
mgr.saveAndUpdateModel(); % запустить сохранение и обновление
% modelName = bdroot(gcb); % получить имя верхнего уровня модели
% blockName = gcb;
% mgr = asynchManage(modelName, blockName); % создать объект класса
% mgr.saveAndUpdateModel(); % запустить сохранение и обновление
end
function close(blockPath)
@@ -324,6 +324,9 @@ classdef mcuMask
start(t);
end
function v = getMyLibVersion()
v = 'pre-1.03';
end
end
end

View File

@@ -8,7 +8,7 @@ classdef mcuPath
end
%% ADD PATH TO TABLE
function addSourceFileTable(targetParamName, message)
% Открываем проводник для выбора файлов
[files, pathstr] = uigetfile({ ...

View File

@@ -66,9 +66,9 @@ function res = mexing(compile_mode)
beep
else
blockPath = gcb;
config = periphConfig.read_config(blockPath);
config = periphConfig.update_config(blockPath, config);
periphConfig.write_config(config);
config = configJs.read(blockPath);
config = configJs.update(blockPath, config);
configJs.write(config);
periphConfig.updateMask(blockPath, config);
end
end
@@ -232,10 +232,16 @@ function definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, val_
end
% Берём alias из маски
val = '';
if ~strcmp(param.Type, 'popup')
def_name = param.Alias;
else
def_name = param.Value;
if strcmp(param.Alias, '')
def_name = param.Value;
else
def_name = param.Alias;
val = param.Value;
end
end
if strcmp(def_name, '')
@@ -259,7 +265,11 @@ function definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, val_
newDefine = '';
end
else
newDefine = ['-D"' def_name '"'];
if strcmp(param.Alias, '')
newDefine = ['-D"' def_name '"'];
else
newDefine = ['-D"' def_name '__EQ__' val '"'];
end
end

View File

@@ -74,7 +74,7 @@ classdef periphConfig
blockPath = gcb;
mask = Simulink.Mask.get(blockPath);
config = periphConfig.read_config(blockPath);
config = configJs.read(blockPath);
containerName = 'configTabAll';
container = mask.getDialogControl(containerName);
paramsAll = mcuMask.collect_all_parameters(container);
@@ -130,7 +130,7 @@ classdef periphConfig
blockPath = gcb;
mask = Simulink.Mask.get(blockPath);
hObj = mask.getParameter(paramName);
config = periphConfig.read_config(blockPath);
config = configJs.read(blockPath);
container = mask.getDialogControl('configTabAll');
% === Проверка на Tab_<Periph>_Enable ===
@@ -175,7 +175,7 @@ classdef periphConfig
% Получаем содержимое config по nameBase возможно, вложенное
try
valueStruct = periphConfig.get_field(config, nameBase);
valueStruct = configJs.get_field(config, nameBase);
catch
warning('Не удалось найти путь %s в config.', nameBase);
return;
@@ -209,103 +209,33 @@ classdef periphConfig
periphConfig.addCodeBat(CodeStruct, periphPath);
end
function config = update_config(blockPath, config)
if isempty(config)
return;
end
mask = Simulink.Mask.get(blockPath);
maskParams = mask.Parameters;
paramNames = arrayfun(@(p) p.Name, maskParams, 'UniformOutput', false);
% Обработка остальных секций (с дефайнами)
periphs = fieldnames(config);
for i = 1:numel(periphs)
periph = periphs{i};
% Пропускаем Code и UserCode
if strcmp(periph, 'Code') || strcmp(periph, 'UserCode')
continue;
end
% Проверяем есть ли Defines
if ~isfield(config.(periph), 'Defines')
continue;
end
defines = config.(periph).Defines;
defNames = fieldnames(defines);
for j = 1:numel(defNames)
defPrompt = defNames{j};
paramName = matlab.lang.makeValidName(defPrompt);
% Проверка, существует ли параметр с таким именем
if ismember(paramName, paramNames)
param = mask.getParameter(paramName);
valStr = param.Value;
% Проверяем, существует ли элемент defPrompt в структуре defines
if isfield(defines, defPrompt)
% Преобразуем строку в соответствующий тип
if strcmpi(defines.(defPrompt).Type, 'checkbox')
config.(periph).Defines.(defPrompt).Default = strcmpi(valStr, 'on');
elseif strcmpi(defines.(defPrompt).Type, 'edit')
valNum = str2double(valStr);
if isnan(valNum)
config.(periph).Defines.(defPrompt).Default = valStr;
else
config.(periph).Defines.(defPrompt).Default = valNum;
end
end
end
end
end
end
end
function config = read_config(blockPath)
mask = Simulink.Mask.get(blockPath);
pathparam = mask.getParameter('periphPath');
config_path = pathparam.Value;
if ~isempty(config_path)
jsonText = fileread(config_path);
config = jsondecode(jsonText);
else
config = [];
end
end
function write_config(config)
if isempty(config)
return
end
blockHandle = gcbh;
mask = Simulink.Mask.get(blockHandle);
pathparam = mask.getParameter('periphPath');
config_path = pathparam.Value;
jsonText = jsonencode(config, 'PrettyPrint', true);
fid = fopen(config_path, 'w', 'n', 'UTF-8');
if fid == -1
error('Не удалось открыть файл periph_config.json для записи.');
end
fwrite(fid, jsonText, 'char');
fclose(fid);
end
end
methods(Static, Access=private)
function addHiddenParam(mask, containerName, nameBase, kind, existingParams)
% Преобразуем к красивому имени
prettyName = strrep(nameBase, '_', ' ');
paramName = ['Hidden_' char(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 clear_tab_params(mask, configStruct, prefix, depth)
if nargin < 4
depth = 0;
@@ -326,7 +256,7 @@ classdef periphConfig
end
else
if strcmp(key, 'Sources') || strcmp(key, 'Includes')
baseName = periphConfig.get_final_name_from_prefix(prefix);
baseName = configJs.get_final_name_from_prefix(prefix);
periphConfig.clear_single_periph_code_param(mask, baseName);
end
end
@@ -354,7 +284,7 @@ classdef periphConfig
end
else
if strcmp(key, 'Sources') || strcmp(key, 'Includes')
baseName = periphConfig.get_final_name_from_prefix(prefix);
baseName = configJs.get_final_name_from_prefix(prefix);
periphConfig.store_single_periph_code(mask, baseName, configStruct);
end
end
@@ -513,10 +443,6 @@ classdef periphConfig
mcuMask.delete_all_tabs(mask, container);
end
function res = addCodeBat(codeConfig, codePath)
% Добавить сурсы и пути в батник
@@ -647,6 +573,9 @@ classdef periphConfig
if isfield(def, 'Def') && iscell(def.Def) && ~isempty(def.Def)
choices = def.Def;
valStr = ''; % по умолчанию ничего
elseif isfield(def, 'Options')
choices = def.Def;
valStr = ''; % по умолчанию ничего
else
warning('Popout параметр "%s" не содержит допустимого списка в Def.', defPrompt);
return;
@@ -692,13 +621,18 @@ classdef periphConfig
if isfield(def, 'Def')
if strcmp(paramType, 'popup')
param.TypeOptions = def.Def;
if iscell(def.Def)
param.TypeOptions = def.Def;
elseif isfield(def, 'Options')
param.Alias = def.Def;
param.TypeOptions = def.Options;
end
else
param.Alias = def.Def;
end
end
callback = sprintf('periphConfig.periphParamCallback("%s");', paramName);
callback = sprintf('try periphConfig.periphParamCallback("%s"); catch end', paramName);
param.Callback = callback;
end
@@ -709,8 +643,8 @@ classdef periphConfig
function clear_single_periph_code_param(mask, periph)
% Очистка кода одного поля конфига
paramNames = {
['Hidden_' periph '_Sources'],
['Hidden_' periph '_Includes']
['Hidden_' char(periph) '_Sources'],
['Hidden_' char(periph) '_Includes']
};
for i = 1:numel(paramNames)
@@ -731,7 +665,7 @@ classdef periphConfig
paramName = ['Hidden_' char(periph) '_Sources'];
try
param = mask.getParameter(paramName);
param.Value = periphConfig.convert_code_value(code.Sources);
param.Value = configJs.convert_code_value(code.Sources);
catch
mcuMask.disp(0, ['Параметр ' paramName ' не найден']);
end
@@ -739,60 +673,18 @@ classdef periphConfig
% Сохраняем Includes, если они есть
if isfield(code, 'Includes')
paramName = ['Hidden_' periph '_Includes'];
paramName = ['Hidden_' char(periph) '_Includes'];
try
param = mask.getParameter(paramName);
param.Value = periphConfig.convert_code_value(code.Includes);
param.Value = configJs.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)
if cond
res = valTrue;

View File

@@ -1,5 +1,5 @@
<deployment-project plugin="plugin.toolbox" plugin-version="1.0">
<configuration build-checksum="2658716694" file="E:\.WORK\MATLAB\mcu_matlab\mcuwrapper.prj" location="E:\.WORK\MATLAB\mcu_matlab" name="mcuwrapper" target="target.toolbox" target-name="Package Toolbox">
<configuration build-checksum="1391118035" file="F:\Work\Projects\MATLAB\mcu_matlab_lib\mcuwrapper.prj" location="F:\Work\Projects\MATLAB\mcu_matlab_lib" name="mcuwrapper" target="target.toolbox" target-name="Package Toolbox">
<param.appname>MCU Wrapper</param.appname>
<param.authnamewatermark>Razvalyaev</param.authnamewatermark>
<param.email>wot890089@mail.ru</param.email>
@@ -7,7 +7,7 @@
<param.summary>Library for run MCU program in Simulink</param.summary>
<param.description />
<param.screenshot />
<param.version>1.01</param.version>
<param.version>1.03</param.version>
<param.output>${PROJECT_ROOT}\MCU Wrapper.mltbx</param.output>
<param.products.name />
<param.products.id />
@@ -27,7 +27,7 @@
<param.exported.on.package>false</param.exported.on.package>
<param.required.addons>
<requiredaddons>
<requiredAddOn earliest="earliest" fromRepository="true" id="e5534541-4a80-11e4-9553-005056977bd0" include="true" latest="latest">findjobj - find java handles of Matlab graphic objects</requiredAddOn>
<requiredAddOn earliest="earliest" fromRepository="true" id="e5534541-4a80-11e4-9553-005056977bd0" include="false" latest="latest">findjobj - find java handles of Matlab graphic objects</requiredAddOn>
</requiredaddons>
</param.required.addons>
<param.matlab.project.id />
@@ -84,6 +84,7 @@
<file>${PROJECT_ROOT}\McuLib</file>
</fileset.rootdir>
<fileset.rootfiles>
<file>${PROJECT_ROOT}\McuLib\.library_installed.mat</file>
<file>${PROJECT_ROOT}\McuLib\install_my_library.m</file>
<file>${PROJECT_ROOT}\McuLib\lib</file>
<file>${PROJECT_ROOT}\McuLib\m</file>
@@ -96,12 +97,49 @@
<fileset.depfun.excluded />
<fileset.package />
<build-deliverables>
<file location="${PROJECT_ROOT}" name="MCU Wrapper.mltbx" optional="false">E:\.WORK\MATLAB\mcu_matlab\MCU Wrapper.mltbx</file>
<file location="${PROJECT_ROOT}" name="MCU Wrapper.mltbx" optional="false">F:\Work\Projects\MATLAB\mcu_matlab_lib\MCU Wrapper.mltbx</file>
</build-deliverables>
<workflow />
<matlab>
<root>C:\Program Files\MyProgs\MATLAB\R2023a</root>
<toolboxes />
<root>C:\Program Files\MATLAB\R2023a</root>
<toolboxes>
<toolbox name="matlabcoder" />
<toolbox name="embeddedcoder" />
<toolbox name="gpucoder" />
<toolbox name="fixedpoint" />
<toolbox name="matlabhdlcoder" />
<toolbox name="neuralnetwork" />
</toolboxes>
<toolbox>
<matlabcoder>
<enabled>true</enabled>
</matlabcoder>
</toolbox>
<toolbox>
<embeddedcoder>
<enabled>true</enabled>
</embeddedcoder>
</toolbox>
<toolbox>
<gpucoder>
<enabled>true</enabled>
</gpucoder>
</toolbox>
<toolbox>
<fixedpoint>
<enabled>true</enabled>
</fixedpoint>
</toolbox>
<toolbox>
<matlabhdlcoder>
<enabled>true</enabled>
</matlabhdlcoder>
</toolbox>
<toolbox>
<neuralnetwork>
<enabled>true</enabled>
</neuralnetwork>
</toolbox>
</matlab>
<platform>
<unix>false</unix>