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