当前位置:网站首页>2837xd code generation - Supplement (2)
2837xd code generation - Supplement (2)
2022-07-02 09:43:00 【Quikk】
2837xd Code generation —— Add (2)
- 5 The basic process of model-based code generation (MDB)
5 The basic process of model-based code generation (MDB)
First, build the following Simulink Model :

Because code generation generally only supports discrete fixed step , So the parser needs to be set accordingly . The basic setting process is the same as that described above . After generating the code , Click on C CODE You can quickly locate the generated code statements :

And then there is Report There will also be interactive probes , But my problem can't be shown , Now I can't find the reason .

5.1 Compilation process
The compilation process is as follows : First, the user builds Simulink Model , After the model is compiled, it will generate **.rtw file ..TLC**(Target Language Compiler) The file will call **.rtw And then generate .c and .h** file .
.rtw The file mainly writes the name, size and value of the resource , Be similar to .h file , Make a warehouse declaration . Tell the program what's in it , What can be used .
.TLC It can be well parsed **.rtw** The content in , And then generate the appropriate code .
Code generation type :

5.1.1 TLC Language
1) Basic syntax and data types
%<> Is to extract the value of a variable
%assign str="today" %% Define string
%assign tr =TLC_TRUE
%assign tr2 =TLC_FALSE
%warning Hello Word %<str> or %<tr> %% Output statement
%error Hello Word %<str> %% Error prompt statement
%trace Hello Word %<str> %% You have to use tlc xxx.TLC -v function ( Debugging use )
%if ISEQUAL(tr,1) %%if sentence
%warning Hello Word %<str>
%else
%warning good %<str>
%endif
%assign data=[1,2,3,4] %% Array , Data must be separated by commas ( Cannot be separated by spaces )
%switch TYPE(data) %%switch sentence
%case "Number"
%warning data is Number
%break
%case "String"
%warning data is String
%break
%case "Vector"
%warning data is Vector
%break
%case "Matrix"
%warning data is Matrix
%break
%case "Real"
%warning data is Real
%break
%case "Real32"
%warning data is Real32 %%Real For floating point type , There are many types
%break
%endswitch
2) Loop statement
%assign data=[1,2,3,4]
%foreach idx=5 %% Loop statement
%if ISEQUAL(idx,3) %%if sentence
%continue
%endif
%warning data[%<idx>] = %<data[idx]>
%endforeach
%% Left middle 1 Position is the cyclic judgment bit , if 1 Then execute all loops once (iden2=3 Also execute )
%% If it is zero, execute body The sentence between ( Execution times are iden1),iden2=3 Don't execute
%for iden1 = 5,1,iden2=3
%warning start
%body
%warning data[%<iden1>] = %<data[iden1]>
%endbody
%warning over
%endfor
3) Matrix operations
%assign mat=[["A","B"],["A","B"],[6U,"B"]]
%foreach idx=size(mat,0) %% How many... Please [],
%foreach idx2=size(mat,1) %% Please, everyone [] How many elements are there in
%warning mat[%<idx>][%<idx2>] = %<data[idx][idx2]>
%endforeach
%endforeach
4) Data flow control ( write file ), In this way, a .c file . You can know that the code is basically generated in this way, and the automated script writes some variables ( The frame has been fixed ).
%assign str="today"
%assign func_name="main"
%assign return_name="void"
%assign arg_name="void"
%openfile buf ="mytest.c"
#include "stdio.h"
%<return_name> %<func_name>(%<arg_name>)
{
printf("Hello World");
printf("%<str>");
}
%closefile buf
5)record( Similar to a structure )
%%create
%createrecord NEW_RECORD{
Name "author";Age 25}
%warning %<NEW_RECORD.Name>
%%add
%addrecord NEW_RECORD School CJ %% Additional data
%warning %<NEW_RECORD.School>
%%merge
mergerecord NEW_RECORD1 NEW_RECORD1 %% Put two record Merge into NEW_RECORD1 in
%%copy
%createrecord NEW_RECORD3{
}
%copyrecord NEW_RECORD3 NEW_RECORD2 %% take NEW_RECORD2 Copy the value of to NEW_RECORD3 in
%%delete
%undef NEW_RECORD1 %% Delete
%with NEW_RECORD1 %% The following statements are limited to NEW_RECORD1 Intermediate reading and writing
%undef School %% In this way, internal members can be deleted
%endwith
%with NEW_RECORD1.SUB %% The following statements are limited to NEW_RECORD1 Intermediate reading and writing ( If in NEW_RECORD1 There is SUB Substructure )
%undef School %% So you can delete SUB Internal members
%endwith
6) File stream data is appended
%openfile buf = "text.txt"
//This is a text
%openfile buf1 ="text.c"
%selectfile buf
//add text.txt
%selectfile buf1
//add text.c
%selectfile STDOUT
//This is std %% Be similar to cout Output to Command Window in
%selectfile NULL_FILE %% Do not display ( Generally, it starts as a function )
//NULL FILE
%closefile buf
%closefile buf1
7)TLC Function writing
%selectfile NULL_FILE
%function hex2dec(hexnum) void %%void No return output return
%assign hexnum = FEVAL("regexprep",hexnum,"0x",""); %% call matlab function regexprep, In the string 0x Just delete
%warning hexnum = %<hexnum>
%assign decnum = FEVAL("hex2dec",hexnum)
%assign decnum = CAST("Number",%<decnum>)
%warning decnum = %<decnum>
%return decnum
%endfunction
call :
%assign a = hex2dec("0x5f")
- Code generation instance ( Write in the file func_gen.tlc in )
%selectfile NULL_FILE
%function code_gen(filename,ret,funcname,body,argu_list) Output
%openfile buf ="%<filename>"
#include <math.h>
%<ret> %<funcname>(%<argu_list>)
{
%<body>
}
%closefile buf
%endfunction
call :
%include "func_gen.tlc"
%createrecord codegen_rec{
ret "float";...
funcname "my_calcu";...
argument "int a";...
filename "calculate.c";...
body "float a;\n b=sin(a);\n return b;"..
}
%<code_gen(codegen_rec.filename,codegen_rec.ret,codegen_rec.funcname,codegen_rec.body,codegen_rec.argument)>
TLC file , It is not recommended by the government to write by yourself , Unskilled writing will lead to code generation failure , But we can learn to read it . But use c—mex When encapsulating your own module , You must write your own module level TLC.
5.2 System default ert.tlc Generate code structure
The generation module structure can be divided into the following parts :
1) External input :struct:model_U(model by simulink The name of the document , I won't go over it again )
2) modular I/O:struct:model_B
3) External output :struct:model_Y
4) Module state variables :struct:model_X
5) Module parameters :struct:model_P
6) Module intermediate variables ( working space ):struct:rtRWork、rtIWork、rtPWork、rtDWork
5.3 Optimize code generation
The first optimization scheme is explained in the previous example :
1) Give our named value to the signal line that needs to be optimized . Here is the record before optimization step expression :
coder_test_Y.Out1 = coder_test_P.Constant_Value * coder_test_U.in;
The goal is optimized to :
Out = 10 * in;

2) Select the signal line and select Properties.

3) Enter the option box (Code Generation-Storage class Is shown in the figure ), Change here to global variable , The structure will no longer be used for inclusion .

4) Here we need to have a clear understanding , In the model in And out Belongs to variable , and 10 It belongs to constant . For constant setting, you need to go to Configuration Parameters Set in .

5) Generate the code again :

It can be found that the target requirements have been met . Here is the second way to add , Before starting, add a gain:

1) First, replace all constants with expressions :

2) Get into Command Window Make the relevant configuration : Type the following statements respectively
k_constant=Simulink.Parameter;
k_gain=Simulink.Parameter;
in=Simulink.Signal;
out=Simulink.Signal;
Here are the constants and signals respectively Simulink Structure , Its kind Parameter Is the class of defined parameter type .

here Parameter Give an example to illustrate :
I、 Signal line configuration

II、Parameter To configure

Then enter Simulink Configure the signal line : Check the box shown in the above figure box The other signal lines have exactly the same configuration .

After marking, the signal sign will appear :

Then generate the code again :

It can be found that the readability is enhanced compared with that before .
notes :Storage Class There are also many data types in , You can try the data type by yourself .
5.4 Different Storage Class Generate differences
Signal The type of
1)Default(Custom): And Global Similar effect , Generate global variables .
2)BitField(Custom): You can generate customized structures ( The structure name can be customized ).
3)Volatile(Custom): You can generate customized header files and source files (.c And .h file ), And declare in this document Volatile Type variable .
4)Const(Custom): You can generate customized header files and source files (.c And .h file ), And declare in this document Const Type variable .
5)ConstVolatile(Custom): You can generate customized header files and source files (.c And .h file ), And declare in this document ConstVolatile Type variable .
6)ExportToFile(Custom): You can generate customized header files and source files (.c And .h file ), And declare variables in this file .
7)ImportFromFile(Custom): You can choose variables from user-defined files ( You need to give your own file )
8)FileScope(Custom): Static variables , Can only be accessed in the current file .
9)Struct(Custom): And BitField(Custom) The effect is the same , however BitField(Custom) Bits can be generated bianl( Boolean type ).
10)Reusable(Custom): Reuse type variables , All belong to Reusable(Custom) Variables of type will define only one variable .
Parameter Compare with Signal Multiple types
11)Define(Custom): Macro definition parameters
12)CompilerFlag: Generate a preprocessing statement .
#ifndef k3
#error error
#endif
There is still one left GetSet The type has no description ,GetSet Type needs to be given a GetFunction And SetFunction in .

Here you can give a usage scenario , That is, read and write GPIO Corresponding value : Then you need to give GPIORead And GPIOWrite Function to read and write respectively GPIO Value . Because in DSP You need a function to read this function correctly , So you need to use methods to call , It's kind of similar here C++ Private properties in need to provide the same concept as interfaces for access .
Build the following block diagram from scratch :

Of this block diagram var representative GPIO Value , You need to call statements and read and write ,var The type of is set as follows :

Store in the model directory GPIO.h And GPIO.c file :

Then we need to pay attention to that it must be in Configuration Parameter Add a statement to , If you don't join, you will report an error. You can't find two functions . I read this official demos I know :

then DEBUG Just fine . You can see that the generated code will GPIO After reading the value of , Zoom in again 15 Times write back .

5.5 Data type alias
Simulink Macro definitions have been made for some data types in (rtwtypes.h In file ):
typedef double real_T;
typedef double time_T;
typedef unsigned char boolean_T;
typedef int int_T;
typedef unsigned int uint_T;
typedef unsigned long ulong_T;
typedef char char_T;
typedef unsigned char uchar_T;
typedef char_T byte_T;
In use , We can define type aliases ourselves , Increase code readability :
1) Configure after entering instructions

2)Data Scope It is divided into import and Export ,Base type You can choose to typedef Data type of , For example, here is the use of a Defined double type .
This is a type of substitution , Often we need to carry out multiple types of substitution :
stay Configuration Parameter Of Code Generation Under the Data Type Replacement Define :

After definition, you still need to put these aliases in Workspace Defined in , Just like the first one :
// Model callback function
k_constant=Simulink.Parameter;
k_constant.Value=10;
k_constant.CoderInfo.StorageClass='ExportedGlobal';
k_gain=Simulink.Parameter;
k_gain.Value=1.5;
k_gain.CoderInfo.StorageClass='ExportedGlobal';
in=Simulink.Signal;
in.CoderInfo.StorageClass='ExportedGlobal';
out=Simulink.Signal;
out.CoderInfo.StorageClass='ExportedGlobal';
var=Simulink.Signal;
var.StorageClass='GetSet'
var.CoderInfo.CustomAttributes.HeaderFile='GPIO.h';
var.CoderInfo.CustomAttributes.GetFunction='GPIORead';
var.CoderInfo.CustomAttributes.SetFunction='GPIOWrite';
my_double=Simulink.AliasType;
my_double.BaseType='double';
my_single=Simulink.AliasType;
my_single.BaseType='single';
my_int32=Simulink.AliasType;
my_int32.BaseType='int32';
my_int16=Simulink.AliasType;
my_int16.BaseType='int16';
These can be quickly written in the callback function of the model by using scripts , Automatically write when the model is loaded . The generated code is as follows :

5.6 example (Clark Transformation )
First, build the Clark Transform the model :

Input 50Hz Three phase AC test :

You can see that the output time difference is 0.005s, So the corresponding phase difference is 0.005/0.02*(2*pi)=90°. therefore Clark The algorithm meets the requirements , The following code generation .
First define the input and output of the signal line , The type set here is ExportedGlobal.

Then set the sub module , Check the setting page number Treat as atomic unit, Here is to make the whole module as an atom ( Have a sampling frequency ).

There are three options in the code generation interface :1)Inline 2)Nonreusable function( Non reusable ) 3)Reusable function( Can be reused )

1)Inline Schema generation code :

You can see that the code is directly generated in step Internal function , No encapsulation .
2)Nonreusable function Schema generation code , Set the following parameters :

Function interface Is to set whether the function is allowed to take parameters . Here, an error is reported in the generation process , Need to put Compact Change the mode to Modular.
Generate effect :


You can see Clark The module is packaged separately , But because it is a variable, the corresponding parameters are not generated , Change variables into model parameter variables , You can generate functions with parameters .
3)Reusable function Schema generation :
When a module needs to be in Simulink When used in , It has to be set to Reusable function Pattern to generate code , Otherwise you will report an error .
Don't use reusable function Multiple codes will be generated , It is not conducive to code reuse :


Used reusable function after , Will reuse a function file . This is in the process of code generation Need to be flexible .

5.7 With pretreatment C Code generation
#if
#endif
The above is the preprocessing statement .
Simulink Provides a module that can generate preprocessing code :Variant Model.

As shown in the figure below , You can edit it in the attribute interface of this module , there var The value of the variable can be in CommandWindow Assignment in . When given var=1 when , You can see the internal situation of the module ( Grey means that the condition cannot be fulfilled , The explanation is very clear out And in Do not connect to the module , The default connection has been made for the system ):

Then, when generating code , All sub modules must be set as atomic sub modules . The effect of generated code is shown in the following figure ( It has an obvious conditional compilation structure ):

5.8 Enumeration variable type creation
Matlab Not only does it support program oriented languages , It also supports object-oriented languages , The creation of enumeration type is the development using object-oriented language :
classdef week <Simulink.IntEnumType
enumeration
Sun(0)
Mon(1)
Tue(2)
Wed(3)
Thu(4)
Fri(5)
Sat(6)
end
end
Organization m The script content is as above , Put it in a unified directory with the model , The enumeration type is defined week.
structure Simulink The model is shown in the figure below :

Generated code can be observed , Created enumeration type .Matlab The object-oriented language of is also relatively rich .

边栏推荐
- 2837xd 代码生成——StateFlow(1)
- Microservice practice | Eureka registration center and cluster construction
- Typora安装包分享
- TD conducts functional simulation with Modelsim
- Chrome video download Plug-in – video downloader for Chrome
- Typora installation package sharing
- 每天睡觉前30分钟阅读_day3_Files
- Elastic Stack之Beats(Filebeat、Metricbeat)、Kibana、Logstash教程
- TD联合Modelsim进行功能仿真
- Machine learning practice: is Mermaid a love movie or an action movie? KNN announces the answer
猜你喜欢

2837xd code generation - stateflow (4)

QT QLabel样式设置

2837xd 代码生成——补充(1)

Web security and defense

Elastic Stack之Beats(Filebeat、Metricbeat)、Kibana、Logstash教程

图像识别-数据增广

Say goodbye to 996. What are the necessary plug-ins in idea?

Bold prediction: it will become the core player of 5g

Customize redis connection pool

idea查看字节码配置
随机推荐
2837xd 代码生成——补充(2)
Idempotent design of Internet API interface
MySQL事务
Int to string, int to qstring
Tools used for Yolo object recognition and data generation
ZK configuration center -- configuration and use of config Toolkit
Mysql默认事务隔离级别及行锁
Customize redis connection pool
Who is better for Beijing software development? How to find someone to develop system software
Image recognition - data augmentation
JDBC review
cmake的命令-官方文档
Difference between redis serialization genericjackson2jsonredisserializer and jackson2jsonredisserializer
图像识别-数据清洗
Matplotlib swordsman - a stylist who can draw without tools and code
How to choose between efficiency and correctness of these three implementation methods of distributed locks?
Bold prediction: it will become the core player of 5g
Navicat 远程连接Mysql报错1045 - Access denied for user ‘root‘@‘222.173.220.236‘ (using password: YES)
Discussion on improving development quality and reducing test bug rate
C语言之数据插入