8.8 KiB
TargetLink Struct In- and Out-port Signals
[TOC]
Before You Start
External struct support was recently added, your repository might be in a state were some structs are still in the old format.
Inports and Outports Must Match
The name of the generated struct is the same as the name of the TL_BusInport/TL_BusOutport block. Therefore, the developer should change the producer and the consumer of a struct at the same time. By doing that, powertrain-build can verify that the structs look the same. If a struct were to change in size but keep the name, powertrain-build will catch that.
Definings Struct Signals
This section describes how to create struct signals.
Easiest way to work with and share structs is to create buses and storing them in .mat files, which can be loaded where needed in the _par.m files. Bus .mat files should be stored in a shared folder, such as Models/Common/VcBusDefinitions. This is very similar to how to work with shared enumerations, see TargetLink Enumerations.
Outports
To create an outgoing signal one must use the TL block TL_BusOutport. The name of the generated struct will be the same as the block name, so name the block appropriately. Preferably, the block name should be the same as the .mat file defining the bus signal.
The insignal to this block must come from a Bus Creator, where the name of the struct outport signal will be the same as the insignal. Each struct member will get the same name as the signals entering the bus creator.
To link to a loaded bus object, right click on the bus creator and click "Block Parameters (BusCreator)". Select "Bus: <object name>" as the data type. Expand the data type options (click ">>") and make sure mode is set to "Bus object" and then input the name of the bus. It is possible to browse loaded bus objects by clicking the "Edit" button.
For the bus, it is important to select the class CVC_DISP (like normal outports), data type IMPLICIT_STRUCT, name macro $L.
For the members, it is important to select the class CVC_DISP, otherwise they won't show up in the A2L-file, and name macro $L.
A2L extract:
/begin MEASUREMENT
sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal1 /* Name */
"" /* LongIdentifier */
FLOAT32_IEEE /* Datatype */
VOID_SCALING /* Conversion */
1 /* Resolution */
0 /* Accuracy */
-3.402823466e38 /* LowerLimit */
3.402823466e38 /* UpperLimit */
READ_WRITE
/begin IF_DATA ASAP1B_ADDRESS
KP_BLOB 0x00000000
/end IF_DATA
/end MEASUREMENT
JSON config file extract:
"outports": {
"sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal1": {
"handle": "VcCcHvcBustest/VcCcHvcBustest/Subsystem/VcCcHvcBustest/Bus Outport",
"name": "sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal1",
"configs": "((ALWAYS_ACTIVE))",
"description": "",
"type": "Float32",
"unit": "",
"offset": "-",
"lsb": "-",
"min": "-",
"max": "-",
"class": "CVC_DISP",
"width": 1
}
}
C source code extract:
/**************************************************************************************************\
CVC_DISP: CVC global observable variables in RAM | Width: N.A.
\**************************************************************************************************/
CVC_DISP struct sVcCcHvcBustest_Bus_SomeOutBus sVcCcHvcBustest_Bus_TestSignal = {
0.F, /* Te_BusSignal1 */
0.F /* Te_BusSignal2 */
};
void RESTART_VcCcHvcBustest(void)
{
sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal1 = 0.F;
sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal2 = 0.F;
}
C header code extract:
/*------------------------------------------------------------------------------------------------*\
TYPEDEFS
\*------------------------------------------------------------------------------------------------*/
struct sVcCcHvcBustest_Bus_SomeOutBus {
Float32 Te_BusSignal1;
Float32 Te_BusSignal2;
}; /* Description: bus outport struct */
/**************************************************************************************************\
CVC_DISP: CVC global observable variables in RAM | Width: N.A.
\**************************************************************************************************/
extern CVC_DISP struct sVcCcHvcBustest_Bus_SomeOutBus sVcCcHvcBustest_Bus_TestSignal;
Inports
To create an incoming signal one must use the TL block TL_BusInport. The insignal to this block can either come from a Bus Creator or a constant block located on the outermost layer, preferably referencing a bus object.
To link to a loaded bus object, right click on the bus creator/constant block and click "Block Parameters (<block type>)". Select "Bus: <object name>" as the data type. Expand the data type options (click ">>") and make sure mode is set to "Bus object" and then input the name of the bus. It is possible to browse loaded bus objects by clicking the "Edit" button, see image in the "Outports" chapter.
The name of the struct inport signal will be the same as the insignal or bus object, respectively.
For the bus, it is important to select the class CVC_EXT (like normal inports), data type IMPLICIT_STRUCT, name macro $L.
For the members, it is important to select the class CVC_DISP, otherwise they won't show up in the A2L-file, and name macro $L.
A2L extract:
/begin MEASUREMENT
sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal1 /* Name */
"" /* LongIdentifier */
FLOAT32_IEEE /* Datatype */
VOID_SCALING /* Conversion */
1 /* Resolution */
0 /* Accuracy */
-3.402823466e38 /* LowerLimit */
3.402823466e38 /* UpperLimit */
READ_WRITE
/begin IF_DATA ASAP1B_ADDRESS
KP_BLOB 0x00000000
/end IF_DATA
/end MEASUREMENT
JSON config file extract:
"inports": {
"sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal1": {
"handle": "VcCcHvcBusReceive/VcCcHvcBusReceive/Subsystem/VcCcHvcBusReceive/Bus Inport",
"name": "sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal1",
"configs": "((ALWAYS_ACTIVE))",
"description": "",
"type": "Float32",
"unit": "",
"offset": "-",
"lsb": "-",
"min": "-",
"max": "-",
"class": "CVC_DISP",
"width": 1
}
}
C source code extract:
void VcCcHvcBusReceive(void)
{
/* TargetLink outport: VcCcHvcBusReceive/Out1
# combined # Sum: VcCcHvcBusReceive/VcCcHvcBusReceive/Sum */
sVcCcHvcBusReceive_Te_templateSignal = sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal1 +
sVcCcHvcBustest_Bus_TestSignal.Te_BusSignal2;
/* Gain: VcCcHvcBusReceive/Gain1
VcCcHvcBusReceive/Gain1: folded operation multiplication to constant value 0.1 */
rVcCcHvcBusReceive_Z_Version = 0.1F;
}
C header code extract:
#include "udt_CcHvcBusRe.h"
/**************************************************************************************************\
CVC_EXT: CVC external interface input variables | Width: N.A.
\**************************************************************************************************/
CVC_EXT struct sVcCcHvcBustest_Bus_SomeInBus sVcCcHvcBustest_Bus_TestSignal;
In this case, the struct is generated in additional header file. Where "udt" stands for "user defined types".
Example file, udt_CcHvcBusRe.h:
/**************************************************************************************************\
***
*** Simulink model : VcCcHvcBusReceive_OPortMvd
*** TargetLink subsystem : VcCcHvcBusReceive_OPortMvd/VcCcHvcBusReceive
*** Codefile : udt_CcHvcBusRe.h
***
*** Generation date: 2021-03-22 10:48:56
***
*** TargetLink version : 4.3p3 from 16-Oct-2018
*** Code generator version : Build Id 4.3.0.27 from 2018-09-24 17:55:03
\**************************************************************************************************/
#ifndef UDT_CCHVCBUSRE_H
#define UDT_CCHVCBUSRE_H
#include "tl_basetypes.h"
struct sVcCcHvcBustest_Bus_SomeInBus {
Float32 Te_BusSignal1;
Float32 Te_BusSignal2;
}; /* Description: bus inport struct */
#endif /* UDT_CCHVCBUSRE_H */
/*------------------------------------------------------------------------------------------------*\
END OF FILE
\*------------------------------------------------------------------------------------------------*/
The Common Header File
powertrain-build will generate a file named VcStructs.h, which defines all the busses/structs used in the project.
This file can be included if you for instance use a custom VcDummy_spm.c file.