How to get the port types and dimensions for a block

We are generating code using RTW via a script. I am trying to collect the port dimensions and data types. Argument names would be great too, but not required.
I am currently able to get the port names

 採用された回答

Fangjun Jiang
Fangjun Jiang 2011 年 6 月 3 日

1 投票

Sometimes it is hard to find help in the document. Many times I just poke around and make an educated guess. I made a simple model and ran the code below. It seems to be able to get the dimension and data types. Hope this will help.
clc;
acModelName=bdroot;
lcInportHandles = find_system(acModelName,'FindAll','On','SearchDepth',1,'BlockType','Inport');
for i=1:length(lcInportHandles)
lcInputDimensions = get_param(lcInportHandles(i),'CompiledPortDimensions');
lcInputDimensions=lcInputDimensions.Outport
lcInputDataTypes = get_param(lcInportHandles(i),'CompiledPortDataTypes');
lcInputDataTypes = lcInputDataTypes.Outport
end
The output looks like this:
lcInputDimensions =
1 2
lcInputDataTypes =
'single'
lcInputDimensions =
1 1
lcInputDataTypes =
'int8'

4 件のコメント

Kevin
Kevin 2011 年 6 月 3 日
Ok, this is all great stuff. Now, how to I dig into the Buses until I am down to a struct of primitives, or a struct of structs with primitives at the lowest level, like I have on the code size?
Thanks for the help. The .Ouport part was a bit confusing, but I understand now.
-Kevin
Fangjun Jiang
Fangjun Jiang 2011 年 6 月 3 日
How do you specify your bus, through a bus object, or you just mean a bus line out of the Bus Creator block in your model?
Kevin
Kevin 2011 年 6 月 3 日
I am not sure how they were initially created. I know I have three buses, two input and one output, and I need to iterate through all of the elements until I get down to primitive types. Then, these must match the structs which are created in RTW when we build our code.
This probably should be another topic.
Kevin
Kevin 2011 年 6 月 3 日
I moved the next part of this to the following:
http://www.mathworks.com/matlabcentral/answers/8749-how-to-iterate-through-a-bus-object-intil-i-have-a-struct-of-primitives-which-match-rtw-output-with

サインインしてコメントする。

その他の回答 (4 件)

Nirmal Gunaseelan
Nirmal Gunaseelan 2011 年 6 月 2 日

2 投票

You can get the dimensions and data types of a block's port after you put the model into a 'compiled' state. The
model([],[],[],'compile')
where model is your model name will get you there. After that, a get_param on the block of interest with the options
CompiledPortDimensions
CompiledPortDataTypes
will get you the info you want.

3 件のコメント

Fangjun Jiang
Fangjun Jiang 2011 年 6 月 2 日
Good to know this model([],[],[],'compile') approach! From what version of Simulink can I do this?
Kevin
Kevin 2011 年 6 月 2 日
What is 'model'? A handle to a model?
Nirmal Gunaseelan
Nirmal Gunaseelan 2011 年 6 月 3 日
'model' in the above snippet is the name of your loaded model. I like to think of it as a way to interact with the model as though it has a function signature.
I have been using this snippet for a long time now, I believe it was there as far back as R14.

サインインしてコメントする。

Kevin
Kevin 2011 年 6 月 2 日

0 投票

@Nirmal Gunaseelan - So, how do I get a pointer to my model in order to execute this? When I do a find_system, I can't figure out how to limit the results to my top-level model that I am building?
Fangjun Jiang
Fangjun Jiang 2011 年 6 月 2 日

0 投票

Some properties such as dimensions and data types are not up to date when the model is loaded. These properties depend on other information. They also need to be cross-checked to avoid any miss-match. You need to "update" the model or further force the model to be "compiled" to go through those propagation and cross-checking. The command model([],[],[],'compile') is to force that process. model is not a handle. It is the name of your model. The model needs to be loaded. Once the command model([],[],[],'compile') is done. You can use find_system() with 'SearchDepth' to find all the root-level Inport blocks and Output blocks. And then you can get the dimension and data type property of all those Inport/Outport blocks.

5 件のコメント

Kevin
Kevin 2011 年 6 月 2 日
Very cool. Now I just need to figure out how to access the CompiledPortDimensions parameter. There are so many half-answers, to which I can't find the other half, and the matlab documentation is about as helpful as MicroSoft help.
I have:
lcInportHandles = find_system(acModelName,'FindAll','On','SearchDepth',1,'BlockType','Inport');
lcInportNames = get(lcInportHandles,'Name'); % gets a vector of input names
lcVec = get_param(lcInportHandles,'CompiledPortDimensions'); % gives two empty 1x1 structs.
Walter Roberson
Walter Roberson 2011 年 6 月 2 日
Kevin, does lcInportNames return valid looking names? Do Inport always have to be named or are they sometimes nameless?
Fangjun Jiang
Fangjun Jiang 2011 年 6 月 2 日
You code looks good. I am off Matlab now so won't be able to confirm it for you. Do this to do a quick test-run.
Select an Inport block at your model root level by just clicking it. Go to Matlab command window and type get(gcbh). You'll see a long list of properties and their values. Check whether 'CompiledPortDiemsios' is the exact right property name. Remember you need to run that model(...) command first.
Kevin
Kevin 2011 年 6 月 2 日
CompiledPortWidths: [1x1 struct]
CompiledPortDimensions: [1x1 struct]
CompiledPortDataTypes: [1x1 struct]
CompiledPortComplexSignals: [1x1 struct]
CompiledPortFrameData: [1x1 struct]
The parameter names look correct. Everything looks empty though. I know there is a somewhat complicated bus for the input. Something is wrong - I just don't know what it might be.
Kevin
Kevin 2011 年 6 月 2 日
@Walter - yes, the names vector has two input names and one output name, and they are correct according to the model.

サインインしてコメントする。

Kevin
Kevin 2011 年 6 月 2 日

0 投票

Ok, here is where I am at now...
lcInterfaceSpec = RTW.getEncapsulationInterfaceSpecification(acModelName);
%get handles to our inport/outports
lcInportHandles = find_system(acModelName,'FindAll','On','SearchDepth',1,'BlockType','Inport');
lcOutportHandles = find_system(acModelName,'FindAll','On','SearchDepth',1,'BlockType','Outport');
lcInportNames = get(lcInportHandles,'Name');
lcOutportNames = get(lcOutportHandles,'Name');
lcPortNames = vertcat(lcInportNames, lcOutportNames);
%now, get the dimensions of each of our ports
%code_blocks = find_system(getfullname(acModelName),'LookUnderMasks','all','BlockType','SubSystem','Name','code');
%lcModelHandle = find_system(acModelName,'FindAll','On','SearchDepth',1,'BlockType','SubSystem');
%the following commands require a compiled model...
eval([acModelName,'([],[],[],''compile'');']);
q=get_param(gcb,'PortHandles');
lcInputDimensions = get_param(lcInportHandles,'CompiledPortDimensions');
lcInputDimensions2 = get_param(q.Inport,'CompiledPortDimensions');
lcInputDataTypes = get_param(lcInportHandles,'CompiledPortDataTypes');
lcInputDataTypes2 = get_param(q.Inport,'CompiledPortDataType');
lcInputPortWidths = get_param(lcInportHandles,'CompiledPortWidths');
lcInputPortWidths2 = get_param(q.Inport,'CompiledPortWidth');
lcOutputDimensions = get_param(lcOutportHandles,'CompiledPortDimensions');
lcOutputDataTypes = get_param(lcOutportHandles,'CompiledPortDataTypes');
lcOutputPortWidths = get_param(lcOutportHandles,'CompiledPortWidths');
%first, get the number of arguments
lnArguments = lcInterfaceSpec.getNumArgs;
%loop through args, check the type, and loop through any complex types
for i=1:length(lcPortNames) % should be the same as lnArguments
%todo/fix - how to check types???? ARRRGHHHHH!!!!
lcArgName = getArgName(lcInterfaceSpec, lcPortNames{i});
lcQualifier = getArgQualifier(lcInterfaceSpec, lcPortNames{i}); %const
lcCategory = getArgCategory(lcInterfaceSpec, lcPortNames{i}); %Pointer
lnPosition = getArgPosition(lcInterfaceSpec, lcPortNames{i})
end
So, I found http://www.mathworks.com/help/toolbox/ecoder/ref/rtw.modelcppargsclass.getargqualifier.html some time ago, and just now figured out how to get results out of it. But there is no way to get the data type out of it. I also found that get_param(lcInportHandles,'CompiledPortDataTypes') returns the names of the bus, rather than a real type. I was hoping to get a type like Simulink.BusElement from http://www.mathworks.com/matlabcentral/fileexchange/13399-embedded-coder-robot-nxt-demo/content/ecrobotNXT/nxtracer/param.m, or from here: http://www.mathworks.com/help/toolbox/simulink/ug/f14-90479.html.
So, how do I tell if I have a bus, or a primitive, or something else?
Thanks,
-Kevin

3 件のコメント

Nirmal Gunaseelan
Nirmal Gunaseelan 2011 年 6 月 3 日
Kevin, the data type of the port is the name of the bus. This bus object should be thought of as the data type specification in the workspace. When you EVAL this data type name, you'll be getting the bus object. You could then access its type (Simulink.Bus) using CLASS (Bus/primitive) and its elements (Simulink.BusElement) and their data types and so on (buses could have other buses as its elements). I agree that the bus type is making the process of finding the data type complicated.
韵 郝
韵 郝 2021 年 6 月 24 日
@Kevin, the model is stuck and cannot be closed after executing this command "eval([acModelName,'([],[],[],''compile'');']);", how can I stop compiling?
Fabien Jeanneteau Safran
Fabien Jeanneteau Safran 2022 年 5 月 11 日
Hi,
If you are stuck (like me), you should try:
model([],[],[],'term')
I found answer on following page: https://fr.mathworks.com/matlabcentral/answers/29764-turn-off-compile-mode
Regards,
Fabien

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeEvent Functions についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by