структуризировано:
выделены отдельный файл для работы с wrapper и appwrapper
This commit is contained in:
parent
245592a821
commit
edb22966ff
156
McuLib/m/appWrap.m
Normal file
156
McuLib/m/appWrap.m
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
classdef appWrap
|
||||||
|
|
||||||
|
methods(Static)
|
||||||
|
function appWrapperFunc()
|
||||||
|
block = gcb;
|
||||||
|
% Получаем имя функции и путь к файлам
|
||||||
|
[filename, section, tool, example]= appWrap.getAppWrapperUserFile(block);
|
||||||
|
mcuMask.tool(tool, example);
|
||||||
|
|
||||||
|
% Загружаем содержимое файла
|
||||||
|
set_param(block, 'appWrapperCode', '');
|
||||||
|
try
|
||||||
|
code = fileread(filename);
|
||||||
|
code = regexprep(code, '\r\n?', '\n'); % нормализуем окончания строк
|
||||||
|
|
||||||
|
includesText = editCode.extractSection(code, section);
|
||||||
|
set_param(block, 'appWrapperCode', includesText);
|
||||||
|
catch
|
||||||
|
end
|
||||||
|
% % Поиск тела обычной функции
|
||||||
|
% expr = sprintf('void %s()', sel);
|
||||||
|
% funcBody = editCode.extractSection(code, expr);
|
||||||
|
% set_param(block, 'wrapperCode', funcBody);
|
||||||
|
end
|
||||||
|
|
||||||
|
function saveAppWrapperCode()
|
||||||
|
block = gcb;
|
||||||
|
|
||||||
|
% Получаем имя функции и путь к файлам
|
||||||
|
[filename, section] = appWrap.getAppWrapperUserFile(block);
|
||||||
|
if ~isfile(filename)
|
||||||
|
errordlg(['Файл не найден: ', filename]);
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
sel = get_param(block, 'appWrapperFunc');
|
||||||
|
basePath = get_param(block, 'appWrapperPath');
|
||||||
|
if isempty(basePath)
|
||||||
|
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
newBody = get_param(block, 'appWrapperCode');
|
||||||
|
code = fileread(filename);
|
||||||
|
code = regexprep(code, '\r\n?', '\n');
|
||||||
|
newBody = strrep(newBody, '\', '\\');
|
||||||
|
code = editCode.insertSection(code, section, newBody);
|
||||||
|
% else
|
||||||
|
% % Обновляем тело функции
|
||||||
|
% expr = sprintf('void %s()', sel);
|
||||||
|
% code = editCode.insertSection(code, expr, newBody);
|
||||||
|
% end
|
||||||
|
fid = fopen(filename, 'w', 'n', 'UTF-8');
|
||||||
|
if fid == -1
|
||||||
|
errordlg('Не удалось открыть файл для записи');
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
fwrite(fid, code);
|
||||||
|
fclose(fid);
|
||||||
|
mcuMask.disp(1, ['Обновлено: ' sel]);
|
||||||
|
end
|
||||||
|
|
||||||
|
function openAppWrapperCode()
|
||||||
|
block = gcb;
|
||||||
|
|
||||||
|
% Получаем имя функции и путь к файлам
|
||||||
|
filename = appWrap.getAbsolutePath(mcuMask.getAppWrapperUserFile(block));
|
||||||
|
if exist(filename, 'file') == 2
|
||||||
|
% Формируем команду без кавычек
|
||||||
|
cmd = sprintf('rundll32.exe shell32.dll,OpenAs_RunDLL %s', filename);
|
||||||
|
status = system(cmd);
|
||||||
|
if status ~= 0
|
||||||
|
errordlg('Не удалось открыть окно выбора приложения.');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
errordlg('Файл не найден');
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
%% SPECIFIC TOOLS
|
||||||
|
methods(Static, Access = private)
|
||||||
|
|
||||||
|
function [filename, section, tool, example] = getAppWrapperUserFile(block)
|
||||||
|
sel = get_param(block, 'appWrapperFunc');
|
||||||
|
basePath = mcuPath.get('appWrapperPath');
|
||||||
|
if isempty(basePath)
|
||||||
|
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
% Формируем путь к файлу в зависимости от типа запроса
|
||||||
|
if strcmp(sel, 'Includes')
|
||||||
|
filename = fullfile(basePath, 'app_includes.h');
|
||||||
|
section = '// INCLUDES';
|
||||||
|
tool = 'Инклюды для доступа к коду МК в коде оболочке';
|
||||||
|
example = '#include "main.h"';
|
||||||
|
elseif strcmp(sel, 'Dummy')
|
||||||
|
filename = fullfile(basePath, 'app_wrapper.c');
|
||||||
|
section = '// DUMMY';
|
||||||
|
tool = 'Заглушки для различных функций и переменных';
|
||||||
|
example = ['CAN_HandleTypeDef hcan = {0};' newline...
|
||||||
|
'void hardware_func(handle *huart) {}' newline...
|
||||||
|
'int wait_for_hardware_flag(int *flag) {' newline...
|
||||||
|
' return 1;' newline...
|
||||||
|
'}' newline...
|
||||||
|
''];
|
||||||
|
elseif strcmp(sel, 'App Init')
|
||||||
|
filename = fullfile(basePath, 'app_init.c');
|
||||||
|
section = '// USER APP INIT';
|
||||||
|
tool = ['Код для инициализации приложения МК.' newline newline...
|
||||||
|
'Вызов функций инициализации, если не используется отдельный поток для main().'];
|
||||||
|
example = 'init_func();';
|
||||||
|
elseif strcmp(sel, 'App Step')
|
||||||
|
filename = fullfile(basePath, 'app_wrapper.c');
|
||||||
|
section = '// USER APP STEP';
|
||||||
|
tool = ['Код приложения МК для вызова в шаге симуляции.' newline newline ...
|
||||||
|
'Вызов функций программы МК, если не используется отдельный поток для main().'];
|
||||||
|
example = 'step_func();';
|
||||||
|
elseif strcmp(sel, 'App Inputs')
|
||||||
|
filename = fullfile(basePath, 'app_io.c');
|
||||||
|
section = '// USER APP INPUT';
|
||||||
|
tool = ['Работа с буффером для портов S-Function' newline newline ...
|
||||||
|
'Буфер в начале хранит входные порты S-Function, далее идут выходные порты:' newline ...
|
||||||
|
'Buffer[0:15] - входной порт, Buffer[16:31] - входной 1 порт, ' newline ...
|
||||||
|
'Buffer[32:47] - выходной 1 порт, Buffer[48:63] - выходной 2 порт'];
|
||||||
|
example = ['// чтение 1-го элемента 0-го входного массива' newline...
|
||||||
|
'app_variable_2 = ReadInputArray(0, 1);' newline newline...
|
||||||
|
'// запись в буфер выходов' newline ...
|
||||||
|
'app_variable_2 = Buffer[10];'];
|
||||||
|
elseif strcmp(sel, 'App Outputs')
|
||||||
|
filename = fullfile(basePath, 'app_io.c');
|
||||||
|
section = '// USER APP OUTPUT';
|
||||||
|
tool = ['Работа с буффером для портов S-Function' newline newline ...
|
||||||
|
'Буфер в начале хранит входные порты S-Function, далее идут выходные порты:' newline ...
|
||||||
|
'Buffer[0:15] - входной порт, Buffer[16:31] - входной 1 порт, ' newline ...
|
||||||
|
'Buffer[32:47] - выходной 1 порт, Buffer[48:63] - выходной 2 порт'];
|
||||||
|
example = ['// запись в 1-й элемент 0-го выходного массива' newline...
|
||||||
|
'WriteOutputArray(app_variable, 0, 1);' newline newline ...
|
||||||
|
'// запись в буфер выходов' newline ...
|
||||||
|
'Buffer[XD_OUTPUT_START + 10] = app_variable_2;'];
|
||||||
|
elseif strcmp(sel, 'App Deinit')
|
||||||
|
filename = fullfile(basePath, 'app_init.c');
|
||||||
|
section = '// USER APP DEINIT';
|
||||||
|
tool = ['Код для деинициализации приложения МК.' newline newline ...
|
||||||
|
'Можно деинициализировать приложение МК, для повторного запуска.'];
|
||||||
|
example = 'memset(&htim1, sizeof(htim1), 0;';
|
||||||
|
else
|
||||||
|
tool = '';
|
||||||
|
mcuMask.disp(0, '\nОшибка выбора типа секции кода: неизвестное значение');
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -39,7 +39,7 @@ classdef asynchManage < handle
|
|||||||
methods (Access = private)
|
methods (Access = private)
|
||||||
function saveCallback(obj)
|
function saveCallback(obj)
|
||||||
try
|
try
|
||||||
mcuMask.saveAndClose(obj.maskBlockPath);
|
mcuMask.close(obj.maskBlockPath);
|
||||||
save_system(obj.modelName);
|
save_system(obj.modelName);
|
||||||
catch ME
|
catch ME
|
||||||
warning('progr:Nneg', 'Ошибка при сохранении модели: %s', ME.message);
|
warning('progr:Nneg', 'Ошибка при сохранении модели: %s', ME.message);
|
||||||
@ -79,7 +79,7 @@ classdef asynchManage < handle
|
|||||||
function GUIconfigCallback(obj)
|
function GUIconfigCallback(obj)
|
||||||
|
|
||||||
try
|
try
|
||||||
mcuMask.saveAndClose(obj.maskBlockPath);
|
mcuMask.close(obj.maskBlockPath);
|
||||||
mexing(0);
|
mexing(0);
|
||||||
catch ME
|
catch ME
|
||||||
warning('progr:Nneg', 'Ошибка при обновлении модели: %s', ME.message);
|
warning('progr:Nneg', 'Ошибка при обновлении модели: %s', ME.message);
|
||||||
|
72
McuLib/m/mainWrap.m
Normal file
72
McuLib/m/mainWrap.m
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
classdef mainWrap
|
||||||
|
|
||||||
|
methods(Static)
|
||||||
|
function enableThreading()
|
||||||
|
block = gcb;
|
||||||
|
maskNames = get_param(block, 'MaskNames');
|
||||||
|
maskValues = get_param(block, 'MaskValues');
|
||||||
|
maskEnables = get_param(block, 'MaskEnables');
|
||||||
|
idxEnable = find(strcmp(maskNames, 'enableThreading'));
|
||||||
|
idxEdit = find(strcmp(maskNames, 'threadCycles'));
|
||||||
|
if isempty(idxEnable) || isempty(idxEdit)
|
||||||
|
error('Параметры enableThreading или threadCycles не найдены в маске');
|
||||||
|
end
|
||||||
|
val = maskValues{idxEnable};
|
||||||
|
if strcmp(val, 'on')
|
||||||
|
maskEnables{idxEdit} = 'on';
|
||||||
|
else
|
||||||
|
maskEnables{idxEdit} = 'off';
|
||||||
|
end
|
||||||
|
set_param(block, 'MaskEnables', maskEnables);
|
||||||
|
end
|
||||||
|
|
||||||
|
function enableDeinit()
|
||||||
|
block = gcb;
|
||||||
|
maskNames = get_param(block, 'MaskNames');
|
||||||
|
maskValues = get_param(block, 'MaskValues');
|
||||||
|
maskEnables = get_param(block, 'MaskEnables');
|
||||||
|
idxEnable = find(strcmp(maskNames, 'enableThreading'));
|
||||||
|
idxEdit = find(strcmp(maskNames, 'threadCycles'));
|
||||||
|
if isempty(idxEnable) || isempty(idxEdit)
|
||||||
|
error('Параметры enableThreading или threadCycles не найдены в маске');
|
||||||
|
end
|
||||||
|
val = maskValues{idxEnable};
|
||||||
|
if strcmp(val, 'on')
|
||||||
|
maskEnables{idxEdit} = 'on';
|
||||||
|
else
|
||||||
|
maskEnables{idxEdit} = 'off';
|
||||||
|
end
|
||||||
|
set_param(block, 'MaskEnables', maskEnables);
|
||||||
|
end
|
||||||
|
|
||||||
|
function extConsol()
|
||||||
|
block = gcb;
|
||||||
|
mask = Simulink.Mask.get(block);
|
||||||
|
fullOut = mask.getParameter('fullOutput');
|
||||||
|
extCons = mask.getParameter('extConsol');
|
||||||
|
if isempty(extCons) || isempty(fullOut)
|
||||||
|
error('Параметры fullOutput или extConsol не найдены в маске');
|
||||||
|
end
|
||||||
|
|
||||||
|
if(strcmp(extCons.Enabled, 'on'))
|
||||||
|
if strcmp(extCons.Value, 'on')
|
||||||
|
fullOut.Enabled = 'off';
|
||||||
|
fullOut.Value = 'on';
|
||||||
|
else
|
||||||
|
fullOut.Enabled = 'on';
|
||||||
|
end
|
||||||
|
else
|
||||||
|
fullOut.Enabled = 'on';
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
%% SPECIFIC TOOLS
|
||||||
|
methods(Static, Access = private)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -1,5 +1,5 @@
|
|||||||
classdef mcuMask
|
classdef mcuMask
|
||||||
|
%% CALLBACKS
|
||||||
methods(Static)
|
methods(Static)
|
||||||
% Following properties of 'maskInitContext' are avalaible to use:
|
% Following properties of 'maskInitContext' are avalaible to use:
|
||||||
% - BlockHandle
|
% - BlockHandle
|
||||||
@ -58,148 +58,37 @@ classdef mcuMask
|
|||||||
end
|
end
|
||||||
|
|
||||||
%% WRAPPER PARAMS
|
%% WRAPPER PARAMS
|
||||||
function enableThreading(callbackContext)
|
|
||||||
block = gcb;
|
|
||||||
maskNames = get_param(block, 'MaskNames');
|
|
||||||
maskValues = get_param(block, 'MaskValues');
|
|
||||||
maskEnables = get_param(block, 'MaskEnables');
|
|
||||||
idxEnable = find(strcmp(maskNames, 'enableThreading'));
|
|
||||||
idxEdit = find(strcmp(maskNames, 'threadCycles'));
|
|
||||||
if isempty(idxEnable) || isempty(idxEdit)
|
|
||||||
error('Параметры enableThreading или threadCycles не найдены в маске');
|
|
||||||
end
|
|
||||||
val = maskValues{idxEnable};
|
|
||||||
if strcmp(val, 'on')
|
|
||||||
maskEnables{idxEdit} = 'on';
|
|
||||||
else
|
|
||||||
maskEnables{idxEdit} = 'off';
|
|
||||||
end
|
|
||||||
set_param(block, 'MaskEnables', maskEnables);
|
|
||||||
end
|
|
||||||
|
|
||||||
function enableDeinit(callbackContext)
|
|
||||||
block = gcb;
|
|
||||||
maskNames = get_param(block, 'MaskNames');
|
|
||||||
maskValues = get_param(block, 'MaskValues');
|
|
||||||
maskEnables = get_param(block, 'MaskEnables');
|
|
||||||
idxEnable = find(strcmp(maskNames, 'enableThreading'));
|
|
||||||
idxEdit = find(strcmp(maskNames, 'threadCycles'));
|
|
||||||
if isempty(idxEnable) || isempty(idxEdit)
|
|
||||||
error('Параметры enableThreading или threadCycles не найдены в маске');
|
|
||||||
end
|
|
||||||
val = maskValues{idxEnable};
|
|
||||||
if strcmp(val, 'on')
|
|
||||||
maskEnables{idxEdit} = 'on';
|
|
||||||
else
|
|
||||||
maskEnables{idxEdit} = 'off';
|
|
||||||
end
|
|
||||||
set_param(block, 'MaskEnables', maskEnables);
|
|
||||||
end
|
|
||||||
|
|
||||||
function extConsol(callbackContext)
|
|
||||||
block = gcb;
|
|
||||||
mask = Simulink.Mask.get(block);
|
|
||||||
fullOut = mask.getParameter('fullOutput');
|
|
||||||
extCons = mask.getParameter('extConsol');
|
|
||||||
if isempty(extCons) || isempty(fullOut)
|
|
||||||
error('Параметры fullOutput или extConsol не найдены в маске');
|
|
||||||
end
|
|
||||||
|
|
||||||
if(strcmp(extCons.Enabled, 'on'))
|
|
||||||
if strcmp(extCons.Value, 'on')
|
|
||||||
fullOut.Enabled = 'off';
|
|
||||||
fullOut.Value = 'on';
|
|
||||||
else
|
|
||||||
fullOut.Enabled = 'on';
|
|
||||||
end
|
|
||||||
else
|
|
||||||
fullOut.Enabled = 'on';
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function wrapperPath_add(callbackContext)
|
function wrapperPath_add(callbackContext)
|
||||||
mcuPath.addPath('wrapperPath');
|
mcuPath.addPath('wrapperPath');
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function enableThreading(callbackContext)
|
||||||
|
mainWrap.enableThreading();
|
||||||
|
end
|
||||||
|
|
||||||
|
function enableDeinit(callbackContext)
|
||||||
|
mainWrap.enableDeinit();
|
||||||
|
end
|
||||||
|
|
||||||
|
function extConsol(callbackContext)
|
||||||
|
mainWrap.extConsol();
|
||||||
|
end
|
||||||
|
|
||||||
|
%% USER WRAPPER CODE
|
||||||
function appWrapperPath_add(callbackContext)
|
function appWrapperPath_add(callbackContext)
|
||||||
mcuPath.addPath('appWrapperPath');
|
mcuPath.addPath('appWrapperPath');
|
||||||
end
|
end
|
||||||
%% USER WRAPPER CODE
|
|
||||||
|
|
||||||
function appWrapperFunc(callbackContext)
|
function appWrapperFunc(callbackContext)
|
||||||
block = gcb;
|
appWrap.appWrapperFunc();
|
||||||
% Получаем имя функции и путь к файлам
|
|
||||||
[filename, section, tool, example]= mcuMask.getWrapperUserFile(block);
|
|
||||||
mcuMask.tool(tool, example);
|
|
||||||
|
|
||||||
% Загружаем содержимое файла
|
|
||||||
set_param(block, 'appWrapperCode', '');
|
|
||||||
try
|
|
||||||
code = fileread(filename);
|
|
||||||
code = regexprep(code, '\r\n?', '\n'); % нормализуем окончания строк
|
|
||||||
|
|
||||||
includesText = editCode.extractSection(code, section);
|
|
||||||
set_param(block, 'appWrapperCode', includesText);
|
|
||||||
catch
|
|
||||||
end
|
|
||||||
% % Поиск тела обычной функции
|
|
||||||
% expr = sprintf('void %s()', sel);
|
|
||||||
% funcBody = editCode.extractSection(code, expr);
|
|
||||||
% set_param(block, 'wrapperCode', funcBody);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function saveAppWrapperCode(callbackContext)
|
function saveAppWrapperCode(callbackContext)
|
||||||
block = gcb;
|
appWrap.saveAppWrapperCode();
|
||||||
|
|
||||||
% Получаем имя функции и путь к файлам
|
|
||||||
[filename, section] = mcuMask.getWrapperUserFile(block);
|
|
||||||
if ~isfile(filename)
|
|
||||||
errordlg(['Файл не найден: ', filename]);
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
|
|
||||||
sel = get_param(block, 'appWrapperFunc');
|
|
||||||
basePath = get_param(block, 'appWrapperPath');
|
|
||||||
if isempty(basePath)
|
|
||||||
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
newBody = get_param(block, 'appWrapperCode');
|
|
||||||
code = fileread(filename);
|
|
||||||
code = regexprep(code, '\r\n?', '\n');
|
|
||||||
newBody = strrep(newBody, '\', '\\');
|
|
||||||
code = editCode.insertSection(code, section, newBody);
|
|
||||||
% else
|
|
||||||
% % Обновляем тело функции
|
|
||||||
% expr = sprintf('void %s()', sel);
|
|
||||||
% code = editCode.insertSection(code, expr, newBody);
|
|
||||||
% end
|
|
||||||
fid = fopen(filename, 'w', 'n', 'UTF-8');
|
|
||||||
if fid == -1
|
|
||||||
errordlg('Не удалось открыть файл для записи');
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
fwrite(fid, code);
|
|
||||||
fclose(fid);
|
|
||||||
mcuMask.disp(1, ['Обновлено: ' sel]);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function openAppWrapperCode(callbackContext)
|
function openAppWrapperCode(callbackContext)
|
||||||
block = gcb;
|
appWrap.openAppWrapperCode();
|
||||||
|
|
||||||
% Получаем имя функции и путь к файлам
|
|
||||||
filename = mcuPath.getAbsolutePath(mcuMask.getWrapperUserFile(block));
|
|
||||||
if exist(filename, 'file') == 2
|
|
||||||
% Формируем команду без кавычек
|
|
||||||
cmd = sprintf('rundll32.exe shell32.dll,OpenAs_RunDLL %s', filename);
|
|
||||||
status = system(cmd);
|
|
||||||
if status ~= 0
|
|
||||||
errordlg('Не удалось открыть окно выбора приложения.');
|
|
||||||
end
|
|
||||||
else
|
|
||||||
errordlg('Файл не найден');
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
%% USER CODE
|
%% USER CODE
|
||||||
@ -220,36 +109,23 @@ classdef mcuMask
|
|||||||
end
|
end
|
||||||
|
|
||||||
%% PERIPH CONFIG
|
%% PERIPH CONFIG
|
||||||
|
|
||||||
function periphPath_add(callbackContext)
|
function periphPath_add(callbackContext)
|
||||||
mcuPath.addAnyFile('periphPath');
|
mcuPath.addAnyFile('periphPath');
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function periphUpdate(callbackContext)
|
||||||
|
modelName = bdroot(gcb); % получить имя верхнего уровня модели
|
||||||
|
blockName = gcb;
|
||||||
|
mgr = asynchManage(modelName, blockName); % создать объект класса
|
||||||
|
mgr.updateGUIfromConfig(); % запустить сохранение и обновление
|
||||||
|
end
|
||||||
|
|
||||||
%% COMPILE
|
%% COMPILE
|
||||||
function compile(callbackContext)
|
function compile(callbackContext)
|
||||||
compiler.compile();
|
compiler.compile();
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function setSFuncName(callbackContext)
|
||||||
function updateModel(callbackContext)
|
|
||||||
addpath(mcuPath.get('wrapperPath'));
|
|
||||||
res = mexing(1);
|
|
||||||
if res ~= 0
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
|
|
||||||
modelName = bdroot(gcb); % получить имя верхнего уровня модели
|
|
||||||
blockName = gcb;
|
|
||||||
mgr = asynchManage(modelName, blockName); % создать объект класса
|
|
||||||
mgr.saveAndUpdateModel(); % запустить сохранение и обновление
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function findjobj_link(callbackContext)
|
|
||||||
web('https://www.mathworks.com/matlabcentral/fileexchange/14317-findjobj-find-java-handles-of-matlab-graphic-objects');
|
|
||||||
end
|
|
||||||
|
|
||||||
function set_name(callbackContext)
|
|
||||||
block = gcb;
|
block = gcb;
|
||||||
% Получаем параметр имени S-Function из маски блока
|
% Получаем параметр имени S-Function из маски блока
|
||||||
newName = mcuMask.get_name();
|
newName = mcuMask.get_name();
|
||||||
@ -282,88 +158,30 @@ classdef mcuMask
|
|||||||
fwrite(fid, updatedText);
|
fwrite(fid, updatedText);
|
||||||
fclose(fid);
|
fclose(fid);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%% LINK TO EXTERNAL CONSOLE
|
||||||
|
function findjobj_link(callbackContext)
|
||||||
|
web https://www.mathworks.com/matlabcentral/fileexchange/14317-findjobj-find-java-handles-of-matlab-graphic-objects;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
%% SPECIFIC TOOLS
|
|
||||||
methods(Static, Access = private)
|
|
||||||
|
|
||||||
function [filename, section, tool, example] = getWrapperUserFile(block)
|
|
||||||
sel = get_param(block, 'appWrapperFunc');
|
|
||||||
basePath = mcuPath.get('appWrapperPath');
|
|
||||||
if isempty(basePath)
|
|
||||||
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
% Формируем путь к файлу в зависимости от типа запроса
|
|
||||||
if strcmp(sel, 'Includes')
|
|
||||||
filename = fullfile(basePath, 'app_includes.h');
|
|
||||||
section = '// INCLUDES';
|
|
||||||
tool = 'Инклюды для доступа к коду МК в коде оболочке';
|
|
||||||
example = '#include "main.h"';
|
|
||||||
elseif strcmp(sel, 'Dummy')
|
|
||||||
filename = fullfile(basePath, 'app_wrapper.c');
|
|
||||||
section = '// DUMMY';
|
|
||||||
tool = 'Заглушки для различных функций и переменных';
|
|
||||||
example = ['CAN_HandleTypeDef hcan = {0};' newline...
|
|
||||||
'void hardware_func(handle *huart) {}' newline...
|
|
||||||
'int wait_for_hardware_flag(int *flag) {' newline...
|
|
||||||
' return 1;' newline...
|
|
||||||
'}' newline...
|
|
||||||
''];
|
|
||||||
elseif strcmp(sel, 'App Init')
|
|
||||||
filename = fullfile(basePath, 'app_init.c');
|
|
||||||
section = '// USER APP INIT';
|
|
||||||
tool = ['Код для инициализации приложения МК.' newline newline...
|
|
||||||
'Вызов функций инициализации, если не используется отдельный поток для main().'];
|
|
||||||
example = 'init_func();';
|
|
||||||
elseif strcmp(sel, 'App Step')
|
|
||||||
filename = fullfile(basePath, 'app_wrapper.c');
|
|
||||||
section = '// USER APP STEP';
|
|
||||||
tool = ['Код приложения МК для вызова в шаге симуляции.' newline newline ...
|
|
||||||
'Вызов функций программы МК, если не используется отдельный поток для main().'];
|
|
||||||
example = 'step_func();';
|
|
||||||
elseif strcmp(sel, 'App Inputs')
|
|
||||||
filename = fullfile(basePath, 'app_io.c');
|
|
||||||
section = '// USER APP INPUT';
|
|
||||||
tool = ['Работа с буффером для портов S-Function' newline newline ...
|
|
||||||
'Буфер в начале хранит входные порты S-Function, далее идут выходные порты:' newline ...
|
|
||||||
'Buffer[0:15] - входной порт, Buffer[16:31] - входной 1 порт, ' newline ...
|
|
||||||
'Buffer[32:47] - выходной 1 порт, Buffer[48:63] - выходной 2 порт'];
|
|
||||||
example = ['// чтение 1-го элемента 0-го входного массива' newline...
|
|
||||||
'app_variable_2 = ReadInputArray(0, 1);' newline newline...
|
|
||||||
'// запись в буфер выходов' newline ...
|
|
||||||
'app_variable_2 = Buffer[10];'];
|
|
||||||
elseif strcmp(sel, 'App Outputs')
|
|
||||||
filename = fullfile(basePath, 'app_io.c');
|
|
||||||
section = '// USER APP OUTPUT';
|
|
||||||
tool = ['Работа с буффером для портов S-Function' newline newline ...
|
|
||||||
'Буфер в начале хранит входные порты S-Function, далее идут выходные порты:' newline ...
|
|
||||||
'Buffer[0:15] - входной порт, Buffer[16:31] - входной 1 порт, ' newline ...
|
|
||||||
'Buffer[32:47] - выходной 1 порт, Buffer[48:63] - выходной 2 порт'];
|
|
||||||
example = ['// запись в 1-й элемент 0-го выходного массива' newline...
|
|
||||||
'WriteOutputArray(app_variable, 0, 1);' newline newline ...
|
|
||||||
'// запись в буфер выходов' newline ...
|
|
||||||
'Buffer[XD_OUTPUT_START + 10] = app_variable_2;'];
|
|
||||||
elseif strcmp(sel, 'App Deinit')
|
|
||||||
filename = fullfile(basePath, 'app_init.c');
|
|
||||||
section = '// USER APP DEINIT';
|
|
||||||
tool = ['Код для деинициализации приложения МК.' newline newline ...
|
|
||||||
'Можно деинициализировать приложение МК, для повторного запуска.'];
|
|
||||||
example = 'memset(&htim1, sizeof(htim1), 0;';
|
|
||||||
else
|
|
||||||
tool = '';
|
|
||||||
mcuMask.disp(0, '\nОшибка выбора типа секции кода: неизвестное значение');
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
%% GENERAL TOOLS
|
%% GENERAL TOOLS
|
||||||
methods(Static, Access = public)
|
methods(Static, Access = public)
|
||||||
|
|
||||||
function saveAndClose(blockPath)
|
function updateModel()
|
||||||
|
addpath(mcuPath.get('wrapperPath'));
|
||||||
|
res = mexing(1);
|
||||||
|
if res ~= 0
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
modelName = bdroot(gcb); % получить имя верхнего уровня модели
|
||||||
|
blockName = gcb;
|
||||||
|
mgr = asynchManage(modelName, blockName); % создать объект класса
|
||||||
|
mgr.saveAndUpdateModel(); % запустить сохранение и обновление
|
||||||
|
end
|
||||||
|
|
||||||
|
function close(blockPath)
|
||||||
try
|
try
|
||||||
% Считываем текущее имя модели
|
% Считываем текущее имя модели
|
||||||
modelName = bdroot(blockPath);
|
modelName = bdroot(blockPath);
|
||||||
|
Loading…
Reference in New Issue
Block a user