Code covered by the BSD License  

Highlights from
Simulink bus/SimEvents entity interface blocks

Simulink bus/SimEvents entity interface blocks

by

 

This utility generates blocks which interface between Simulink bus signals and SimEvents entities.

bus2entity(BusObject)
function bus2entity(BusObject)
%% BUS2ENTITY Create bus to entity conversion block
%   BUS2ENTITY(BUSOBJECT) creates a Simulink block in a new model which can
%   be used to convert a bus signal to a SimEvents entity.  The entity will
%   have attributes corresponding to the signals in the bus, all of which
%   will be converted to doubles.  Use the trigger port to control
%   generation of entities.
%
%   This function does not currently support nested buses.

%% Check for valid BusObject
if ~strcmp(class(BusObject),'Simulink.Bus')
    error('Invalid bus object');
elseif isempty(BusObject.Elements)
    error('Bus contains no signals');
end

AttributeCount = length(BusObject.Elements);

%% Load necessary Simulink and SimEvents librarys
load_system('simulink');
load_system('simeventsattributes2');
load_system('simeventstranslate1');
load_system('simeventsgenerators1');
load_system('simeventsportsubsys1');

%% Create top level block
MdlTop = new_system;
MdlTop = getfullname(MdlTop);
Mdl = [MdlTop,'/Bus2Entity'];
add_block('simulink/Ports & Subsystems/Subsystem',Mdl,...
    'Position',[70 48 200 117]);
% Empty subsystem
Simulink.SubSystem.deleteContents(Mdl);

%% Add Subsystem
Subsystem = [Mdl,'/Subsystem'];
add_block('simulink/Ports & Subsystems/Function-Call Subsystem',Subsystem,...
    'Position',[240 50+5*mod(AttributeCount,2) 340 45+25*AttributeCount+5*mod(AttributeCount,2)]);

%% Set Subsystem parameters
% We need to propagate execution context
set_param(Subsystem,'PropExecContextOutsideSubsystem','on')

%% Add BusSelector
BusSelector = [Subsystem,'/Bus Selector'];
add_block('simulink/Signal Routing/Bus Selector',BusSelector,...
    'Position',[175 84 180 84+50*AttributeCount]);

%% Set BusSelector parameters
% , is used to separate signal names.
OutputSignals = '';
for i = 1:AttributeCount
    OutputSignals = [OutputSignals,BusObject.Elements(i).Name,','];
end
OutputSignals = OutputSignals(1:end-1); % Remove trailing ,

set_param(BusSelector,'OutputSignals',OutputSignals);

%% Add DataTypeConversion
DataTypeConversion = {};
for i = 1:AttributeCount
    DataTypeConversion{i} = [Subsystem,'/ToDouble',num2str(i)];
    add_block('simulink/Signal Attributes/Data Type Conversion',DataTypeConversion{i},...
        'Position',[260 43+50*i 335 77+50*i]);
end

%% Add Outport
Inport = [Subsystem,'/In1'];
set_param(Inport,'Position',[110 78+25*AttributeCount 140 92+25*AttributeCount]);
Outport = {[Subsystem,'/Out1']};
for i = 2:AttributeCount
    Outport{i} = [Subsystem,'/Out',num2str(i)];
    add_block('simulink/Ports & Subsystems/Out1',Outport{i},...
        'Position',[360 53+50*i 390 67+50*i]);
end

%% Connect Inport, BusSelector, DataTypeConversion and Outport signal lines
delete_line(Subsystem,'In1/1','Out1/1') % Delete exisiting line
InportPorts = get_param(Inport,'PortHandles');
BusSelectorPorts = get_param(BusSelector,'PortHandles');
add_line(Subsystem,InportPorts.Outport,BusSelectorPorts.Inport);
for i = 1:AttributeCount
    DataTypeConversionPorts = get_param(DataTypeConversion{i},'PortHandles');
    OutportPorts = get_param(Outport{i},'PortHandles');
    add_line(Subsystem,BusSelectorPorts.Outport(i),DataTypeConversionPorts.Inport);
    add_line(Subsystem,DataTypeConversionPorts.Outport,OutportPorts.Inport);
end

%% Add SetAttribute
SetAttribute = [Mdl,'/Set Attribute'];
add_block('simeventsattributes2/Set Attribute',SetAttribute,...
    'Position',[410 43+3*AttributeCount 500 77+23*AttributeCount]);

%% Set SetAttribute parameters
% For Value, TreatAsVector we repeat the defaults; For From we repeat
% Signal port.  For Name we loop through the bus elements.  | is used to
% separate attributes.
AttributeName = '';
for i = 1:AttributeCount
    AttributeName = [AttributeName,BusObject.Elements(i).Name,'|'];
end
AttributeName = AttributeName(1:end-1); % Remove trailing |
    
set_param(SetAttribute,'AttributeName',AttributeName,...
	'AttributeValue',[repmat('0|',1,AttributeCount-1),'0'],...
	'AttributeFrom',[repmat('Signal port|',1,AttributeCount-1),'Signal port'],...
	'AttributeTreatAsVector',[repmat('1|',1,AttributeCount-1),'1']);

%% Connect Subsystem and SetAttribute
SubsystemPorts = get_param(Subsystem,'PortHandles');
SetAttributePorts = get_param(SetAttribute,'PortHandles');
for i = 1:AttributeCount
    add_line(Mdl,SubsystemPorts.Outport(i),SetAttributePorts.Inport(i));
end

%% Add FcnCallSplitter and EntityGenerator
FcnCallSplitter = [Mdl,'/FcnCallSplitter'];
add_block('simeventstranslate1/Signal-Based Event to Function-Call Event',FcnCallSplitter,...
    'Position',[105 85+25*AttributeCount 190 140+25*AttributeCount]);
EntityGenerator = [Mdl,'/EntityGenerator'];
add_block('simeventsgenerators1/Entity Generators/Event-Based Entity Generator',EntityGenerator,...
    'Position',[250 102+25*AttributeCount 335 158+25*AttributeCount]);

%% Set FcnCallSplitter parameters
set_param(FcnCallSplitter,'GenerateFunctionCallUpon','Function call from port fcn',...
	'EnableF2Port','on',...
	'SpecifyEventPriority','on',...
	'PriorityFunctionCall','1');

%% Set EntityGenerator parameters
set_param(EntityGenerator,'GenerateEntitiesUpon','Function call from port fcn',...
	'SpecifyEventPriority','on',...
	'PriorityEntityGeneration','2');

%% Connect FcnCallSplitter, EntityGenerator, Subsystem and SetAttribute
FcnCallSplitterPorts = get_param(FcnCallSplitter,'PortHandles');
EntityGeneratorPorts = get_param(EntityGenerator,'PortHandles');
add_line(Mdl,FcnCallSplitterPorts.Outport(1),SubsystemPorts.Trigger);
add_line(Mdl,FcnCallSplitterPorts.Outport(2),EntityGeneratorPorts.Inport);
add_line(Mdl,EntityGeneratorPorts.RConn,SetAttributePorts.LConn);

%% Add input and output ports
BusIn = [Mdl,'/BusIn'];
add_block('simulink/Ports & Subsystems/In1',BusIn,...
    'Position',[35 40+15*AttributeCount+5*mod(AttributeCount,2) 65 54+15*AttributeCount+5*mod(AttributeCount,2)]);
TriggerIn = [Mdl,'/TriggerIn'];
add_block('simulink/Ports & Subsystems/In1',TriggerIn,...
    'Position',[35 108+25*AttributeCount 65 122+25*AttributeCount]);
EntityOut = [Mdl,'/OUT'];
add_block('simeventsportsubsys1/Conn',EntityOut,...
    'Position',[540 63+10*AttributeCount 570 80+10*AttributeCount],...
    'Side','Right','Orientation','left'); % Flip and put on right of subsystem

%% Connect input and output ports to rest of system
BusInPorts = get_param(BusIn,'PortHandles');
TriggerInPorts = get_param(TriggerIn,'PortHandles');
EntityOutPorts = get_param(EntityOut,'PortHandles');
add_line(Mdl,BusInPorts.Outport,SubsystemPorts.Inport);
add_line(Mdl,TriggerInPorts.Outport,FcnCallSplitterPorts.Inport);
add_line(Mdl,SetAttributePorts.RConn,EntityOutPorts.RConn);

%% That's all folks!
set_param(Mdl,'Mask','on')
set_param(Mdl,'MaskType','Bus2Entity')
set_param(Mdl,'MaskDescription',sprintf([...
    'Bus to entity interface.  Generated entities will have attributes ',...
    'corresponding to the signals in the bus, all of which will be ',...
    'converted to doubles.  Use the trigger port to control generation of ',...
    'entities.\n\nThis block was created with BUS2ENTITY.  A separate ',...
    'block must be created for each bus object.']));
open_system(MdlTop);

Contact us