release 1.0
This commit is contained in:
284
McuLib/m/mcuPorts.m
Normal file
284
McuLib/m/mcuPorts.m
Normal file
@@ -0,0 +1,284 @@
|
||||
classdef mcuPorts
|
||||
|
||||
methods(Static)
|
||||
|
||||
function write()
|
||||
block = gcb;
|
||||
mask = Simulink.Mask.get(block);
|
||||
hPath = fullfile('.\MCU_Wrapper', 'mcu_wrapper_conf.h');
|
||||
cPath = fullfile('.\MCU_Wrapper', 'mcu_wrapper.c');
|
||||
mcuPorts.defaultUnused();
|
||||
%% CREATE
|
||||
prefixNumb = 'IN';
|
||||
[widths, portPrefixes] = mcuPorts.getMaskNames('in');
|
||||
|
||||
headerText = mcuPorts.addPortHeaderDefines('', widths, prefixNumb, portPrefixes);
|
||||
cText = mcuPorts.addPortCDefines('', widths, prefixNumb, portPrefixes);
|
||||
|
||||
prefixNumb = 'OUT';
|
||||
[widths, portPrefixes] = mcuPorts.getMaskNames('out');
|
||||
|
||||
headerText = mcuPorts.addPortHeaderDefines(headerText, widths, prefixNumb, portPrefixes);
|
||||
cText = mcuPorts.addPortCDefines(cText, widths, prefixNumb, portPrefixes);
|
||||
|
||||
%% WRITE
|
||||
|
||||
hCode = fileread(hPath);
|
||||
hCode = regexprep(hCode, '\r\n?', '\n');
|
||||
cCode = fileread(cPath);
|
||||
cCode = regexprep(cCode, '\r\n?', '\n');
|
||||
|
||||
code = editCode.insertSection(hCode, '// INPUT/OUTPUTS PARAMS', headerText.PARAMS);
|
||||
code = editCode.insertSection(code, '// INPUT/OUTPUTS AUTO-PARAMS', headerText.AUTO_PARAMS);
|
||||
|
||||
fid = fopen(hPath, 'w', 'n', 'UTF-8');
|
||||
if fid == -1
|
||||
error('Не удалось открыть файл для записи');
|
||||
end
|
||||
fwrite(fid, code);
|
||||
fclose(fid);
|
||||
|
||||
code = editCode.insertSection(cCode, '// INPUT/OUTPUTS AUTO-PARAMS', cText);
|
||||
fid = fopen(cPath, 'w', 'n', 'UTF-8');
|
||||
if fid == -1
|
||||
error('Не удалось открыть файл для записи');
|
||||
end
|
||||
fwrite(fid, code);
|
||||
fclose(fid);
|
||||
end
|
||||
|
||||
|
||||
function [portwidth, defnames] = getMaskNames(port_prefix)
|
||||
block = gcb;
|
||||
% Получаем значение из спиннера
|
||||
mask = Simulink.Mask.get(block);
|
||||
paramName = sprintf('%sNumb', port_prefix);
|
||||
param = mask.getParameter(paramName);
|
||||
numb = str2double(param.Value);
|
||||
|
||||
|
||||
% Инициализируем массив для значений
|
||||
defnames = strings(1, numb);
|
||||
portwidth = [];
|
||||
|
||||
% Чтение значений edit-параметров
|
||||
for i = 1:numb
|
||||
paramName = sprintf('%s_port_%d_name', port_prefix, i);
|
||||
param = mask.getParameter(paramName);
|
||||
defnames(i) = param.Value;
|
||||
paramName = sprintf('%s_port_%d_width', port_prefix, i);
|
||||
param = mask.getParameter(paramName);
|
||||
portwidth(i) = str2double(param.Value);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function updateMask()
|
||||
mcuPorts.updateMask_prefix('in');
|
||||
mcuPorts.updateMask_prefix('out');
|
||||
end
|
||||
|
||||
|
||||
function defaultUnused()
|
||||
mcuPorts.defaultUnused_prefix('in');
|
||||
mcuPorts.defaultUnused_prefix('out');
|
||||
end
|
||||
end
|
||||
|
||||
methods(Static, Access=private)
|
||||
|
||||
|
||||
|
||||
function updateMask_prefix(port_prefix)
|
||||
block = gcb;
|
||||
% Получаем значение из спиннера
|
||||
mask = Simulink.Mask.get(block);
|
||||
paramName = sprintf('%sNumb', port_prefix);
|
||||
param = mask.getParameter(paramName);
|
||||
n = str2double(param.Value);
|
||||
|
||||
% Максимальное количество портов
|
||||
maxPorts = param.Range(2);
|
||||
|
||||
% Проходим по всем edit-полям
|
||||
for i = 1:maxPorts
|
||||
% Формируем имя параметра
|
||||
paramDefName = sprintf('%s_port_%d_name', port_prefix, i);
|
||||
paramWidthName = sprintf('%s_port_%d_width', port_prefix, i);
|
||||
paramDef = mask.getParameter(paramDefName);
|
||||
paramWidth = mask.getParameter(paramWidthName);
|
||||
|
||||
if i <= n
|
||||
% Показываем параметр
|
||||
paramDef.Visible = 'on';
|
||||
paramWidth.Visible = 'on';
|
||||
|
||||
% Если значение пустое — задаём дефолтное
|
||||
if isempty(strtrim(paramDef.Value))
|
||||
paramDef.Value = upper(port_prefix);
|
||||
end
|
||||
% Если значение пустое — задаём дефолтное
|
||||
if isempty(strtrim(paramWidth.Value)) || strcmp(paramWidth.Value, '0')
|
||||
paramWidth.Value = '16';
|
||||
end
|
||||
else
|
||||
% Скрываем параметр
|
||||
paramDef.Visible = 'off';
|
||||
paramWidth.Visible = 'off';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function defaultUnused_prefix(port_prefix)
|
||||
block = gcb;
|
||||
% Получаем значение из спиннера
|
||||
mask = Simulink.Mask.get(block);
|
||||
paramName = sprintf('%sNumb', port_prefix);
|
||||
param = mask.getParameter(paramName);
|
||||
numb = str2double(param.Value);
|
||||
|
||||
% Максимальное количество портов
|
||||
maxPorts = param.Range(2);
|
||||
% Чтение значений edit-параметров
|
||||
for i = numb+1:maxPorts
|
||||
paramName = sprintf('%s_port_%d_name', port_prefix, i);
|
||||
param = mask.getParameter(paramName);
|
||||
param.Value = upper(port_prefix);
|
||||
paramName = sprintf('%s_port_%d_width', port_prefix, i);
|
||||
param = mask.getParameter(paramName);
|
||||
param.Value = '16';
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function headerText = addPortHeaderDefines(existingText, widths, prefixNumb, portPrefixes)
|
||||
% existingText — структура с полями PARAMS, AUTO_PARAMS
|
||||
% widths — вектор ширин портов
|
||||
% prefixNumb — префикс общего счётчика (например, 'OUT')
|
||||
% portPrefixes — {'OUT', 'OUT', ...}
|
||||
|
||||
n = numel(widths);
|
||||
upperPrefix = upper(prefixNumb);
|
||||
|
||||
% === PARAMS ===
|
||||
lines = {
|
||||
sprintf('#define %s_PORT_NUMB %d', upperPrefix, n)
|
||||
};
|
||||
for i = 1:n
|
||||
lines{end+1} = sprintf('#define %s_PORT_%d_WIDTH %d', ...
|
||||
upper(portPrefixes{i}), i, widths(i));
|
||||
end
|
||||
newParams = strjoin(lines, newline);
|
||||
newParams = [newParams, newline];
|
||||
|
||||
% === AUTO-PARAMS ===
|
||||
lines = {};
|
||||
|
||||
% Формируем выражение суммы ширин с добавлением PORT
|
||||
sumExprParts = cell(1,n);
|
||||
for i = 1:n
|
||||
sumExprParts{i} = sprintf('%s_PORT_%d_WIDTH', upper(portPrefixes{i}), i);
|
||||
end
|
||||
sumExpr = strjoin(sumExprParts, ' + ');
|
||||
|
||||
lines{end+1} = sprintf('/// === Полный размер буфера ===');
|
||||
lines{end+1} = sprintf('#define TOTAL_%s_SIZE (%s)', upperPrefix, sumExpr);
|
||||
|
||||
lines{end+1} = '';
|
||||
lines{end+1} = sprintf('/// === Смещения массивов (внутри общего буфера) ===');
|
||||
|
||||
for i = 1:n
|
||||
if i == 1
|
||||
lines{end+1} = '#define OFFSET_ARRAY_1 0';
|
||||
else
|
||||
lines{end+1} = sprintf('#define OFFSET_ARRAY_%d (OFFSET_ARRAY_%d + %s_PORT_%d_WIDTH)', ...
|
||||
i, i - 1, upper(portPrefixes{i - 1}), i - 1);
|
||||
end
|
||||
end
|
||||
newAuto = strjoin(lines, newline);
|
||||
|
||||
% === Добавление к существующему ===
|
||||
if isfield(existingText, 'PARAMS')
|
||||
headerText.PARAMS = [existingText.PARAMS, newline, newParams];
|
||||
else
|
||||
headerText.PARAMS = newParams;
|
||||
end
|
||||
|
||||
if isfield(existingText, 'AUTO_PARAMS')
|
||||
headerText.AUTO_PARAMS = [existingText.AUTO_PARAMS, newline, newAuto, newline];
|
||||
else
|
||||
headerText.AUTO_PARAMS = [newAuto, newline];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function cText = addPortCDefines(existingText, widths, prefixNumb, portPrefixes)
|
||||
% existingText — существующий текст .c
|
||||
% widths — вектор ширин портов
|
||||
% prefixNumb — общий префикс ('OUT')
|
||||
% portPrefixes — {'OUT', 'LOG', ...}
|
||||
|
||||
n = numel(widths);
|
||||
upperPrefix = upper(prefixNumb);
|
||||
lowerPrefix = lower(prefixNumb);
|
||||
|
||||
lines = {};
|
||||
|
||||
% === Таблица длин ===
|
||||
lines{end+1} = '/**';
|
||||
lines{end+1} = sprintf(' * @brief Таблица длин массивов %s', upperPrefix);
|
||||
lines{end+1} = ' */';
|
||||
% Здесь используем общий префикс для количества портов
|
||||
lines{end+1} = sprintf('const int %sLengths[%s_PORT_NUMB] = {', lowerPrefix, upperPrefix);
|
||||
for i = 1:n
|
||||
comma = ',';
|
||||
if i == n
|
||||
comma = '';
|
||||
end
|
||||
% Используем макросы с портовыми префиксами из portPrefixes
|
||||
lines{end+1} = sprintf(' %s_PORT_%d_WIDTH%s', upper(portPrefixes{i}), i, comma);
|
||||
end
|
||||
lines{end+1} = '};';
|
||||
|
||||
% === Таблица смещений ===
|
||||
lines{end+1} = '/**';
|
||||
lines{end+1} = sprintf(' * @brief Таблица смещений в выходном массиве %s', upperPrefix);
|
||||
lines{end+1} = ' */';
|
||||
lines{end+1} = sprintf('const int %sOffsets[%s_PORT_NUMB] = {', lowerPrefix, upperPrefix);
|
||||
for i = 1:n
|
||||
comma = ',';
|
||||
if i == n
|
||||
comma = '';
|
||||
end
|
||||
lines{end+1} = sprintf(' OFFSET_ARRAY_%d%s', i, comma);
|
||||
end
|
||||
lines{end+1} = '};';
|
||||
lines{end+1} = '';
|
||||
|
||||
newText = strjoin(lines, newline);
|
||||
|
||||
if nargin < 1 || isempty(existingText)
|
||||
cText = newText;
|
||||
else
|
||||
cText = [existingText, newline, newText];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function val = iff(cond, a, b)
|
||||
% Условное выражение inline
|
||||
if cond
|
||||
val = a;
|
||||
else
|
||||
val = b;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user