How to get correct embedded code generation of Lookup Table?
6 views (last 30 days)
I am trying to get Simulink to generate c-code for a lookup table block via embedded coder. I would like to generate code for only this small section to then schedule within my larger project.
When I go through the process to generate code there are no errors found, however the code generated only controls timing, it does not handle any inputs or outputs.
My question now becomes, what is the minimum necessary components in Simulink to generate code for a lookup table? (Current generated step function is included below)
/* Model step function */
/* Update absolute time for base rate */
/* The "clockTick0" counts the number of times the code of this task has
* been executed. The absolute time is the multiplication of "clockTick0"
* and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
* overflow during the application lifespan selected.
((time_T)(++rtM->Timing.clockTick0)) * rtM->Timing.stepSize0;
/* Update absolute timer for sample time: [0.2s, 0.0s] */
/* The "clockTick1" counts the number of times the code of this task has
* been executed. The resolution of this integer timer is 0.2, which is the step size
* of the task. Size of "clockTick1" ensures timer will not overflow during the
* application lifespan selected.
Andy Bartlett on 21 Aug 2023
My hunch is that Embedded Coder has optimized away code for the specific Lookup Table Block.
One form of optimization is "dead path elimination."
Suppose the ouput of the lookup table block only feeds a Display Block or a Scope Block.
That lookup table instance is "live" for simulation because it has observable effects for a simulation.
But in embedded code, that same lookup instance is "dead code." View only things like Display Blocks and Scope Blocks are not used in the embedded code and are thus dead code. In turn, blocks that only feed "dead code blocks", also become "dead code blocks" too.
Make sure the lookup table instance is feeding a block that will remain "live" in the embedded code. For example, if the lookup table block feeds a root level outport, then Embedded Coder will keep that lookup table "live" in the generated code.
Embedded Coder also does deeper analysis to determine what is dead and optimize away the dead stuff. For example, suppose Embedded Coder determines that the middle input to a switch block is always true and thus the third input will never be used. Blocks that only feed that third switch input would be "dead code."
Another form of optimization is "constant folding".
Suppose there is a series of 10 stateless blocks fed by a (non-tunable) Constant Block. Embedded Coder will optimize away the calculations of those 10 blocks and just generate a constant value for the last block in the series. So if a lookup table block was in this series, you would not see any lookup table code. If the input to the lookup was variable, then you would see the generated code for the lookup table.
To see blocks that are potentially constant folded, turn on display of Sample Times colors. Blocks that are magenta color may be constant folded, unless a tunable parameter is driving those blocks.