diff --git a/MCU_Wrapper/mcu_wrapper_conf.h b/MCU_Wrapper/mcu_wrapper_conf.h index c05a059..5b9a458 100644 --- a/MCU_Wrapper/mcu_wrapper_conf.h +++ b/MCU_Wrapper/mcu_wrapper_conf.h @@ -45,8 +45,8 @@ // Parametrs of MCU simulator //#define RUN_APP_MAIN_FUNC_THREAD ///< Enable using thread for MCU main() func -#define DEKSTOP_CYCLES_FOR_MCU_APP 0xFF ///< number of for() cycles after which MCU thread would be suspended -#define MCU_CORE_CLOCK 72000000 +//#define DEKSTOP_CYCLES_FOR_MCU_APP 0xFF ///< number of for() cycles after which MCU thread would be suspended +//#define MCU_CORE_CLOCK 72000000 //#define DEINITIALIZE_AFTER_SIM ///< Enable deinitializing structures at simulation ends diff --git a/MCU_Wrapper/run_mex.bat b/MCU_Wrapper/run_mex.bat index 64dd87f..d268403 100644 --- a/MCU_Wrapper/run_mex.bat +++ b/MCU_Wrapper/run_mex.bat @@ -1,23 +1,30 @@ @echo off +:: Получаем аргументы из командной строки +:: %1 - includes_USER +:: %2 - code_USER +:: %3 - режим (например, debug) -set defines=-D"STM32F103xB" -D"USE_HAL_DRIVER"^ +:: Аргументы: +:: %1 — includes строка (в кавычках) +:: %2 — sources строка +:: %3 — defines строка +:: %4 — режим компиляции (debug/release) + +:: Сохраняем как переменные +set includes_USER=%~1 +set code_USER=%~2 +set defines_USER=%~3 +set compil_mode=%~4 + +:: Заменяем __EQ__ на = +set defines_USER=%defines_USER:__EQ__==% + + +set defines_WRAPPER=-D"STM32F103xB" -D"USE_HAL_DRIVER"^ -D"MATLAB"^ -D"__sizeof_ptr=8" -:: -------------------------USERS PATHS AND CODE--------------------------- -set includes_USER= -I"..\mcu_project\upp\Core\Inc" -I"..\mcu_project\upp\Core\upp" -set code_USER=.\App_Wrapper\main.c^ - .\App_Wrapper\app_io.c^ - ..\mcu_project\upp\Core\Src\gpio.c^ - ..\mcu_project\upp\Core\Src\adc.c^ - ..\mcu_project\upp\Core\Src\tim.c^ - ..\mcu_project\upp\Core\Src\stm32f1xx_hal_msp.c^ - ..\mcu_project\upp\Core\Src\stm32f1xx_it.c^ - ..\mcu_project\upp\Core\Src\system_stm32f1xx.c^ - ..\mcu_project\upp\Core\upp\upp.c^ - ..\mcu_project\upp\Core\upp\zero_cross.c^ - ..\mcu_project\upp\Core\upp\adc_filter.c^ - ..\mcu_project\upp\Core\upp\tiristor.c +:: -------------------------USERS PATHS AND CODE--------------------------- ::------------------------------------------------------------------------- @@ -70,15 +77,65 @@ set code_WRAPPER= .\MCU_Wrapper\MCU.c^ :: --------ALL INCLUDES-------- set includes= %includes_USER% %includes_MCU% %includes_WRAPPER% set codes= %code_WRAPPER% %code_USER% %code_MCU% %code_MCU_Sim% +set defines= %defines_USER% %defines_WRAPPER% :: -------OUTPUT FOLDER-------- set output= -outdir "." :: если нужен дебаг, до запускаем run mex с припиской debug -IF [%1]==[debug] (set debug= -g) +IF %compil_mode%==[debug] (set debug= -g) ::------------------------------------------------------------------------- ::------START COMPILING------- echo Compiling... + + +echo =========================== +echo INCLUDES: +echo USER: +for %%f in (%includes_USER%) do ( + echo %%f +) +echo INTERNAL: +for %%f in (%includes_MCU%) do ( + echo %%f +) +for %%f in (%includes_WRAPPER%) do ( + echo %%f +) + +echo =========================== +echo SOURCES: +echo USER: +for %%f in (%code_USER%) do ( + echo %%f +) +echo INTERNAL: +for %%f in (%code_WRAPPER%) do ( + echo %%f +) +for %%f in (%code_MCU_Sim%) do ( + echo %%f +) +for %%f in (%code_MCU%) do ( + echo %%f +) + +echo =========================== +echo DEFINES: +echo USER: +for %%d in (%defines_USER%) do ( + echo %%d +) +echo INTERNAL: +for %%f in (%defines_WRAPPER%) do ( + echo %%f +) +echo =========================== +echo MODE: %compil_mode% +echo =========================== + + +echo mex %output% %defines% %includes% %codes% %debug% mex %output% %defines% %includes% %codes% %debug% echo %DATE% %TIME% \ No newline at end of file diff --git a/mcu_test_r2023.slx b/mcu_test_r2023.slx index 8442475..192e203 100644 Binary files a/mcu_test_r2023.slx and b/mcu_test_r2023.slx differ diff --git a/mexing.m b/mexing.m index f524873..21f81e7 100644 --- a/mexing.m +++ b/mexing.m @@ -1,19 +1,152 @@ % Компилирует S-function -clear, clc, - -set = mex.getCompilerConfigurations('C', 'Selected'); +clear, clc Ts = 0.00001; -delete("*.mexw64") -delete("*.mexw64.pdb") -delete(".\MCU_Wrapper\Outputs\*.*"); +% Флаг режима отладки +definesArg = buildDefinesString(); -status=system('.\MCU_Wrapper\run_mex.bat debug'); +maskNames = get_param(gcbh, 'MaskNames'); +isDebug = find(strcmp(maskNames, 'enableDebug')); +if strcmpi(isDebug, 'on') + modeArg = "release"; +else + modeArg = "debug"; +end -if status==0 +[includesArg, codeArg] = make_mex_arguments('incTable', 'srcTable'); + + +% Вызов батника с двумя параметрами: includes и code +cmd = sprintf('.\\MCU_Wrapper\\run_mex.bat "%s" "%s" "%s" %s', includesArg, codeArg, definesArg, modeArg); + +status = system(cmd); + +if status == 0 beep else - error('Error!'); + error('Error during compilation'); end - + + +function [includesArg, codeArg] = make_mex_arguments(incTableName, srcTableame) +%MAKE_MEX_ARGUMENTS Формирует строки аргументов для вызова mex-компиляции через батник +% +% [includesArg, codeArg] = make_mex_arguments(includesCell, codeCell) +% +% Вход: +% includesCell — ячейковый массив путей к директориям include +% codeCell — ячейковый массив исходных файлов +% +% Выход: +% includesArg — строка для передачи в батник, например: "-I"inc1" -I"inc2"" +% codeArg — строка с исходниками, например: ""src1.c" "src2.cpp"" + + + % Здесь пример получения из маски текущего блока (замени по своему) + blockHandle = gcbh; % или замени на нужный блок + + includesCell = parseCellString(get_param(blockHandle, incTableName)); + codeCell = parseCellString(get_param(blockHandle, srcTableame)); + + % Оборачиваем пути в кавычки и добавляем -I + includesStr = strjoin(cellfun(@(f) ['-I"' f '"'], includesCell, 'UniformOutput', false), ' '); + + % Оборачиваем имена файлов в кавычки + codeStr = strjoin(cellfun(@(f) ['"' f '"'], codeCell, 'UniformOutput', false), ' '); + + % Удаляем символ переноса строки и пробел в конце, если вдруг попал + codeStr = strtrim(codeStr); + includesStr = strtrim(includesStr); + + % Оборачиваем всю строку в кавычки, чтобы батник корректно понял + % includesArg = ['"' includesStr '"']; + % codeArg = ['"' codeStr '"']; + includesArg = includesStr; + codeArg = codeStr; + +end + +function definesArg = buildDefinesString() + blockHandle = gcbh; + + % Получаем MaskValues и MaskNames + maskValues = get_param(blockHandle, 'MaskValues'); + paramNames = get_param(blockHandle, 'MaskNames'); + + % Индексы параметров + idxEnable = find(strcmp(paramNames, 'enableThreading')); + idxCycles = find(strcmp(paramNames, 'threadCycles')); + idxClk = find(strcmp(paramNames, 'mcuClk')); + + if any([isempty(idxEnable), isempty(idxCycles), isempty(idxClk)]) + error('Один или несколько параметров не найдены в маске'); + end + + % Значения + enableVal = maskValues{idxEnable}; + cyclesVal = maskValues{idxCycles}; + clkMHz = str2double(maskValues{idxClk}); + clkHz = round(clkMHz * 1e6); + + % Формируем defines в формате: -D"NAME=VALUE" + if strcmpi(enableVal, 'on') + def1 = ['-D"RUN_APP_MAIN_FUNC_THREAD"']; + else + def1 = ['']; + end + def2 = ['-D"DEKSTOP_CYCLES_FOR_MCU_APP__EQ__' cyclesVal '"']; + def3 = ['-D"MCU_CORE_CLOCK__EQ__' num2str(clkHz) '"']; + + definesArg = strjoin({def1, def2, def3}, ' '); + % definesArg = ['"' definesStr '']; + % definesArg = definesStr; +end + + + +function out = parseCellString(str) + str = strtrim(str); + if startsWith(str, '{') && endsWith(str, '}') + str = str(2:end-1); + end + + parts = split(str, ';'); + out = cell(numel(parts), 1); + for i = 1:numel(parts) + el = strtrim(parts{i}); + if startsWith(el, '''') && endsWith(el, '''') + el = el(2:end-1); + end + out{i} = el; + end + + if isempty(out) || (numel(out) == 1 && isempty(out{1})) + out = {}; + end +end + +function str = cellArrayToString(cellArray) + quoted = cellfun(@(s) ['''' s ''''], cellArray, 'UniformOutput', false); + str = ['{' strjoin(quoted, ';') '}']; +end + +% % Компилирует S-function +% clear, clc, +% +% set = mex.getCompilerConfigurations('C', 'Selected'); +% +% Ts = 0.00001; +% +% delete("*.mexw64") +% delete("*.mexw64.pdb") +% delete(".\MCU_Wrapper\Outputs\*.*"); +% +% status=system('.\MCU_Wrapper\run_mex.bat debug'); +% +% if status==0 +% beep +% else +% error('Error!'); +% end +%