162 lines
7.7 KiB
Matlab
162 lines
7.7 KiB
Matlab
classdef compiler
|
||
% Класс для компиляции бинарника S-Function в MATLAB
|
||
% Управляет процессом сборки mex-файлов для Simulink
|
||
methods(Static)
|
||
|
||
function compile()
|
||
% Основная функция компиляции S-Function
|
||
% Добавляет путь к файлам обёртки и запускает компиляцию
|
||
addpath(mcuPath.get('wrapperPath'));
|
||
mexing(1); % 1 - флаг компиляции
|
||
end
|
||
|
||
% хз че это
|
||
function get_availbe()
|
||
addpath(mcuPath.get('wrapperPath'));
|
||
mexing(1);
|
||
end
|
||
function choose()
|
||
addpath(mcuPath.get('wrapperPath'));
|
||
mexing(1);
|
||
end
|
||
|
||
function updateRunBat()
|
||
% Обновление BAT-файла для компиляции S-Function
|
||
% Формирует списки исходных файлов и путей для включения
|
||
|
||
% === КОМПИЛЯЦИЯ ОСНОВНОЙ ОБЁРТКИ ===
|
||
sources = {
|
||
'MCU.c'
|
||
'mcu_wrapper.c'
|
||
};
|
||
% Список заголовочных файлов (.h)
|
||
includes = { '.\' };
|
||
wrapperPath = mcuPath.get('wrapperPath');
|
||
|
||
% Формируем строки для BAT-файла
|
||
wrapperSrcText = compiler.createSourcesBat('code_WRAPPER', sources, wrapperPath);
|
||
wrapperIncText = compiler.createIncludesBat('includes_WRAPPER', includes, wrapperPath);
|
||
|
||
% Обновляем BAT-файл для основной обёртки
|
||
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');
|
||
|
||
% Формируем строки для BAT-файла
|
||
wrapperSrcText = compiler.createSourcesBat('code_APP_WRAPPER', sources, periphPath);
|
||
wrapperIncText = compiler.createIncludesBat('includes_APP_WRAPPER', includes, periphPath);
|
||
|
||
% Обновляем BAT-файл для обёртки приложения
|
||
res = compiler.updateRunMexBat(wrapperSrcText, wrapperIncText, ':: APP WRAPPER BAT');
|
||
|
||
% Обновляем BAT-файл для периферии
|
||
periphConfig.updatePeriphRunMexBat();
|
||
end
|
||
|
||
function res = updateRunMexBat(srcText, incText, Section)
|
||
% Обновляет секцию в BAT-файле для компиляции mex
|
||
% Входные параметры:
|
||
% srcText - текст для записи set code_... (исходные файлы)
|
||
% incText - текст для записи set includes_... (пути включения)
|
||
% Section - секция в BAT-файле для обновления
|
||
%
|
||
% Возвращает:
|
||
% res - 1 при успехе, 0 при ошибке
|
||
% Объединяем исходные файлы и пути включения
|
||
periphBat = [srcText '\n\n' incText];
|
||
batPath = fullfile(mcuPath.get('wrapperPath'), 'run_mex.bat');
|
||
res = 1; % По умолчанию - ошибка
|
||
|
||
try
|
||
% Читаем текущее содержимое BAT-файла
|
||
code = fileread(batPath);
|
||
code = regexprep(code, '\r\n?', '\n'); % Нормализуем переводы строк
|
||
|
||
% Вставляем новую секцию в BAT-файл
|
||
code = editCode.insertSection(code, Section, periphBat);
|
||
|
||
% Записываем обновленный BAT-файл
|
||
fid = fopen(batPath, 'w', 'n', 'UTF-8');
|
||
if fid == -1
|
||
error('Не удалось открыть файл для записи');
|
||
end
|
||
fwrite(fid, code);
|
||
fclose(fid);
|
||
res = 1; % Успех
|
||
catch ME
|
||
% Ошибка записи в BAT-файл
|
||
mcuMask.disp(0, '\nОшибка: неудачная запись в файл при записи файла: %s', ME.message);
|
||
end
|
||
end
|
||
|
||
function srcText = createSourcesBat(prefix_name, sources, path)
|
||
% Создает строку с исходными файлами для BAT-файла
|
||
% Формат: set code_WRAPPER=file1.c file2.c ...
|
||
|
||
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 ' ']; % ^ для продолжения строки в BAT
|
||
else
|
||
srcText = [srcText srcList{i}]; % Последний файл без продолжения
|
||
end
|
||
end
|
||
|
||
% Добавляем префикс переменной BAT
|
||
srcText = ['set ' prefix_name '=' srcText];
|
||
end
|
||
|
||
function incText = createIncludesBat(prefix_name, includes, path)
|
||
% Создает строку с путями включения для BAT-файла
|
||
% Формат: set includes_WRAPPER=-I"path1" -I"path2" ...
|
||
|
||
incList = {};
|
||
if nargin >= 2 && iscell(includes)
|
||
for i = 1:numel(includes)
|
||
% Формируем полный путь для включения
|
||
fullPath = fullfile(path, includes{i});
|
||
incList{end+1} = ['-I"' strrep(fullPath, '\', '\\') '"']; % Флаг include для компилятора
|
||
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
|
||
|
||
% Добавляем префикс переменной BAT
|
||
incText = ['set ' prefix_name '=' incText];
|
||
end
|
||
|
||
end
|
||
end |