Все изменения накопившиеся с релиза

This commit is contained in:
2025-11-14 21:56:39 +03:00
parent ac2fe4d653
commit 9b8b5ec533
17 changed files with 1008 additions and 699 deletions

View File

@@ -1,100 +1,144 @@
classdef appWrap
% Класс для редактирования кода обёртки МК прямо внутри MATLAB/Simulink
% Позволяет работать с кодом микроконтроллера без переключения между IDE
methods(Static)
function appWrapperFunc()
block = gcb;
% Получаем имя функции и путь к файлам
[filename, section, tool, example]= appWrap.getAppWrapperUserFile(block);
% Загружает код обёртки из файлов в интерфейс MATLAB для редактирования
% Автоматически вызывается при выборе типа кода в маске блока
block = gcb; % Получаем текущий блок Simulink для редактирования
% Определяем какой файл и секцию нужно редактировать
[filename, section, tool, example] = appWrap.getAppWrapperUserFile(block);
% Показываем подсказку по выбранному типу кода прямо в MATLAB
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);
% Загружаем код из файла в интерфейс MATLAB
try
% Читаем исходный код из файла
code = fileread(filename);
code = regexprep(code, '\r\n?', '\n'); % унифицируем переводы строк для MATLAB
% Вырезаем только нужную секцию для редактирования
includesText = editCode.extractSection(code, section);
% Загружаем код в текстовое поле маски для редактирования
set_param(block, 'appWrapperCode', includesText);
catch
% Если файл не найден или ошибка чтения - оставляем поле пустым
% Пользователь сможет написать код с нуля прямо в MATLAB
end
end
function saveAppWrapperCode()
block = gcb;
% Сохраняет отредактированный код из MATLAB обратно в файлы обёртки
% Вызывается при нажатии кнопки "Сохранить" в интерфейсе
block = gcb; % Текущий редактируемый блок
% Получаем имя функции и путь к файлам
% Определяем куда сохранять based на выборе пользователя в MATLAB
[filename, section] = appWrap.getAppWrapperUserFile(block);
% Проверяем что файл существует перед сохранением
if ~isfile(filename)
errordlg(['Файл не найден: ', filename]);
errordlg(['Файл не найден: ', filename], 'Ошибка сохранения в MATLAB');
return;
end
% Получаем выбранный тип кода и путь к файлам
sel = get_param(block, 'appWrapperFunc');
basePath = get_param(block, 'appWrapperPath');
if isempty(basePath)
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
errordlg('Не указан путь к файлам обёртки.', 'Ошибка в MATLAB');
return;
end
% Получаем код который пользователь написал/отредактировал в MATLAB
newBody = get_param(block, 'appWrapperCode');
% Читаем текущее содержимое файла чтобы сохранить структуру
code = fileread(filename);
code = regexprep(code, '\r\n?', '\n');
% Экранируем специальные символы для корректного сохранения из MATLAB
newBody = strrep(newBody, '\', '\\');
% Вставляем отредактированную в MATLAB секцию обратно в файл
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');
% Сохраняем изменения прямо из MATLAB без внешних редакторов
fid = fopen(filename, 'w', 'n');
if fid == -1
errordlg('Не удалось открыть файл для записи');
errordlg('Не удалось сохранить файл из MATLAB', 'Ошибка записи');
return;
end
% Записываем обновленный код
fwrite(fid, code);
fclose(fid);
mcuMask.disp(1, ['Обновлено: ' sel]);
% Подтверждаем успешное сохранение в интерфейсе MATLAB
mcuMask.disp(1, ['Сохранено в MATLAB: ' sel]);
end
function openAppWrapperCode()
% Альтернативный способ: открывает файл в системном редакторе
% Для случаев когда нужно работать во внешней IDE
block = gcb;
% Получаем имя функции и путь к файлам
% Получаем абсолютный путь к файлу для открытия
filename = mcuPath.getAbsolutePath(appWrap.getAppWrapperUserFile(block));
if exist(filename, 'file') == 2
% Формируем команду без кавычек
% Открываем через системный диалог "Открыть с помощью"
% Полезно если нужно использовать привычную IDE вместо редактора MATLAB
cmd = sprintf('rundll32.exe shell32.dll,OpenAs_RunDLL %s', filename);
status = system(cmd);
if status ~= 0
errordlg('Не удалось открыть окно выбора приложения.');
errordlg('Не удалось открыть файл во внешнем редакторе');
end
else
errordlg('Файл не найден');
errordlg('Файл не найден для открытия');
end
end
%% SPECIFIC TOOLS
%% SPECIFIC TOOLS
function [filename, section, tool, example] = getAppWrapperUserFile(block, sel)
% Маппинг типов кода на файлы и секции для редактирования в MATLAB
% Центральное место настройки - здесь определяется где что редактировать
if (nargin < 2)
% Получаем какой тип кода пользователь выбрал в интерфейсе MATLAB
sel = get_param(block, 'appWrapperFunc');
end
% Базовый путь к файлам обёртки (настраивается в маске)
basePath = mcuPath.get('appWrapperPath');
if isempty(basePath)
errordlg('Не указан путь к файлам обёртки (wrapperPath).');
errordlg('Не указан путь к файлам обёртки.');
return;
end
% Формируем путь к файлу в зависимости от типа запроса
% В зависимости от выбора в MATLAB - определяем что редактировать:
if strcmp(sel, 'Includes')
% Редактирование подключения заголовочных файлов
filename = fullfile(basePath, 'app_includes.h');
section = '// INCLUDES';
tool = 'Инклюды для доступа к коду МК в коде оболочке';
example = '#include "main.h"';
example = '#include "main.h"'; % Пример для подсказки в MATLAB
elseif strcmp(sel, 'Dummy')
% Редактирование заглушек для симуляции
filename = fullfile(basePath, 'app_wrapper.c');
section = '// DUMMY';
tool = 'Заглушки для различных функций и переменных';
@@ -104,19 +148,25 @@ classdef appWrap
' 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')
% Редактирование обработки входных данных от Simulink
filename = fullfile(basePath, 'app_io.c');
section = '// USER APP INPUT';
tool = ['Работа с буффером для портов S-Function' newline newline ...
@@ -127,7 +177,9 @@ classdef appWrap
'app_variable_2 = ReadInputArray(0, 1);' newline newline...
'// запись в буфер выходов' newline ...
'app_variable_2 = Buffer[10];'];
elseif strcmp(sel, 'App Outputs')
% Редактирование формирования выходных данных для Simulink
filename = fullfile(basePath, 'app_io.c');
section = '// USER APP OUTPUT';
tool = ['Работа с буффером для портов S-Function' newline newline ...
@@ -138,17 +190,20 @@ classdef appWrap
'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
% Неизвестный тип кода - выводим сообщение в консоль MATLAB
tool = '';
mcuMask.disp(0, '\nОшибка выбора типа секции кода: неизвестное значение');
end
end
end
end