06-20-2017 08:25 AM
Hi,
I am trying to write a model in C starting from template.c, which is provided, and based on sinewave.c.
I had a couple of questions.
1. This is more curiosity than functionality. The macro DataSection is used in a number of places in both ni_modelframework.c and template.c with string parameters, for example DataSection(".NIVS.numtasks"). In ni_modelframework.h, this is defined as an empty macro. Is this macro used for documentation purposes? If so, I was curious how it is used.
2. What are the values for the "datatype" component of structs such as NI_Parameters, NI_Signals etc. I recognize that double is 0, since rtDBL is defined as 0 in sinewave.c. The comment for this component says "/* integer describing a user defined datatype. Must have a corresponding entry in GetValueByDataType and SetValueByDataType */". What are GetValueByDataType and SetValueByDataType?
Thank you.
Siva
Solved! Go to Solution.
06-20-2017 03:41 PM
I now realize that for my second question above, "datatype" as actually user defined, i.e. the values used to set up the NI_Parameter, NI_ExternalIO etc. structs must be consistent with USER_SetValueByDataType and USER_GetValueByDataType.
I only have my question 1 above.
Thank you.
Siva
06-20-2017 04:49 PM - edited 06-20-2017 04:55 PM
Hi Siva,
Your understanding of the "datatype" is correct. The DataSection is used to identify sections of code for non-Win32 binaries. We use these sections to collect state information for libraries in which we cannot execute their code to collect such information. This state information is retrieved at configuration time such as by System Explorer. Consider them as specific markers. Note that these markers are however not used at runtime by their native Operating System; instead, the corresponding entry is called. You may choose to remove these DataSections if you are only building Windows\PharLAP binaries (Win32 DLL).
06-20-2017 08:17 PM
Hi Nestor,
Thank you.
Siva
06-20-2017 10:59 PM
A follow up question, wasn't sure if this belonged in this thread or in a new one.
I noticed that of the many function declared as DLL_EXPORT in ni_modelframework.h (I am guessing this in the "interface" for the Veristand Engine to work with the model), there are four functions that are not defined in ni_modelframework.c
1. NIRT_PostOutputs
2. NIRT_GetSimState
3. NIRT_SetSimState
4. NIRT_GetTaskSpec
Why are these not defined?
Two of these functions, NIRT_GetSimState and NIRT_SetSimState are defined in the example, sinwave.c; why?
Thank you.
Siva
06-21-2017 10:17 AM
NIRT_PostOutputs and NIRT_GetTaskSpec are both interfaces for multi-rate models. A single-rate model (all of our examples) has one task to execute. This task is executed at each each model time step. A multi-rate model has two or more tasks. The tasks are executed at a decimated rate of the base task. Note that we do not provide a scheduler for the multi-rate models; instead we are simply given a list of tasks to execute by a model for a given time step. This feature is primarily used by MathWorks Simulink generated models. You may ignore these functions.
The NIRT_Get/SetSimState are used by the Pause/Resume Model feature in VeriStand. The sinewave example is simply showing how to make use of this function, but the implementation is unnecessary if there is intent to use the Pause/Resume model feature in VeriStand.
06-21-2017 11:49 AM - edited 06-21-2017 11:51 AM
Thank you.
A further question about setting up the rtParamAttribs struct.
I have the following in model.h:
#ifndef MODEL_h # define MODEL_h #define NCHAN 4 #define SAMPLE_DT 0.0009765625 typedef struct { double amp[NCHAN]; double freq[NCHAN]; } Parameters; #endif
and the following code to set up rtParamAttributes:
int32_t ParameterSize DataSection(".NIVS.paramlistsize") = 2; NI_Parameter rtParamAttribs[] DataSection(".NIVS.paramlist") = { {0, "MCSineGen/Amplitude", offsetof(Parameters, amp), rtDBL, NCHAN, 1, 0, 0}, {0, "MCSineGen/Frequency", offsetof(Parameters, freq), rtDBL, NCHAN, 1, 1, 0} }; int32_t ParamDimList[] DataSection(".NIVS.paramdimlist") = { NCHAN, /* MCSineGen/Amplitude */ NCHAN /* MCSineGen/Frequency */ };
I expect both parameters "Amplitude" and "Frequency" to be NCHANx1 arrays. But when I import in the model in System Explorer, Amplitude shows up as NCHANxNCHAN, while frequency shows up as NCHANx1. I wonder what I am doing wrong.
Thank you.
06-21-2017 08:08 PM
I get the desired behavior if I did the following instead (set each parameter as a 2D NCHANx1 array).
int32_t ParameterSize DataSection(".NIVS.paramlistsize") = 2; NI_Parameter rtParamAttribs[] DataSection(".NIVS.paramlist") = { {0, "MCSineGen/Amplitude", offsetof(Parameters, amp), rtDBL, NCHAN, 2, 0, 0}, {0, "MCSineGen/Frequency", offsetof(Parameters, freq), rtDBL, NCHAN, 2, 2, 0} }; int32_t ParamDimList[] DataSection(".NIVS.paramdimlist") = { NCHAN, 1, /* MCSineGen/Amplitude */ NCHAN, 1 /* MCSineGen/Frequency */ };
03-05-2021 11:03 PM - edited 03-05-2021 11:04 PM
Hi Guys,
I have another question in this regard. I'm working on a model development in C++ environment, so in the workspace can I add some additional source files excluding nimodeframework.c and model.cpp? Because I have some external files where complex structures are defined and they're being called for processing the data. Please give your thoughts it would be really helpful
Regards,
Madan Mohan
08-26-2022 06:05 PM
Hello Madan Mohan,
You have likely figured this out my now.
In any case, you can build with other header and source files. The only requirement is that all the callback functions Initialize, Start, TakeOneStep, Finalize are implemented.
hope this helps.
Siva