Compare commits
5 Commits
v1.0
...
245592a821
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
245592a821 | ||
|
|
0a2fd71422 | ||
|
|
966ddc3bac | ||
|
|
df30570d4a | ||
|
|
d983f2525a |
BIN
MCU Wrapper.mltbx
Normal file
BIN
MCU Wrapper.mltbx
Normal file
Binary file not shown.
@@ -7,41 +7,7 @@ function install_my_library()
|
|||||||
addpath(fullfile(libDir, 'm'));
|
addpath(fullfile(libDir, 'm'));
|
||||||
savepath;
|
savepath;
|
||||||
|
|
||||||
% 2. Диалог выбора папки для копирования шаблонов
|
|
||||||
defaultTargetDir = pwd;
|
|
||||||
answer = questdlg(['Выберите папку для копирования шаблонов кода. ', ...
|
|
||||||
'По умолчанию текущая папка: ' defaultTargetDir], ...
|
|
||||||
'Выбор папки', ...
|
|
||||||
'Текущая папка', 'Выбрать другую', 'Текущая папка');
|
|
||||||
|
|
||||||
switch answer
|
|
||||||
case 'Выбрать другую'
|
|
||||||
targetDir = uigetdir(defaultTargetDir, 'Выберите папку для шаблонов');
|
|
||||||
if isequal(targetDir,0)
|
|
||||||
disp('Копирование шаблонов отменено пользователем.');
|
|
||||||
targetDir = '';
|
|
||||||
end
|
|
||||||
case 'Текущая папка'
|
|
||||||
targetDir = defaultTargetDir;
|
|
||||||
otherwise
|
|
||||||
targetDir = defaultTargetDir;
|
|
||||||
end
|
|
||||||
|
|
||||||
if ~isempty(targetDir)
|
|
||||||
templatesDir = fullfile(libDir, 'templates');
|
|
||||||
templateFiles = dir(fullfile(templatesDir, '*.*'));
|
|
||||||
for k = 1:numel(templateFiles)
|
|
||||||
if ~templateFiles(k).isdir
|
|
||||||
copyfile(fullfile(templatesDir, templateFiles(k).name), ...
|
|
||||||
fullfile(targetDir, templateFiles(k).name));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
fprintf('Шаблоны кода скопированы в папку:\n%s\n', targetDir);
|
|
||||||
end
|
|
||||||
|
|
||||||
% 3. Обновляем Library Browser
|
% 3. Обновляем Library Browser
|
||||||
rehash;
|
rehash;
|
||||||
sl_refresh_customizations;
|
sl_refresh_customizations;
|
||||||
|
|
||||||
disp('Библиотека успешно установлена и добавлена в Library Browser.');
|
|
||||||
end
|
end
|
||||||
|
|||||||
Binary file not shown.
@@ -67,7 +67,6 @@ classdef asynchManage < handle
|
|||||||
if ~isempty(obj.maskBlockPath)
|
if ~isempty(obj.maskBlockPath)
|
||||||
try
|
try
|
||||||
mcuMask.open(obj.maskBlockPath, 1);
|
mcuMask.open(obj.maskBlockPath, 1);
|
||||||
fprintf('Mask opened for block %s\n', obj.maskBlockPath);
|
|
||||||
catch ME
|
catch ME
|
||||||
warning('progr:Nneg', 'Не удалось открыть маску: %s', ME.message);
|
warning('progr:Nneg', 'Не удалось открыть маску: %s', ME.message);
|
||||||
end
|
end
|
||||||
|
|||||||
139
McuLib/m/compiler.m
Normal file
139
McuLib/m/compiler.m
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
classdef compiler
|
||||||
|
methods(Static)
|
||||||
|
|
||||||
|
function compile()
|
||||||
|
addpath(mcuPath.get('wrapperPath'));
|
||||||
|
mexing(1);
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_availbe()
|
||||||
|
addpath(mcuPath.get('wrapperPath'));
|
||||||
|
mexing(1);
|
||||||
|
end
|
||||||
|
|
||||||
|
function choose()
|
||||||
|
addpath(mcuPath.get('wrapperPath'));
|
||||||
|
mexing(1);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function updateRunBat()
|
||||||
|
sources = {
|
||||||
|
'MCU.c'
|
||||||
|
'mcu_wrapper.c'
|
||||||
|
};
|
||||||
|
% Список заголовочных файлов (.h)
|
||||||
|
includes = { '.\'
|
||||||
|
};
|
||||||
|
periphPath = mcuPath.get('wrapperPath');
|
||||||
|
% Формируем строки
|
||||||
|
wrapperSrcText = compiler.createSourcesBat('code_WRAPPER', sources, periphPath);
|
||||||
|
wrapperIncText = compiler.createIncludesBat('includes_WRAPPER', includes, periphPath);
|
||||||
|
|
||||||
|
% Записываем результат
|
||||||
|
res = compiler.updateRunMexBat(wrapperSrcText, wrapperIncText, ':: WRAPPER BAT'); % Всё прошло успешно
|
||||||
|
|
||||||
|
if res == 0
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
sources = {
|
||||||
|
'app_wrapper.c'
|
||||||
|
'app_init.c'
|
||||||
|
'app_io.c'
|
||||||
|
};
|
||||||
|
% Список заголовочных файлов (.h)
|
||||||
|
includes = { '.\'
|
||||||
|
};
|
||||||
|
periphPath = mcuPath.get('appWrapperPath');
|
||||||
|
% Формируем строки
|
||||||
|
wrapperSrcText = compiler.createSourcesBat('code_APP_WRAPPER', sources, periphPath);
|
||||||
|
wrapperIncText = compiler.createIncludesBat('includes_APP_WRAPPER', includes, periphPath);
|
||||||
|
|
||||||
|
% Записываем результат
|
||||||
|
res = compiler.updateRunMexBat(wrapperSrcText, wrapperIncText, ':: APP WRAPPER BAT'); % Всё прошло успешно
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function res = updateRunMexBat(srcText, incText, Section)
|
||||||
|
% Входные параметры:
|
||||||
|
% srcText - текст для записи set code_...
|
||||||
|
% incText - текст для записи set includes_...
|
||||||
|
%
|
||||||
|
% Возвращает:
|
||||||
|
% res - 0 при успехе, 1 при ошибке
|
||||||
|
periphBat = [srcText '\n\n' incText];
|
||||||
|
batPath = fullfile(mcuPath.get('wrapperPath'), 'run_mex.bat');
|
||||||
|
res = 1;
|
||||||
|
try
|
||||||
|
code = fileread(batPath);
|
||||||
|
code = regexprep(code, '\r\n?', '\n');
|
||||||
|
|
||||||
|
% Записываем строки srcText и incText с переносами строк
|
||||||
|
code = editCode.insertSection(code, Section, periphBat);
|
||||||
|
|
||||||
|
fid = fopen(batPath, 'w', 'n', 'UTF-8');
|
||||||
|
if fid == -1
|
||||||
|
error('Не удалось открыть файл для записи');
|
||||||
|
end
|
||||||
|
fwrite(fid, code);
|
||||||
|
fclose(fid);
|
||||||
|
res = 1;
|
||||||
|
catch ME
|
||||||
|
mcuMask.disp(0, '\nОшибка: неудачная запись в файл при записи файла: %s', ME.message);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function srcText = createSourcesBat(prefix_name, sources, path)
|
||||||
|
srcList = {};
|
||||||
|
if nargin >= 2 && iscell(sources)
|
||||||
|
for i = 1:numel(sources)
|
||||||
|
fullPath = fullfile(path, sources{i});
|
||||||
|
srcList{end+1} = strrep(fullPath, '\', '\\');
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Формируем srcText с переносами строк и ^
|
||||||
|
srcText = '';
|
||||||
|
for i = 1:numel(srcList)
|
||||||
|
if i < numel(srcList)
|
||||||
|
srcText = [srcText srcList{i} '^' newline ' '];
|
||||||
|
else
|
||||||
|
srcText = [srcText srcList{i}];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Добавляем префикс
|
||||||
|
srcText = ['set ' prefix_name '=' srcText];
|
||||||
|
end
|
||||||
|
|
||||||
|
function incText = createIncludesBat(prefix_name, includes, path)
|
||||||
|
incList = {};
|
||||||
|
if nargin >= 2 && iscell(includes)
|
||||||
|
for i = 1:numel(includes)
|
||||||
|
fullPath = fullfile(path, includes{i});
|
||||||
|
incList{end+1} = ['-I"' strrep(fullPath, '\', '\\') '"'];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Формируем incText с переносами строк и ^
|
||||||
|
incText = '';
|
||||||
|
for i = 1:numel(incList)
|
||||||
|
if i == 1 && numel(incList) ~= 1
|
||||||
|
incText = [incText incList{i} '^' newline];
|
||||||
|
elseif i < numel(incList)
|
||||||
|
incText = [incText ' ' incList{i} '^' newline];
|
||||||
|
else
|
||||||
|
incText = [incText ' ' incList{i}];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Добавляем префикс
|
||||||
|
incText = ['set ' prefix_name '=' incText];
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -8,13 +8,13 @@ classdef customtable
|
|||||||
tableControl = mask.getDialogControl(table_name);
|
tableControl = mask.getDialogControl(table_name);
|
||||||
tableParameter = mask.getParameter(table_name);
|
tableParameter = mask.getParameter(table_name);
|
||||||
nCols = tableControl.getNumberOfColumns;
|
nCols = tableControl.getNumberOfColumns;
|
||||||
if nCols > 0
|
% if nCols > 0
|
||||||
for i = 1:nCols
|
% for i = 1:nCols
|
||||||
tableControl.removeColumn(1);
|
% tableControl.removeColumn(1);
|
||||||
end
|
% end
|
||||||
end
|
% end
|
||||||
column = tableControl.addColumn(Name='Title', Type='edit');
|
% column = tableControl.addColumn(Name='Title', Type='edit');
|
||||||
tableControl.Sortable = 'on';
|
% tableControl.Sortable = 'on';
|
||||||
column.Name = tableParameter.Alias;
|
column.Name = tableParameter.Alias;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ classdef editCode
|
|||||||
end
|
end
|
||||||
|
|
||||||
% Формируем новую секцию с нужным текстом
|
% Формируем новую секцию с нужным текстом
|
||||||
|
% newText = strrep(newText, '\', '\\'); % экранируем для корректной вставки
|
||||||
replacement = sprintf('%s START\n%s\n%s END', sectionName, newText, sectionName);
|
replacement = sprintf('%s START\n%s\n%s END', sectionName, newText, sectionName);
|
||||||
|
|
||||||
% Заменяем всю найденную секцию на новую
|
% Заменяем всю найденную секцию на новую
|
||||||
|
|||||||
120
McuLib/m/init.m
120
McuLib/m/init.m
@@ -1,120 +0,0 @@
|
|||||||
% Cкрипт для задания параметров модели
|
|
||||||
|
|
||||||
clear;%очищаем рабочее пространство
|
|
||||||
|
|
||||||
%% ПАРАМЕТРЫ МОДЕЛИ
|
|
||||||
|
|
||||||
addpath('MCU_Wrapper');
|
|
||||||
addpath('motor');
|
|
||||||
Ts = 10e-6;%шаг интегрирования
|
|
||||||
Decim = 1;%интервал прореживания
|
|
||||||
DisableScope = {
|
|
||||||
"Idc";
|
|
||||||
"Udc";
|
|
||||||
};
|
|
||||||
|
|
||||||
GED = "23550";
|
|
||||||
% GED = "22220";
|
|
||||||
|
|
||||||
% начальная скорость ГЭД, доля от NmNom
|
|
||||||
w0 = 0;%0.5;%-0.75;%
|
|
||||||
% пусковой момент, о.е.
|
|
||||||
Mst = 0.6;%0.6;
|
|
||||||
|
|
||||||
% разрешаем/запрещаем сбросы/набросы момента нагрузки
|
|
||||||
changingLoadEnable = 0;%1
|
|
||||||
% разрешаем/запрещаем шум в измеренном токе
|
|
||||||
noiseEnable = 0;%1;%
|
|
||||||
% ... мощность шума
|
|
||||||
NP = 0.08;
|
|
||||||
|
|
||||||
|
|
||||||
%% НОМИНАЛЬНЫЕ ВЕЛИЧИНЫ ГЭД
|
|
||||||
% ... мощность на валу, Вт
|
|
||||||
Pnom = 6300e3;
|
|
||||||
% ... линейное напряжение, В (rms)
|
|
||||||
Unom = 3300;
|
|
||||||
% ... механическая скорость, об/мин
|
|
||||||
NmNom = 180;
|
|
||||||
% ... число пар полюсов
|
|
||||||
Pp = 6;
|
|
||||||
% ... коэффициент мощности
|
|
||||||
CosFi = 0.87;
|
|
||||||
% ... КПД
|
|
||||||
Eff = 0.968;
|
|
||||||
% ... приведенный к валу момент инерции, кг*м^2
|
|
||||||
J = 87e3*0.1;
|
|
||||||
|
|
||||||
|
|
||||||
%% РАСЧЕТЫ
|
|
||||||
% разкомментирование всех блоков
|
|
||||||
|
|
||||||
modelName = [bdroot '/Measurements'];
|
|
||||||
blocks = find_system(modelName, ...
|
|
||||||
'IncludeCommented', 'on', ...
|
|
||||||
'FollowLinks', 'on', ...
|
|
||||||
'LookUnderMasks', 'all', ...
|
|
||||||
'BlockType', 'Scope');
|
|
||||||
for i = 1:length(blocks)
|
|
||||||
set_param(blocks{i}, 'Commented', 'off');
|
|
||||||
end
|
|
||||||
% отключение графиков для ускорения смуляции
|
|
||||||
for i = 1:length(DisableScope)
|
|
||||||
set_param([modelName '/'] + DisableScope{i}, 'Commented', 'on');
|
|
||||||
end
|
|
||||||
|
|
||||||
% для упрощения записи
|
|
||||||
SQRT2 = sqrt(2);
|
|
||||||
SQRT3 = sqrt(3);
|
|
||||||
PI2 = pi*2;
|
|
||||||
|
|
||||||
% ... полная мощность, ВА
|
|
||||||
Snom = Pnom/CosFi/Eff;
|
|
||||||
% ... механическая скорость, рад/с
|
|
||||||
WmNom = NmNom/60*PI2;
|
|
||||||
% ... момент на валу, Н*м
|
|
||||||
Mnom = Pnom/WmNom;
|
|
||||||
% ... эл. скорость, рад/с
|
|
||||||
WeNom = WmNom*Pp;
|
|
||||||
% ... эл. скорость, Гц
|
|
||||||
FeNom = WeNom/PI2;
|
|
||||||
% ... потокосцепление статора, Вб
|
|
||||||
PsiNom = Unom*SQRT2/(WeNom*SQRT3);
|
|
||||||
% ... напряжение на входе инвертора, B
|
|
||||||
UdcNom = Unom*SQRT2;
|
|
||||||
% ... ток, А (ampl)
|
|
||||||
Inom = Snom/(Unom*SQRT3)*SQRT2*0.5;%0.5 - т.к. обмоток две
|
|
||||||
|
|
||||||
% схема замещения ГЭД
|
|
||||||
if GED == "22220"
|
|
||||||
GED
|
|
||||||
Rs = 11.8e-3;%Ом
|
|
||||||
Xls = 72.7e-3;%72.7e-3;%Ом
|
|
||||||
Rr = 11.1e-3*2.0;%*0.8;%Ом
|
|
||||||
Xlr = 85.5e-3;%Ом
|
|
||||||
Xm = 2.9322;%2.87;%Ом
|
|
||||||
Fe = 18;%Гц
|
|
||||||
Lls = Xls/(Fe*PI2);%Гн
|
|
||||||
Llr = Xlr/(Fe*PI2);%Гн
|
|
||||||
Lm = Xm/(Fe*PI2);%Гн
|
|
||||||
elseif GED == "23550"
|
|
||||||
GED
|
|
||||||
Rs = 0.0282;%Ом
|
|
||||||
Xls = 0.4016;%Ом
|
|
||||||
Rr = 0.139;%Ом
|
|
||||||
Xlr = 0.2006;%Ом
|
|
||||||
Xm = 5.2796;%Ом
|
|
||||||
Fe = 18.2;%Гц
|
|
||||||
Lls = Xls/(Fe*PI2);%Гн
|
|
||||||
Llr = Xlr/(Fe*PI2);%Гн
|
|
||||||
Lm = Xm/(Fe*PI2);%Гн
|
|
||||||
end
|
|
||||||
|
|
||||||
% ёмкость на входе INU, Ф
|
|
||||||
Cdc = 50e-3;
|
|
||||||
% снаберы в INU
|
|
||||||
Csn = Pnom/(1000*WeNom*Unom^2)/10;%Ф (0.5 - т.к. преобразователей два)
|
|
||||||
Rsn = 2*Ts/Csn*10;%Ом
|
|
||||||
|
|
||||||
% постоянная времени фильтра для тока ГЭД, c
|
|
||||||
Tiac = 30e-6;
|
|
||||||
59
McuLib/m/installTemplates.m
Normal file
59
McuLib/m/installTemplates.m
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
function installTemplates(forceCopy)
|
||||||
|
% installTemplates Копирует содержимое папки templates (включая вложенные папки) из уровня выше McuLib.slx в текущую папку
|
||||||
|
%
|
||||||
|
% installTemplates(forceCopy)
|
||||||
|
%
|
||||||
|
% forceCopy — логический параметр (true/false)
|
||||||
|
% Если true, файлы будут перезаписаны.
|
||||||
|
% Если false или не указан, копирование происходит без перезаписи существующих файлов.
|
||||||
|
|
||||||
|
if nargin < 1
|
||||||
|
forceCopy = false;
|
||||||
|
end
|
||||||
|
|
||||||
|
try
|
||||||
|
libDir = fileparts(which('McuLib.slx')); % папка с McuLib.slx
|
||||||
|
parentDir = fileparts(libDir); % уровень выше
|
||||||
|
templatesDir = fullfile(parentDir, 'templates'); % папка templates
|
||||||
|
|
||||||
|
targetDir = pwd; % текущая папка
|
||||||
|
mcuMask.disp(1, '');
|
||||||
|
if ~exist(templatesDir, 'dir')
|
||||||
|
mcuMask.disp(1, 'Папка шаблонов %s не найдена.', templatesDir);
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Список всех файлов и папок внутри templates (рекурсивно)
|
||||||
|
entries = dir(fullfile(templatesDir, '**', '*'));
|
||||||
|
|
||||||
|
for k = 1:length(entries)
|
||||||
|
if ~entries(k).isdir
|
||||||
|
% Относительный путь внутри templates
|
||||||
|
relPath = erase(entries(k).folder, [templatesDir filesep]);
|
||||||
|
if startsWith(relPath, filesep)
|
||||||
|
relPath = relPath(2:end); % убрать начальный слеш
|
||||||
|
end
|
||||||
|
|
||||||
|
srcFile = fullfile(entries(k).folder, entries(k).name);
|
||||||
|
destFolder = fullfile(targetDir, relPath);
|
||||||
|
destFile = fullfile(destFolder, entries(k).name);
|
||||||
|
|
||||||
|
if ~exist(destFolder, 'dir')
|
||||||
|
mkdir(destFolder);
|
||||||
|
end
|
||||||
|
|
||||||
|
if forceCopy || ~exist(destFile, 'file')
|
||||||
|
copyfile(srcFile, destFile);
|
||||||
|
mcuMask.disp(0, 'Скопирован файл: %s\n', fullfile(relPath, entries(k).name));
|
||||||
|
else
|
||||||
|
% mcuMask.disp(0, 'Файл уже существует и не перезаписывается: %s\n', fullfile(relPath, entries(k).name));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mcuMask.disp(0, ['Шаблоны успешно скопированы в ', targetDir]);
|
||||||
|
|
||||||
|
catch ME
|
||||||
|
mcuMask.disp(0, 'Ошибка при копировании шаблонов: %s', ME.message);
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -10,6 +10,8 @@ classdef mcuMask
|
|||||||
blk = gcbh;
|
blk = gcbh;
|
||||||
% Получаем объект маски текущего блока
|
% Получаем объект маски текущего блока
|
||||||
mask = Simulink.Mask.get(gcb);
|
mask = Simulink.Mask.get(gcb);
|
||||||
|
set_param(blk,"MaskSelfModifiable","on")
|
||||||
|
set_param(blk, 'LinkStatus', 'none');
|
||||||
% mcuMask.disp(1,'');
|
% mcuMask.disp(1,'');
|
||||||
try
|
try
|
||||||
% Проверка наличия findjobj
|
% Проверка наличия findjobj
|
||||||
@@ -17,8 +19,6 @@ classdef mcuMask
|
|||||||
catch
|
catch
|
||||||
findjobjAvailable = false;
|
findjobjAvailable = false;
|
||||||
end
|
end
|
||||||
% Получаем объект маски текущего блока
|
|
||||||
mask = Simulink.Mask.get(gcb);
|
|
||||||
% Имя checkbox-параметра (укажите точное имя из маски)
|
% Имя checkbox-параметра (укажите точное имя из маски)
|
||||||
checkboxParamName = 'extConsol'; % пример
|
checkboxParamName = 'extConsol'; % пример
|
||||||
findjobjLinkName = 'findjobj_link'; % пример
|
findjobjLinkName = 'findjobj_link'; % пример
|
||||||
@@ -46,7 +46,7 @@ classdef mcuMask
|
|||||||
table_names = {'srcTable', 'incTable'};
|
table_names = {'srcTable', 'incTable'};
|
||||||
for k = 1:numel(table_names)
|
for k = 1:numel(table_names)
|
||||||
table_name = table_names{k};
|
table_name = table_names{k};
|
||||||
% customtable.format(table_name);
|
customtable.format(table_name);
|
||||||
end
|
end
|
||||||
% запись описания блока
|
% запись описания блока
|
||||||
textDesc = ['Блок для настройки параметров симуляции микроконтроллера. ' newline ...
|
textDesc = ['Блок для настройки параметров симуляции микроконтроллера. ' newline ...
|
||||||
@@ -119,42 +119,37 @@ classdef mcuMask
|
|||||||
end
|
end
|
||||||
|
|
||||||
function wrapperPath_add(callbackContext)
|
function wrapperPath_add(callbackContext)
|
||||||
block = gcb;
|
mcuPath.addPath('wrapperPath');
|
||||||
mask = Simulink.Mask.get(block);
|
end
|
||||||
% Открываем окно выбора папки
|
|
||||||
folderPath = uigetdir('', 'Выберите папку');
|
function appWrapperPath_add(callbackContext)
|
||||||
% Проверка на отмену
|
mcuPath.addPath('appWrapperPath');
|
||||||
if isequal(folderPath, 0)
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
% Установка значения параметра маски
|
|
||||||
rel = mcuMask.absoluteToRelativePath(folderPath);
|
|
||||||
param = mask.getParameter('wrapperPath');
|
|
||||||
param.Value = rel;
|
|
||||||
|
|
||||||
end
|
end
|
||||||
%% USER WRAPPER CODE
|
%% USER WRAPPER CODE
|
||||||
|
|
||||||
function wrapperFunc(callbackContext)
|
function appWrapperFunc(callbackContext)
|
||||||
block = gcb;
|
block = gcb;
|
||||||
% Получаем имя функции и путь к файлам
|
% Получаем имя функции и путь к файлам
|
||||||
[filename, section, tool, example]= mcuMask.getWrapperUserFile(block);
|
[filename, section, tool, example]= mcuMask.getWrapperUserFile(block);
|
||||||
mcuMask.tool(tool, example);
|
mcuMask.tool(tool, example);
|
||||||
|
|
||||||
% Загружаем содержимое файла
|
% Загружаем содержимое файла
|
||||||
set_param(block, 'wrapperCode', '');
|
set_param(block, 'appWrapperCode', '');
|
||||||
code = fileread(filename);
|
try
|
||||||
code = regexprep(code, '\r\n?', '\n'); % нормализуем окончания строк
|
code = fileread(filename);
|
||||||
|
code = regexprep(code, '\r\n?', '\n'); % нормализуем окончания строк
|
||||||
|
|
||||||
includesText = editCode.extractSection(code, section);
|
includesText = editCode.extractSection(code, section);
|
||||||
set_param(block, 'wrapperCode', includesText);
|
set_param(block, 'appWrapperCode', includesText);
|
||||||
|
catch
|
||||||
|
end
|
||||||
% % Поиск тела обычной функции
|
% % Поиск тела обычной функции
|
||||||
% expr = sprintf('void %s()', sel);
|
% expr = sprintf('void %s()', sel);
|
||||||
% funcBody = editCode.extractSection(code, expr);
|
% funcBody = editCode.extractSection(code, expr);
|
||||||
% set_param(block, 'wrapperCode', funcBody);
|
% set_param(block, 'wrapperCode', funcBody);
|
||||||
end
|
end
|
||||||
|
|
||||||
function saveWrapperCode(callbackContext)
|
function saveAppWrapperCode(callbackContext)
|
||||||
block = gcb;
|
block = gcb;
|
||||||
|
|
||||||
% Получаем имя функции и путь к файлам
|
% Получаем имя функции и путь к файлам
|
||||||
@@ -164,15 +159,16 @@ classdef mcuMask
|
|||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
|
|
||||||
sel = get_param(block, 'wrapperFunc');
|
sel = get_param(block, 'appWrapperFunc');
|
||||||
basePath = get_param(block, 'wrapperPath');
|
basePath = get_param(block, 'appWrapperPath');
|
||||||
if isempty(basePath)
|
if isempty(basePath)
|
||||||
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
|
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
|
||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
newBody = get_param(block, 'wrapperCode');
|
newBody = get_param(block, 'appWrapperCode');
|
||||||
code = fileread(filename);
|
code = fileread(filename);
|
||||||
code = regexprep(code, '\r\n?', '\n');
|
code = regexprep(code, '\r\n?', '\n');
|
||||||
|
newBody = strrep(newBody, '\', '\\');
|
||||||
code = editCode.insertSection(code, section, newBody);
|
code = editCode.insertSection(code, section, newBody);
|
||||||
% else
|
% else
|
||||||
% % Обновляем тело функции
|
% % Обновляем тело функции
|
||||||
@@ -189,11 +185,11 @@ classdef mcuMask
|
|||||||
mcuMask.disp(1, ['Обновлено: ' sel]);
|
mcuMask.disp(1, ['Обновлено: ' sel]);
|
||||||
end
|
end
|
||||||
|
|
||||||
function openWrapperCode(callbackContext)
|
function openAppWrapperCode(callbackContext)
|
||||||
block = gcb;
|
block = gcb;
|
||||||
|
|
||||||
% Получаем имя функции и путь к файлам
|
% Получаем имя функции и путь к файлам
|
||||||
filename = mcuMask.getAbsolutePath(mcuMask.getWrapperUserFile(block));
|
filename = mcuPath.getAbsolutePath(mcuMask.getWrapperUserFile(block));
|
||||||
if exist(filename, 'file') == 2
|
if exist(filename, 'file') == 2
|
||||||
% Формируем команду без кавычек
|
% Формируем команду без кавычек
|
||||||
cmd = sprintf('rundll32.exe shell32.dll,OpenAs_RunDLL %s', filename);
|
cmd = sprintf('rundll32.exe shell32.dll,OpenAs_RunDLL %s', filename);
|
||||||
@@ -216,83 +212,27 @@ classdef mcuMask
|
|||||||
end
|
end
|
||||||
|
|
||||||
function btnAddSrc(callbackContext)
|
function btnAddSrc(callbackContext)
|
||||||
blockHandle = gcb;
|
mcuPath.addSourceFileTable('srcTable', 'Выберите исходные файлы');
|
||||||
% Открываем проводник для выбора файлов
|
|
||||||
[files, pathstr] = uigetfile({ ...
|
|
||||||
'*.c;*.cpp', 'Исходные файлы (*.c, *.cpp)'; ...
|
|
||||||
'*.obj;*.lib', 'Библиотеки (*.obj, *.lib)'; ...
|
|
||||||
'*.*', 'Все файлы (*.*)'}, ...
|
|
||||||
'Выберите файлы', ...
|
|
||||||
'MultiSelect', 'on');
|
|
||||||
|
|
||||||
if isequal(files, 0)
|
|
||||||
return; % Отмена выбора
|
|
||||||
end
|
|
||||||
if ischar(files)
|
|
||||||
files = {files}; % Один файл — в cell
|
|
||||||
end
|
|
||||||
% Парсим строку в cell-массив
|
|
||||||
oldTable = customtable.parse('srcTable');
|
|
||||||
|
|
||||||
% Добавляем новые пути, проверяя уникальность
|
|
||||||
for i = 1:numel(files)
|
|
||||||
fullpath = fullfile(pathstr, files{i});
|
|
||||||
rel = mcuMask.absoluteToRelativePath(fullpath);
|
|
||||||
if ~any(strcmp(rel, oldTable))
|
|
||||||
oldTable{end+1, 1} = rel;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Парсим строку в cell-массив
|
|
||||||
customtable.collect('srcTable', oldTable);
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function btnAddInc(callbackContext)
|
function btnAddInc(callbackContext)
|
||||||
blockHandle = gcb;
|
mcuPath.addPathTable('incTable', 'Выберите папку с заголовочными файлами');
|
||||||
% Открываем проводник для выбора папок
|
|
||||||
pathstr = uigetdir(pwd, 'Выберите папку с заголовочными файлами');
|
|
||||||
if isequal(pathstr, 0)
|
|
||||||
return; % Отмена выбора
|
|
||||||
end
|
|
||||||
% Парсим таблицу
|
|
||||||
oldTable = customtable.parse('incTable');
|
|
||||||
|
|
||||||
rel = mcuMask.absoluteToRelativePath(pathstr);
|
|
||||||
|
|
||||||
% Проверяем наличие пути
|
|
||||||
if ~any(strcmp(rel, oldTable))
|
|
||||||
oldTable{end+1, 1} = rel;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Собираем таблицу
|
|
||||||
customtable.collect('incTable', oldTable);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
%% PERIPH CONFIG
|
%% PERIPH CONFIG
|
||||||
|
|
||||||
function periphPath_add(callbackContext)
|
function periphPath_add(callbackContext)
|
||||||
block = gcbh;
|
mcuPath.addAnyFile('periphPath');
|
||||||
mask = Simulink.Mask.get(block);
|
|
||||||
[file, path] = uigetfile({'*.*','Все файлы (*.*)'}, 'Выберите файл');
|
|
||||||
if isequal(file, 0) || isequal(path, 0)
|
|
||||||
% Отмена выбора — ничего не делаем
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
fullFilePath = fullfile(path, file);
|
|
||||||
rel = mcuMask.absoluteToRelativePath(fullFilePath);
|
|
||||||
param = mask.getParameter('periphPath');
|
|
||||||
param.Value = rel;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%% COMPILE
|
||||||
function compile(callbackContext)
|
function compile(callbackContext)
|
||||||
addpath('MCU_Wrapper');
|
compiler.compile();
|
||||||
mexing(1);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function updateModel(callbackContext)
|
function updateModel(callbackContext)
|
||||||
addpath('MCU_Wrapper');
|
addpath(mcuPath.get('wrapperPath'));
|
||||||
res = mexing(1);
|
res = mexing(1);
|
||||||
if res ~= 0
|
if res ~= 0
|
||||||
return;
|
return;
|
||||||
@@ -309,16 +249,20 @@ classdef mcuMask
|
|||||||
web('https://www.mathworks.com/matlabcentral/fileexchange/14317-findjobj-find-java-handles-of-matlab-graphic-objects');
|
web('https://www.mathworks.com/matlabcentral/fileexchange/14317-findjobj-find-java-handles-of-matlab-graphic-objects');
|
||||||
end
|
end
|
||||||
|
|
||||||
function set_name()
|
function set_name(callbackContext)
|
||||||
block = gcb;
|
block = gcb;
|
||||||
% Получаем параметр имени S-Function из маски блока
|
% Получаем параметр имени S-Function из маски блока
|
||||||
newName = get_param(block, 'sfuncName');
|
newName = mcuMask.get_name();
|
||||||
|
|
||||||
% Путь к файлу, в котором надо заменить строку
|
% Путь к файлу, в котором надо заменить строку
|
||||||
cFilePath = fullfile(pwd, './MCU_Wrapper/MCU.c'); % <-- укажи правильный путь
|
cFilePath = fullfile(pwd, mcuPath.get('wrapperPath'), 'MCU.c'); % <-- укажи правильный путь
|
||||||
|
|
||||||
% Считаем файл в память
|
% Считаем файл в память
|
||||||
fileText = fileread(cFilePath);
|
try
|
||||||
|
fileText = fileread(cFilePath);
|
||||||
|
catch
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
% Регулярное выражение для поиска строки с define
|
% Регулярное выражение для поиска строки с define
|
||||||
% Заменим строку вида: #define S_FUNCTION_NAME old_name
|
% Заменим строку вида: #define S_FUNCTION_NAME old_name
|
||||||
@@ -336,10 +280,8 @@ classdef mcuMask
|
|||||||
error('Не удалось открыть файл для записи.');
|
error('Не удалось открыть файл для записи.');
|
||||||
end
|
end
|
||||||
fwrite(fid, updatedText);
|
fwrite(fid, updatedText);
|
||||||
fclose(fid);
|
fclose(fid);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -347,8 +289,8 @@ classdef mcuMask
|
|||||||
methods(Static, Access = private)
|
methods(Static, Access = private)
|
||||||
|
|
||||||
function [filename, section, tool, example] = getWrapperUserFile(block)
|
function [filename, section, tool, example] = getWrapperUserFile(block)
|
||||||
sel = get_param(block, 'wrapperFunc');
|
sel = get_param(block, 'appWrapperFunc');
|
||||||
basePath = get_param(block, 'wrapperPath');
|
basePath = mcuPath.get('appWrapperPath');
|
||||||
if isempty(basePath)
|
if isempty(basePath)
|
||||||
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
|
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
|
||||||
return;
|
return;
|
||||||
@@ -445,81 +387,13 @@ classdef mcuMask
|
|||||||
mcuMask.disp(clear_flag, '');
|
mcuMask.disp(clear_flag, '');
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function name = get_name()
|
||||||
function absPath = getAbsolutePath(relPath)
|
block = gcb;
|
||||||
% relativeToAbsolutePath — преобразует относительный путь в абсолютный.
|
% Получаем параметр имени S-Function из маски блока
|
||||||
%
|
name = get_param(block, 'sfuncName');
|
||||||
% Если путь уже абсолютный — возвращается он же, приведённый к канонической форме.
|
|
||||||
% Если путь относительный — преобразуется относительно текущей директории.
|
|
||||||
|
|
||||||
% Проверка: абсолютный ли путь
|
|
||||||
if ispc
|
|
||||||
isAbsolute = ~isempty(regexp(relPath, '^[a-zA-Z]:[\\/]', 'once')) || startsWith(relPath, '\\');
|
|
||||||
else
|
|
||||||
isAbsolute = startsWith(relPath, '/');
|
|
||||||
end
|
|
||||||
|
|
||||||
if isAbsolute
|
|
||||||
% Канонизируем абсолютный путь (убираем ./, ../ и т.п.)
|
|
||||||
absPath = char(java.io.File(relPath).getCanonicalPath());
|
|
||||||
else
|
|
||||||
% Строим абсолютный путь от текущей директории
|
|
||||||
cwd = pwd;
|
|
||||||
combined = fullfile(cwd, relPath);
|
|
||||||
absPath = char(java.io.File(combined).getCanonicalPath());
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function rel = absoluteToRelativePath(pathstr)
|
|
||||||
% absoluteToRelativePath — преобразует абсолютный путь в относительный от текущей директории.
|
|
||||||
%
|
|
||||||
% Если путь находится в текущей директории или вложенной в неё — добавляется префикс './'
|
|
||||||
% Если выше — формируются переходы '..'
|
|
||||||
% Если путь совпадает с текущей директорией — возвращается '.'
|
|
||||||
|
|
||||||
% Получаем текущую рабочую директорию
|
|
||||||
cwd = pwd;
|
|
||||||
|
|
||||||
% Преобразуем пути в канонические абсолютные пути
|
|
||||||
fullpath = char(java.io.File(pathstr).getCanonicalPath());
|
|
||||||
cwd = char(java.io.File(cwd).getCanonicalPath());
|
|
||||||
|
|
||||||
% Разбиваем пути на части
|
|
||||||
targetParts = strsplit(fullpath, filesep);
|
|
||||||
baseParts = strsplit(cwd, filesep);
|
|
||||||
|
|
||||||
% Находим длину общего префикса
|
|
||||||
j = 1;
|
|
||||||
while j <= min(length(targetParts), length(baseParts)) && strcmpi(targetParts{j}, baseParts{j})
|
|
||||||
j = j + 1;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Формируем количество подъемов ".." из cwd
|
|
||||||
numUps = length(baseParts) - (j - 1);
|
|
||||||
ups = repmat({'..'}, 1, numUps);
|
|
||||||
|
|
||||||
% Оставшаяся часть пути после общего префикса
|
|
||||||
rest = targetParts(j:end);
|
|
||||||
|
|
||||||
% Объединяем для получения относительного пути
|
|
||||||
relParts = [ups, rest];
|
|
||||||
rel = fullfile(relParts{:});
|
|
||||||
|
|
||||||
% Если путь пустой — это текущая директория
|
|
||||||
if isempty(rel)
|
|
||||||
rel = '.';
|
|
||||||
end
|
|
||||||
|
|
||||||
% Если путь не содержит ".." и начинается внутри текущей директории — добавим './'
|
|
||||||
if ~isempty(rest) && isempty(ups)
|
|
||||||
rel = fullfile('.', rel);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function checkbox_state = read_checkbox(checkboxName)
|
function checkbox_state = read_checkbox(checkboxName)
|
||||||
maskValues = get_param(gcbh, 'MaskValues');
|
maskValues = get_param(gcbh, 'MaskValues');
|
||||||
paramNames = get_param(gcbh, 'MaskNames');
|
paramNames = get_param(gcbh, 'MaskNames');
|
||||||
@@ -579,15 +453,7 @@ classdef mcuMask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function res = ternary(cond, valTrue, valFalse)
|
|
||||||
if cond
|
|
||||||
res = valTrue;
|
|
||||||
else
|
|
||||||
res = valFalse;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function tool(text, example)
|
function tool(text, example)
|
||||||
% Устанавливает заданный текст в параметр Text Area 'toolText' через объект маски
|
% Устанавливает заданный текст в параметр Text Area 'toolText' через объект маски
|
||||||
|
|
||||||
|
|||||||
168
McuLib/m/mcuPath.m
Normal file
168
McuLib/m/mcuPath.m
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
classdef mcuPath
|
||||||
|
methods(Static)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function path = get(paramName)
|
||||||
|
blockPath = gcb;
|
||||||
|
path = get_param(blockPath, paramName);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function addSourceFileTable(targetParamName, message)
|
||||||
|
% Открываем проводник для выбора файлов
|
||||||
|
[files, pathstr] = uigetfile({ ...
|
||||||
|
'*.c;*.cpp', 'Исходные файлы (*.c, *.cpp)'; ...
|
||||||
|
'*.obj;*.lib', 'Библиотеки (*.obj, *.lib)'; ...
|
||||||
|
'*.*', 'Все файлы (*.*)'}, ...
|
||||||
|
message, ...
|
||||||
|
'MultiSelect', 'on');
|
||||||
|
|
||||||
|
if isequal(files, 0)
|
||||||
|
return; % Отмена выбора
|
||||||
|
end
|
||||||
|
if ischar(files)
|
||||||
|
files = {files}; % Один файл — в cell
|
||||||
|
end
|
||||||
|
% Парсим строку в cell-массив
|
||||||
|
oldTable = customtable.parse(targetParamName);
|
||||||
|
|
||||||
|
% Добавляем новые пути, проверяя уникальность
|
||||||
|
for i = 1:numel(files)
|
||||||
|
fullpath = fullfile(pathstr, files{i});
|
||||||
|
rel = mcuPath.absoluteToRelativePath(fullpath);
|
||||||
|
if ~any(strcmp(rel, oldTable))
|
||||||
|
oldTable{end+1, 1} = rel;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Парсим строку в cell-массив
|
||||||
|
customtable.collect(targetParamName, oldTable);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function addPathTable(targetParamName, message)
|
||||||
|
% Открываем проводник для выбора папок
|
||||||
|
pathstr = uigetdir(pwd, message);
|
||||||
|
if isequal(pathstr, 0)
|
||||||
|
return; % Отмена выбора
|
||||||
|
end
|
||||||
|
% Парсим таблицу
|
||||||
|
oldTable = customtable.parse(targetParamName);
|
||||||
|
|
||||||
|
rel = mcuPath.absoluteToRelativePath(pathstr);
|
||||||
|
|
||||||
|
% Проверяем наличие пути
|
||||||
|
if ~any(strcmp(rel, oldTable))
|
||||||
|
oldTable{end+1, 1} = rel;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Собираем таблицу
|
||||||
|
customtable.collect(targetParamName, oldTable);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function addPath(targetParamName, message)
|
||||||
|
block = gcb;
|
||||||
|
mask = Simulink.Mask.get(block);
|
||||||
|
% Открываем окно выбора папки
|
||||||
|
folderPath = uigetdir('', 'Выберите папку');
|
||||||
|
% Проверка на отмену
|
||||||
|
if isequal(folderPath, 0)
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
% Установка значения параметра маски
|
||||||
|
rel = mcuPath.absoluteToRelativePath(folderPath);
|
||||||
|
param = mask.getParameter(targetParamName);
|
||||||
|
param.Value = rel;
|
||||||
|
end
|
||||||
|
|
||||||
|
function addAnyFile(targetParamName, message)
|
||||||
|
block = gcbh;
|
||||||
|
mask = Simulink.Mask.get(block);
|
||||||
|
[file, path] = uigetfile({'*.*','Все файлы (*.*)'}, 'Выберите файл');
|
||||||
|
if isequal(file, 0) || isequal(path, 0)
|
||||||
|
% Отмена выбора — ничего не делаем
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
fullFilePath = fullfile(path, file);
|
||||||
|
rel = mcuPath.absoluteToRelativePath(fullFilePath);
|
||||||
|
param = mask.getParameter(targetParamName);
|
||||||
|
param.Value = rel;
|
||||||
|
end
|
||||||
|
|
||||||
|
function absPath = getAbsolutePath(relPath)
|
||||||
|
% relativeToAbsolutePath — преобразует относительный путь в абсолютный.
|
||||||
|
%
|
||||||
|
% Если путь уже абсолютный — возвращается он же, приведённый к канонической форме.
|
||||||
|
% Если путь относительный — преобразуется относительно текущей директории.
|
||||||
|
|
||||||
|
% Проверка: абсолютный ли путь
|
||||||
|
if ispc
|
||||||
|
isAbsolute = ~isempty(regexp(relPath, '^[a-zA-Z]:[\\/]', 'once')) || startsWith(relPath, '\\');
|
||||||
|
else
|
||||||
|
isAbsolute = startsWith(relPath, '/');
|
||||||
|
end
|
||||||
|
|
||||||
|
if isAbsolute
|
||||||
|
% Канонизируем абсолютный путь (убираем ./, ../ и т.п.)
|
||||||
|
absPath = char(java.io.File(relPath).getCanonicalPath());
|
||||||
|
else
|
||||||
|
% Строим абсолютный путь от текущей директории
|
||||||
|
cwd = pwd;
|
||||||
|
combined = fullfile(cwd, relPath);
|
||||||
|
absPath = char(java.io.File(combined).getCanonicalPath());
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function rel = absoluteToRelativePath(pathstr)
|
||||||
|
% absoluteToRelativePath — преобразует абсолютный путь в относительный от текущей директории.
|
||||||
|
%
|
||||||
|
% Если путь находится в текущей директории или вложенной в неё — добавляется префикс './'
|
||||||
|
% Если выше — формируются переходы '..'
|
||||||
|
% Если путь совпадает с текущей директорией — возвращается '.'
|
||||||
|
|
||||||
|
% Получаем текущую рабочую директорию
|
||||||
|
cwd = pwd;
|
||||||
|
|
||||||
|
% Преобразуем пути в канонические абсолютные пути
|
||||||
|
fullpath = char(java.io.File(pathstr).getCanonicalPath());
|
||||||
|
cwd = char(java.io.File(cwd).getCanonicalPath());
|
||||||
|
|
||||||
|
% Разбиваем пути на части
|
||||||
|
targetParts = strsplit(fullpath, filesep);
|
||||||
|
baseParts = strsplit(cwd, filesep);
|
||||||
|
|
||||||
|
% Находим длину общего префикса
|
||||||
|
j = 1;
|
||||||
|
while j <= min(length(targetParts), length(baseParts)) && strcmpi(targetParts{j}, baseParts{j})
|
||||||
|
j = j + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Формируем количество подъемов ".." из cwd
|
||||||
|
numUps = length(baseParts) - (j - 1);
|
||||||
|
ups = repmat({'..'}, 1, numUps);
|
||||||
|
|
||||||
|
% Оставшаяся часть пути после общего префикса
|
||||||
|
rest = targetParts(j:end);
|
||||||
|
|
||||||
|
% Объединяем для получения относительного пути
|
||||||
|
relParts = [ups, rest];
|
||||||
|
rel = fullfile(relParts{:});
|
||||||
|
|
||||||
|
% Если путь пустой — это текущая директория
|
||||||
|
if isempty(rel)
|
||||||
|
rel = '.';
|
||||||
|
end
|
||||||
|
|
||||||
|
% Если путь не содержит ".." и начинается внутри текущей директории — добавим './'
|
||||||
|
if ~isempty(rest) && isempty(ups)
|
||||||
|
rel = fullfile('.', rel);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -5,8 +5,8 @@ classdef mcuPorts
|
|||||||
function write()
|
function write()
|
||||||
block = gcb;
|
block = gcb;
|
||||||
mask = Simulink.Mask.get(block);
|
mask = Simulink.Mask.get(block);
|
||||||
hPath = fullfile('.\MCU_Wrapper', 'mcu_wrapper_conf.h');
|
hPath = fullfile(mcuPath.get('wrapperPath'), 'mcu_wrapper_conf.h');
|
||||||
cPath = fullfile('.\MCU_Wrapper', 'mcu_wrapper.c');
|
cPath = fullfile(mcuPath.get('wrapperPath'), 'mcu_wrapper.c');
|
||||||
mcuPorts.defaultUnused();
|
mcuPorts.defaultUnused();
|
||||||
%% CREATE
|
%% CREATE
|
||||||
prefixNumb = 'IN';
|
prefixNumb = 'IN';
|
||||||
@@ -190,10 +190,10 @@ classdef mcuPorts
|
|||||||
|
|
||||||
for i = 1:n
|
for i = 1:n
|
||||||
if i == 1
|
if i == 1
|
||||||
lines{end+1} = '#define OFFSET_ARRAY_1 0';
|
lines{end+1} = sprintf('#define OFFSET_%s_ARRAY_1 0', upperPrefix);
|
||||||
else
|
else
|
||||||
lines{end+1} = sprintf('#define OFFSET_ARRAY_%d (OFFSET_ARRAY_%d + %s_PORT_%d_WIDTH)', ...
|
lines{end+1} = sprintf('#define OFFSET_%s_ARRAY_%d (OFFSET_%s_ARRAY_%d + %s_PORT_%d_WIDTH)', ...
|
||||||
i, i - 1, upper(portPrefixes{i - 1}), i - 1);
|
upperPrefix, i, upperPrefix, i - 1, upper(portPrefixes{i - 1}), i - 1);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
newAuto = strjoin(lines, newline);
|
newAuto = strjoin(lines, newline);
|
||||||
@@ -251,7 +251,7 @@ classdef mcuPorts
|
|||||||
if i == n
|
if i == n
|
||||||
comma = '';
|
comma = '';
|
||||||
end
|
end
|
||||||
lines{end+1} = sprintf(' OFFSET_ARRAY_%d%s', i, comma);
|
lines{end+1} = sprintf(' OFFSET_%s_ARRAY_%d%s', upperPrefix, i, comma);
|
||||||
end
|
end
|
||||||
lines{end+1} = '};';
|
lines{end+1} = '};';
|
||||||
lines{end+1} = '';
|
lines{end+1} = '';
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ function res = mexing(compile_mode)
|
|||||||
Ts = 0.00001;
|
Ts = 0.00001;
|
||||||
|
|
||||||
if compile_mode == 1
|
if compile_mode == 1
|
||||||
delete("*.mexw64")
|
delete('*.mexw64')
|
||||||
delete("*.mexw64.pdb")
|
delete('*.mexw64.pdb')
|
||||||
delete(".\MCU_Wrapper\Outputs\*.*");
|
delete([mcuPath.get('wrapperPath'), '\Outputs\*.*']);
|
||||||
set_param(gcb, 'consoleOutput', '');
|
set_param(gcb, 'consoleOutput', '');
|
||||||
% Порты S-Function
|
compiler.updateRunBat();
|
||||||
mcuPorts.write();
|
|
||||||
% Дефайны
|
% Дефайны
|
||||||
definesUserArg = parseDefinesMaskText();
|
definesUserArg = parseDefinesMaskText();
|
||||||
definesWrapperConfigArg = buildWrapperDefinesString();
|
definesWrapperConfigArg = buildWrapperDefinesString();
|
||||||
@@ -30,8 +29,11 @@ function res = mexing(compile_mode)
|
|||||||
|
|
||||||
[includesArg, codeArg] = make_mex_arguments('incTable', 'srcTable');
|
[includesArg, codeArg] = make_mex_arguments('incTable', 'srcTable');
|
||||||
|
|
||||||
|
Name = mcuMask.get_name();
|
||||||
|
|
||||||
% Вызов батника с двумя параметрами: includes и code
|
% Вызов батника с двумя параметрами: includes и code
|
||||||
cmd = sprintf('.\\MCU_Wrapper\\run_mex.bat "%s" "%s" "%s" "%s" %s %s', includesArg, codeArg, definesUserArg, definesConfigArg, modeArg, echoArg);
|
run_bat_mex_path = fullfile(mcuPath.get('wrapperPath'), 'run_mex.bat');
|
||||||
|
cmd = sprintf('%s %s "%s" "%s" "%s" "%s" %s %s', run_bat_mex_path, Name, includesArg, codeArg, definesUserArg, definesConfigArg, modeArg, echoArg);
|
||||||
|
|
||||||
if mcuMask.read_checkbox('extConsol')
|
if mcuMask.read_checkbox('extConsol')
|
||||||
cmdout = runBatAndShowOutput(cmd);
|
cmdout = runBatAndShowOutput(cmd);
|
||||||
@@ -68,9 +70,6 @@ function res = mexing(compile_mode)
|
|||||||
config = periphConfig.update_config(blockPath, config);
|
config = periphConfig.update_config(blockPath, config);
|
||||||
periphConfig.write_config(config);
|
periphConfig.write_config(config);
|
||||||
periphConfig.update(blockPath, config);
|
periphConfig.update(blockPath, config);
|
||||||
% Порты S-Function
|
|
||||||
mcuPorts.write();
|
|
||||||
% set_param(gcb, 'consoleOutput', 'Peripheral configuration file loaded. Re-open Block Parameters');
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ classdef periphConfig
|
|||||||
% Проверяем, была ли маска открыта
|
% Проверяем, была ли маска открыта
|
||||||
% wasOpen = isMaskDialogOpen(blockPath);
|
% wasOpen = isMaskDialogOpen(blockPath);
|
||||||
mask = Simulink.Mask.get(blockPath);
|
mask = Simulink.Mask.get(blockPath);
|
||||||
periphPath = get_param(blockPath, 'periphPath');
|
periphPath = mcuPath.get('periphPath');
|
||||||
[periphPath, ~, ~] = fileparts(periphPath);
|
[periphPath, ~, ~] = fileparts(periphPath);
|
||||||
|
|
||||||
tableNames = {'incTable', 'srcTable'};
|
tableNames = {'incTable', 'srcTable'};
|
||||||
@@ -91,7 +91,7 @@ classdef periphConfig
|
|||||||
for i = 1:numel(periphs)
|
for i = 1:numel(periphs)
|
||||||
periph = periphs{i};
|
periph = periphs{i};
|
||||||
|
|
||||||
% Пропускаем Code и UserCode, они уже обработаны
|
% Пропускаем Code и UserCode
|
||||||
if strcmp(periph, 'Code') || strcmp(periph, 'UserCode')
|
if strcmp(periph, 'Code') || strcmp(periph, 'UserCode')
|
||||||
continue;
|
continue;
|
||||||
end
|
end
|
||||||
@@ -165,86 +165,24 @@ classdef periphConfig
|
|||||||
fwrite(fid, jsonText, 'char');
|
fwrite(fid, jsonText, 'char');
|
||||||
fclose(fid);
|
fclose(fid);
|
||||||
end
|
end
|
||||||
|
|
||||||
function clear_all_from_container(mask, containerName)
|
|
||||||
% allControls = mask.getDialogControls();
|
|
||||||
container = mask.getDialogControl(containerName);
|
|
||||||
if isempty(container)
|
|
||||||
warning('Контейнер "%s" не найден.', containerName);
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Рекурсивно собрать все параметры (не вкладки)
|
|
||||||
paramsToDelete = mcuMask.collect_all_parameters(container);
|
|
||||||
|
|
||||||
% Удаляем все параметры
|
|
||||||
for i = 1:numel(paramsToDelete)
|
|
||||||
try
|
|
||||||
mask.removeParameter(paramsToDelete{i});
|
|
||||||
catch
|
|
||||||
warning('Не удалось удалить параметр %s', paramsToDelete{i});
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Рекурсивно удалить все вкладки внутри контейнера
|
|
||||||
mcuMask.delete_all_tabs(mask, container);
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
methods(Static, Access=private)
|
methods(Static, Access=private)
|
||||||
|
|
||||||
function res = addCodeConfig(codeConfig, periphPath)
|
function res = addCodeConfig(codeConfig, periphPath)
|
||||||
% Возвращает 0 при успехе, 1 при ошибке
|
% Возвращает 0 при успехе, 1 при ошибке
|
||||||
try
|
try
|
||||||
% Источники
|
% Формируем строки
|
||||||
srcList = {};
|
srcText = compiler.createSourcesBat('code_PERIPH', codeConfig.Sources.Options, periphPath);
|
||||||
if isfield(codeConfig, 'Sources') && isfield(codeConfig.Sources, 'Options')
|
incText = compiler.createIncludesBat('includes_PERIPH', codeConfig.Includes.Options, periphPath);
|
||||||
srcFiles = codeConfig.Sources.Options;
|
|
||||||
for i = 1:numel(srcFiles)
|
|
||||||
fullPath = fullfile(periphPath, srcFiles{i});
|
|
||||||
srcList{end+1} = [strrep(fullPath, '\', '\\')];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Формируем srcText с переносами строк и ^
|
|
||||||
srcText = '';
|
|
||||||
for i = 1:numel(srcList)
|
|
||||||
if i < numel(srcList)
|
|
||||||
srcText = [srcText srcList{i} '^' newline ' '];
|
|
||||||
else
|
|
||||||
srcText = [srcText srcList{i}];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Инклуды
|
|
||||||
incList = {};
|
|
||||||
if isfield(codeConfig, 'Includes') && isfield(codeConfig.Includes, 'Options')
|
|
||||||
incPaths = codeConfig.Includes.Options;
|
|
||||||
for i = 1:numel(incPaths)
|
|
||||||
fullPath = fullfile(periphPath, incPaths{i});
|
|
||||||
incList{end+1} = ['-I"' strrep(fullPath, '\', '\\') '"'];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Формируем incText с переносами строк и ^
|
|
||||||
incText = '';
|
|
||||||
for i = 1:numel(incList)
|
|
||||||
if i == 1 && numel(incList) ~= 1
|
|
||||||
incText = [incText incList{i} '^' newline];
|
|
||||||
elseif i < numel(incList)
|
|
||||||
incText = [incText ' ' incList{i} '^' newline];
|
|
||||||
else
|
|
||||||
incText = [incText ' ' incList{i}];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Добавляем префиксы
|
|
||||||
srcText = ['set code_PERIPH' '=' srcText];
|
|
||||||
incText = ['set includes_PERIPH' '=' incText];
|
|
||||||
|
|
||||||
% Записываем результат
|
% Записываем результат
|
||||||
res = periphConfig.updateRunMexBat(srcText, incText); % Всё прошло успешно
|
res = compiler.updateRunMexBat(srcText, incText, ':: PERIPH BAT'); % Всё прошло успешно
|
||||||
catch
|
catch
|
||||||
% В случае ошибки просто возвращаем 1
|
% В случае ошибки просто возвращаем 1
|
||||||
res = 1;
|
res = 1;
|
||||||
@@ -289,7 +227,7 @@ classdef periphConfig
|
|||||||
%
|
%
|
||||||
% Возвращает:
|
% Возвращает:
|
||||||
% res - 0 при успехе, 1 при ошибке
|
% res - 0 при успехе, 1 при ошибке
|
||||||
wrapPath = fullfile('.\MCU_Wrapper', 'mcu_wrapper.c');
|
wrapPath = fullfile(mcuPath.get('wrapperPath'), 'mcu_wrapper.c');
|
||||||
res = 1;
|
res = 1;
|
||||||
try
|
try
|
||||||
code = fileread(wrapPath);
|
code = fileread(wrapPath);
|
||||||
@@ -314,36 +252,6 @@ classdef periphConfig
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function res = updateRunMexBat(srcText, incText)
|
|
||||||
% Входные параметры:
|
|
||||||
% srcText - текст для записи set code_...
|
|
||||||
% incText - текст для записи set includes_...
|
|
||||||
%
|
|
||||||
% Возвращает:
|
|
||||||
% res - 0 при успехе, 1 при ошибке
|
|
||||||
periphBat = [srcText '\n\n' incText];
|
|
||||||
batPath = fullfile('.\MCU_Wrapper', 'run_mex.bat');
|
|
||||||
res = 1;
|
|
||||||
try
|
|
||||||
code = fileread(batPath);
|
|
||||||
code = regexprep(code, '\r\n?', '\n');
|
|
||||||
|
|
||||||
% Записываем строки srcText и incText с переносами строк
|
|
||||||
code = editCode.insertSection(code, ':: PERIPH BAT', periphBat);
|
|
||||||
|
|
||||||
fid = fopen(batPath, 'w', 'n', 'UTF-8');
|
|
||||||
if fid == -1
|
|
||||||
error('Не удалось открыть файл для записи');
|
|
||||||
end
|
|
||||||
fwrite(fid, code);
|
|
||||||
fclose(fid);
|
|
||||||
res = 1;
|
|
||||||
catch ME
|
|
||||||
mcuMask.disp(0, '\nОшибка: неудачная запись в файл при записи файла: %s', ME.message);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function addDefineConfig(mask, containerName, periphName, defPrompt, def)
|
function addDefineConfig(mask, containerName, periphName, defPrompt, def)
|
||||||
% mask — объект маски Simulink.Mask.get(blockPath)
|
% mask — объект маски Simulink.Mask.get(blockPath)
|
||||||
@@ -371,6 +279,8 @@ classdef periphConfig
|
|||||||
paramType = 'checkbox';
|
paramType = 'checkbox';
|
||||||
case 'edit'
|
case 'edit'
|
||||||
paramType = 'edit';
|
paramType = 'edit';
|
||||||
|
case 'popup'
|
||||||
|
paramType = 'popup';
|
||||||
otherwise
|
otherwise
|
||||||
% Игнорируем остальные типы
|
% Игнорируем остальные типы
|
||||||
return;
|
return;
|
||||||
@@ -378,28 +288,46 @@ classdef periphConfig
|
|||||||
|
|
||||||
paramName = matlab.lang.makeValidName(defPrompt);
|
paramName = matlab.lang.makeValidName(defPrompt);
|
||||||
|
|
||||||
% Преобразуем значение Default в строку для Value
|
% Получаем значение
|
||||||
val = def.Default;
|
if strcmp(paramType, 'popup')
|
||||||
if islogical(val)
|
if isfield(def, 'Def') && iscell(def.Def) && ~isempty(def.Def)
|
||||||
valStr = mcuMask.ternary(val, 'on', 'off');
|
choices = def.Def;
|
||||||
elseif isnumeric(val)
|
valStr = ''; % по умолчанию — ничего
|
||||||
valStr = num2str(val);
|
else
|
||||||
elseif ischar(val)
|
warning('Popout параметр "%s" не содержит допустимого списка в Def.', defPrompt);
|
||||||
valStr = val;
|
return;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
error('Unsupported default value type for %s.%s', periphName, defPrompt);
|
val = def.Default;
|
||||||
|
if islogical(val)
|
||||||
|
valStr = periphConfig.ternary(val, 'on', 'off');
|
||||||
|
elseif isnumeric(val)
|
||||||
|
valStr = num2str(val);
|
||||||
|
elseif ischar(val)
|
||||||
|
valStr = val;
|
||||||
|
else
|
||||||
|
error('Unsupported default value type for %s.%s', periphName, defPrompt);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
% Добавляем параметр в маску
|
% Добавляем параметр в маску
|
||||||
param = mask.addParameter( ...
|
if strcmp(paramType, 'popup')
|
||||||
'Type', paramType, ...
|
param = mask.addParameter( ...
|
||||||
'Prompt', def.Prompt, ...
|
'Type', paramType, ...
|
||||||
'Name', paramName, ...
|
'Prompt', def.Prompt, ...
|
||||||
'Value', valStr, ...
|
'Name', paramName, ...
|
||||||
'Container', periphName ...
|
'Container', periphName ...
|
||||||
);
|
);
|
||||||
|
else
|
||||||
|
param = mask.addParameter( ...
|
||||||
|
'Type', paramType, ...
|
||||||
|
'Prompt', def.Prompt, ...
|
||||||
|
'Name', paramName, ...
|
||||||
|
'Value', valStr, ...
|
||||||
|
'Container', periphName ...
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
param.Alias = def.Def;
|
|
||||||
param.Evaluate = 'off';
|
param.Evaluate = 'off';
|
||||||
|
|
||||||
if def.NewRow
|
if def.NewRow
|
||||||
@@ -407,8 +335,46 @@ classdef periphConfig
|
|||||||
else
|
else
|
||||||
param.DialogControl.Row = 'current';
|
param.DialogControl.Row = 'current';
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if strcmp(paramType, 'popup')
|
||||||
|
param.TypeOptions = def.Def;
|
||||||
|
else
|
||||||
|
param.Alias = def.Def;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function clear_all_from_container(mask, containerName)
|
||||||
|
% allControls = mask.getDialogControls();
|
||||||
|
container = mask.getDialogControl(containerName);
|
||||||
|
if isempty(container)
|
||||||
|
warning('Контейнер "%s" не найден.', containerName);
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Рекурсивно собрать все параметры (не вкладки)
|
||||||
|
paramsToDelete = mcuMask.collect_all_parameters(container);
|
||||||
|
|
||||||
|
% Удаляем все параметры
|
||||||
|
for i = 1:numel(paramsToDelete)
|
||||||
|
try
|
||||||
|
mask.removeParameter(paramsToDelete{i});
|
||||||
|
catch
|
||||||
|
warning('Не удалось удалить параметр %s', paramsToDelete{i});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Рекурсивно удалить все вкладки внутри контейнера
|
||||||
|
mcuMask.delete_all_tabs(mask, container);
|
||||||
|
end
|
||||||
|
|
||||||
|
function res = ternary(cond, valTrue, valFalse)
|
||||||
|
if cond
|
||||||
|
res = valTrue;
|
||||||
|
else
|
||||||
|
res = valFalse;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ static void mdlInitializeSizes(SimStruct* S)
|
|||||||
for (int i = 0; i < IN_PORT_NUMB; i++)
|
for (int i = 0; i < IN_PORT_NUMB; i++)
|
||||||
{
|
{
|
||||||
ssSetInputPortWidth(S, i, inLengths[i]);
|
ssSetInputPortWidth(S, i, inLengths[i]);
|
||||||
ssSetInputPortDirectFeedThrough(S, i, 0); // или 1, если нужно
|
ssSetInputPortDirectFeedThrough(S, i, 0);
|
||||||
ssSetInputPortRequiredContiguous(S, i, 1);
|
ssSetInputPortRequiredContiguous(S, i, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,13 +212,13 @@ void SIM_writeOutputs(SimStruct* S)
|
|||||||
int global_index;
|
int global_index;
|
||||||
|
|
||||||
//-------------WRITTING OUTPUT--------------
|
//-------------WRITTING OUTPUT--------------
|
||||||
for (int j = 0; j < OUT_PORT_NUMB; j++)
|
for (int arr_ind = 0; arr_ind < OUT_PORT_NUMB; arr_ind++)
|
||||||
{
|
{
|
||||||
Output = ssGetOutputPortRealSignal(S, j);
|
Output = ssGetOutputPortRealSignal(S, arr_ind);
|
||||||
for (int i = 0; i < outLengths[i]; i++)
|
for (int val_ind = 0; val_ind < outLengths[arr_ind]; val_ind++)
|
||||||
{
|
{
|
||||||
global_index = XD_OUTPUT_START + outOffsets[j] + i;
|
global_index = XD_OUTPUT_START + outOffsets[arr_ind] + val_ind;
|
||||||
Output[i] = Out_Buff[global_index];
|
Output[val_ind] = Out_Buff[global_index];
|
||||||
Out_Buff[global_index] = 0;
|
Out_Buff[global_index] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,13 +236,13 @@ void SIM_readInputs(SimStruct* S)
|
|||||||
int global_index;
|
int global_index;
|
||||||
|
|
||||||
//-------------READING INPUTS---------------
|
//-------------READING INPUTS---------------
|
||||||
for (int j = 0; j < IN_PORT_NUMB; j++)
|
for (int arr_ind = 0; arr_ind < IN_PORT_NUMB; arr_ind++)
|
||||||
{
|
{
|
||||||
Input = ssGetInputPortRealSignal(S, j);
|
Input = ssGetInputPortRealSignal(S, arr_ind);
|
||||||
for (int i = 0; i < inLengths[j]; i++)
|
for (int val_ind = 0; val_ind < inLengths[arr_ind]; val_ind++)
|
||||||
{
|
{
|
||||||
global_index = XD_INPUT_START + inOffsets[j] + i;
|
global_index = XD_INPUT_START + inOffsets[arr_ind] + val_ind;
|
||||||
In_Buff[global_index] = Input[i];
|
In_Buff[global_index] = Input[val_ind];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
|||||||
@@ -11,11 +11,12 @@
|
|||||||
:: %4 — режим компиляции (debug/release)
|
:: %4 — режим компиляции (debug/release)
|
||||||
|
|
||||||
:: Сохраняем как переменные
|
:: Сохраняем как переменные
|
||||||
set includes_USER=%~1
|
set filename=%~1
|
||||||
set code_USER=%~2
|
set includes_USER=%~2
|
||||||
set defines_USER=%~3
|
set code_USER=%~3
|
||||||
set defines_CONFIG=%~4
|
set defines_USER=%~4
|
||||||
set compil_mode=%~5
|
set defines_CONFIG=%~5
|
||||||
|
set compil_mode=%~6
|
||||||
|
|
||||||
:: Заменяем __EQ__ на =
|
:: Заменяем __EQ__ на =
|
||||||
set defines_USER=%defines_USER:__EQ__==%
|
set defines_USER=%defines_USER:__EQ__==%
|
||||||
@@ -51,15 +52,15 @@ set includes= %includes_WRAPPER% %includes_PERIPH% %includes_USER%
|
|||||||
set codes= %code_WRAPPER% %code_PERIPH% %code_USER%
|
set codes= %code_WRAPPER% %code_PERIPH% %code_USER%
|
||||||
set defines= %defines_WRAPPER% %defines_CONFIG% %defines_USER%
|
set defines= %defines_WRAPPER% %defines_CONFIG% %defines_USER%
|
||||||
:: -------OUTPUT FOLDER--------
|
:: -------OUTPUT FOLDER--------
|
||||||
set output= -outdir "."
|
set output= -outdir "." -output %filename%
|
||||||
|
|
||||||
:: если нужен дебаг, до запускаем run_mex с припиской debug
|
:: если нужен дебаг, до запускаем run_mex с припиской debug
|
||||||
IF [%1]==[debug] (set debug= -g)
|
IF %compil_mode%==debug (set debug= -g)
|
||||||
::-------------------------------------------------------------------------
|
::-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
::------START COMPILING-------
|
::------START COMPILING-------
|
||||||
if "%6"=="echo_enable" (
|
if "%7"=="echo_enable" (
|
||||||
echo Compiling...
|
echo Compiling...
|
||||||
|
|
||||||
echo ===========================
|
echo ===========================
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* @file app_config.h
|
* @file app_config.h
|
||||||
* @brief Çàãîëîâî÷íûé ôàéë äëÿ ïîëüçîâàòåëüñêèõ êîíôèãóðàöèé.
|
* @brief Заголовочный файл для пользовательских конфигураций.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
#ifndef _APP_CONFIG
|
#ifndef _APP_CONFIG
|
||||||
#define _APP_CONFIG
|
#define _APP_CONFIG
|
||||||
|
|||||||
BIN
mcuwrapper.mltbx
BIN
mcuwrapper.mltbx
Binary file not shown.
@@ -1,19 +1,19 @@
|
|||||||
<deployment-project plugin="plugin.toolbox" plugin-version="1.0">
|
<deployment-project plugin="plugin.toolbox" plugin-version="1.0">
|
||||||
<configuration file="E:\.WORK\MATLAB\matlab_23550\McuLib\mcuwrapper.prj" location="E:\.WORK\MATLAB\matlab_23550\McuLib" name="mcuwrapper" target="target.toolbox" target-name="Package Toolbox">
|
<configuration build-checksum="1721556499" file="E:\.WORK\MATLAB\mcu_matlab\mcuwrapper.prj" location="E:\.WORK\MATLAB\mcu_matlab" name="mcuwrapper" target="target.toolbox" target-name="Package Toolbox">
|
||||||
<param.appname>mcuwrapper</param.appname>
|
<param.appname>MCU Wrapper</param.appname>
|
||||||
<param.authnamewatermark>Razvalyaev</param.authnamewatermark>
|
<param.authnamewatermark>Razvalyaev</param.authnamewatermark>
|
||||||
<param.email>wot890089@mail.ru</param.email>
|
<param.email>wot890089@mail.ru</param.email>
|
||||||
<param.company>NIO-12</param.company>
|
<param.company>NIO-12</param.company>
|
||||||
<param.summary>Library for run MCU program in Simulink</param.summary>
|
<param.summary>Library for run MCU program in Simulink</param.summary>
|
||||||
<param.description />
|
<param.description />
|
||||||
<param.screenshot />
|
<param.screenshot />
|
||||||
<param.version>1.0</param.version>
|
<param.version>1.01</param.version>
|
||||||
<param.output>${PROJECT_ROOT}\mcuwrapper.mltbx</param.output>
|
<param.output>${PROJECT_ROOT}\MCU Wrapper.mltbx</param.output>
|
||||||
<param.products.name />
|
<param.products.name />
|
||||||
<param.products.id />
|
<param.products.id />
|
||||||
<param.products.version />
|
<param.products.version />
|
||||||
<param.platforms />
|
<param.platforms />
|
||||||
<param.guid>e7dd2564-e462-4878-b445-45763482263f</param.guid>
|
<param.guid>bcf7498f-65f2-487f-b762-d3e88d9a4ebe</param.guid>
|
||||||
<param.exclude.filters />
|
<param.exclude.filters />
|
||||||
<param.exclude.pcodedmfiles>true</param.exclude.pcodedmfiles>
|
<param.exclude.pcodedmfiles>true</param.exclude.pcodedmfiles>
|
||||||
<param.examples />
|
<param.examples />
|
||||||
@@ -48,7 +48,6 @@
|
|||||||
<unset>
|
<unset>
|
||||||
<param.description />
|
<param.description />
|
||||||
<param.screenshot />
|
<param.screenshot />
|
||||||
<param.version />
|
|
||||||
<param.output />
|
<param.output />
|
||||||
<param.products.name />
|
<param.products.name />
|
||||||
<param.products.id />
|
<param.products.id />
|
||||||
@@ -82,22 +81,22 @@
|
|||||||
<param.additional.sw.linux.url />
|
<param.additional.sw.linux.url />
|
||||||
</unset>
|
</unset>
|
||||||
<fileset.rootdir>
|
<fileset.rootdir>
|
||||||
<file>${PROJECT_ROOT}</file>
|
<file>${PROJECT_ROOT}\McuLib</file>
|
||||||
</fileset.rootdir>
|
</fileset.rootdir>
|
||||||
<fileset.rootfiles>
|
<fileset.rootfiles>
|
||||||
<file>${PROJECT_ROOT}\install_my_library.m</file>
|
<file>${PROJECT_ROOT}\McuLib\install_my_library.m</file>
|
||||||
<file>${PROJECT_ROOT}\lib</file>
|
<file>${PROJECT_ROOT}\McuLib\lib</file>
|
||||||
<file>${PROJECT_ROOT}\m</file>
|
<file>${PROJECT_ROOT}\McuLib\m</file>
|
||||||
<file>${PROJECT_ROOT}\sl_customization.m</file>
|
<file>${PROJECT_ROOT}\McuLib\sl_customization.m</file>
|
||||||
<file>${PROJECT_ROOT}\slblocks.m</file>
|
<file>${PROJECT_ROOT}\McuLib\slblocks.m</file>
|
||||||
<file>${PROJECT_ROOT}\startup.m</file>
|
<file>${PROJECT_ROOT}\McuLib\startup.m</file>
|
||||||
<file>${PROJECT_ROOT}\templates</file>
|
<file>${PROJECT_ROOT}\McuLib\templates</file>
|
||||||
</fileset.rootfiles>
|
</fileset.rootfiles>
|
||||||
<fileset.depfun.included />
|
<fileset.depfun.included />
|
||||||
<fileset.depfun.excluded />
|
<fileset.depfun.excluded />
|
||||||
<fileset.package />
|
<fileset.package />
|
||||||
<build-deliverables>
|
<build-deliverables>
|
||||||
<file location="${PROJECT_ROOT}" name="mcuwrapper.mltbx" optional="false">E:\.WORK\MATLAB\matlab_23550\McuLib\mcuwrapper.mltbx</file>
|
<file location="${PROJECT_ROOT}" name="MCU Wrapper.mltbx" optional="false">E:\.WORK\MATLAB\mcu_matlab\MCU Wrapper.mltbx</file>
|
||||||
</build-deliverables>
|
</build-deliverables>
|
||||||
<workflow />
|
<workflow />
|
||||||
<matlab>
|
<matlab>
|
||||||
Reference in New Issue
Block a user