%% set_code % set the script of an embedded matlab block to an inputed % string of eml code, create the inputs and outputs for the % subsystem to connect to the eml block % inputs: % block_handle:handle - handle block to update % code:string - eml code % function_name:string - name of the function % outputs: % eml_handle:handle - handle of eml block, as this function may % create a new block. % Author: Colin Eles elesc@mcmaster.ca % Organization: McMaster Centre for Software Certification function eml_handle = set_code(block_handle,code,function_name) % unlink the block from the library, this is necessary if % we % want to change the subsystem of the block. set_param(block_handle,'LinkStatus','none') % determine if the name already exists in the model if (~strcmp(get(block_handle,'Name'),function_name)) try set_param(block_handle,'Name',function_name); catch exception msgbox(exception.message); end end % embedded matlab code block store code in stateflow states so % we need to get the root hande S = sfroot; % get the path of the code block code_block = sprintf('%s/code',getfullname(block_handle)); % determine if code block already exists code_blocks = find_system(getfullname(block_handle),'LookUnderMasks','all','BlockType','SubSystem','Name','code'); % if the code block does not already exists we need to create a % new one if (isempty(code_blocks)) code_blocks = add_block('simulink/User-Defined Functions/Embedded MATLAB Function',code_block); end eml_handle = code_blocks % find the state of the code block and update it to the new % code myState = S.find('-isa','Stateflow.EMChart', '-and', 'Path', code_block); % find which one we want to edit if (~isempty(myState)) myState.Script = sprintf('%s',code); end % delete any lines that are unconnected and one end or both % code from lines = find_system( getfullname(block_handle), ... 'LookUnderMasks', 'all', ... 'FindAll', 'on', ... 'Type', 'line' ) ; for i=1:length( lines ) if ishandle( lines( i ) ) TableBlock.delete_recursive( lines( i ) ) end end % we need to determine which of the inports and outports we % need to create and delete. Whenever we delete a port anything % connected with this port is unconnected, other blocks, scopes % etc. We would like to avoid this if possible because it can % be quite annoying. % First loop through all the inport blocks, if there does not % exists an inport in the code block of the same name then % delete the inport block inports = find_system(getfullname(block_handle),'LookUnderMasks','all','SearchDepth',1,'FindAll','On','BlockType','Inport'); for i=1:size(inports,1) found = 0; in_handles=find_system(code_block, 'SearchDepth',1,'FindAll','On','FollowLinks','On','LookUnderMasks','All','BlockType','Inport'); for j=1:size(in_handles,1) if strcmp(get_param(inports(i),'Name'),get_param(in_handles(j),'Name')) found = 1; end end if (~found) % old inport no longer exists delete_block(inports(i)); end end % now we loop through all the inports in the code block if % there is an inport block of the same name then connect them, % else create a new inport block and connect them in_handles=find_system(code_block, 'SearchDepth',1,'FindAll','On','FollowLinks','On','LookUnderMasks','All','BlockType','Inport'); for j = 1:size(in_handles,1) found = 0; inports = find_system(getfullname(block_handle),'LookUnderMasks','all','SearchDepth',1,'BlockType','Inport'); for i = 1:size(inports,1) if strcmp(get_param(inports(i),'Name'),get_param(in_handles(j),'Name')) found = 1; % draw the line new_port_num = sprintf('%s/1',get_param(in_handles(j),'Name')); dest_port = sprintf('%s/%d','code',j); try add_line(getfullname(block_handle),new_port_num,dest_port); end end end if (~found) new_port = sprintf('%s/%s',getfullname(block_handle),get_param(in_handles(j),'Name')); add_block('simulink/Sources/In1',new_port) new_port_num = sprintf('%s/1',get_param(in_handles(j),'Name')); dest_port = sprintf('%s/%d','code',j); % sometimes line will be created automatically try add_line(getfullname(block_handle),new_port_num,dest_port); end end end % Next we do the same thing with the outputs outports = find_system(getfullname(block_handle),'LookUnderMasks','all','SearchDepth',1,'FindAll','On','BlockType','Outport'); for i=1:size(outports,1) found = 0; out_handles=find_system(code_block, 'SearchDepth',1,'FindAll','On','FollowLinks','On','LookUnderMasks','All','BlockType','Outport'); for j=1:size(out_handles,1) if strcmp(get_param(outports(i),'Name'),get_param(out_handles(j),'Name')) found = 1; end end if (~found) % old inport no longer exists delete_block(outports(i)); end end out_handles=find_system(code_block, 'SearchDepth',1,'FindAll','On','FollowLinks','On','LookUnderMasks','All','BlockType','Outport'); for j = 1:size(out_handles,1) found = 0; outports = find_system(getfullname(block_handle),'LookUnderMasks','all','SearchDepth',1,'BlockType','Outport'); for i = 1:size(outports,1) if strcmp(get_param(outports(i),'Name'),get_param(out_handles(j),'Name')) found = 1; % draw the line new_port_num = sprintf('%s/1',get_param(out_handles(j),'Name')); dest_port = sprintf('%s/%d','code',j); try add_line(getfullname(block_handle),dest_port,new_port_num); end end end if (~found) new_port = sprintf('%s/%s',getfullname(block_handle),get_param(out_handles(j),'Name')); add_block('simulink/Sinks/Out1',new_port) new_port_num = sprintf('%s/1',get_param(out_handles(j),'Name')); dest_port = sprintf('%s/%d','code',j); try add_line(getfullname(block_handle),dest_port,new_port_num); end end end % delete any lines that are unconnected and one end or both % again sometimes extra lines are created lines = find_system( getfullname(block_handle), ... 'LookUnderMasks', 'all', ... 'FindAll', 'on', ... 'Type', 'line' ) ; for i=1:length( lines ) if ishandle( lines( i ) ) TableBlock.delete_recursive( lines( i ) ) end end end