May 21, 2020

Hooks from the simulink servo

We have already talked about how the servo gets started (by a dynamic call to rt_run()) and how it gets triggered to run at 1 kHz (via the registered callback to mmt_mount_connect()). However the running servo needs access to several things, as follows: Looking at the disassembly of el_servo.o, we can learn the following:

The function mdlOutputs() makes a number of calls:

Finding where the model gets the command and encoders is not so straightforward looking at the disassembled code. Interestingly, there are multiple definitions of some symbols like "mdlStart". This is because the object file links together several "models", each of which defines this symbol. They each have a structure with function pointers to keep all of this straight, but that is not readily apparent looking at the disassembled code first hand.

With this in mind, it is worthwhile to look at "mdlOutputs()", of which there are several. Since I defined an encoder block, it became a "model" and its output routine is responsible for returning encoder value(s). And indeed I see a call to mmt_el_encoders() which is in switch.c -- and it is prefixed by a comment:

/* ================================================ */
/* Hooks for the simulink el_encoders S-function */
/* ================================================ */
The function mmt_el_encoders() sends an array of 7 values, which are documented in the afore mentioned comment.

Studying all of the mdlOutputs() routines in the disassembly, I find an unexpected one that calls mmt_params_out(), which is in telem_sv.c. This is apparently part of getting telemetry from the servo which goes into SV files that we can log.

All told there are 4 definitions of mdlOutputs() in the disassembly, as follows:

The mystery of the target value -- solved!

How the servo gets the target value was a dark mystery for some time. The trick is not being fooled by a name. The mmt_el_encoders() routine sends an array of 7 values, and one of these is the target value for the servo! Just because it has the name "encoders" does not mean that it does only that. And I can understand why I would do this. Why set up a whole separate block and S function just for the command value.