Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
%% 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