Add STATIC_VAR_TABLE locdata

Add CALLBACK cm_d_pwm_callback
Reserve memory for x, y arrays only once during INIT
This commit is contained in:
Holger Vogt 2022-11-07 12:16:58 +01:00
parent 9bab229e7b
commit 2e064db79a
2 changed files with 59 additions and 64 deletions

View File

@ -19,7 +19,7 @@ MODIFICATIONS
23 Aug 1991 Jeffrey P. Murray
30 Sep 1991 Jeffrey P. Murray
06 Oct 2022 Holger Vogt
SUMMARY
@ -69,7 +69,10 @@ NON-STANDARD FEATURES
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
typedef struct {
double *x;
double *y;
} Local_Data_t;
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
@ -120,6 +123,27 @@ NON-STANDARD FEATURES
==============================================================================*/
static void cm_d_pwm_callback(ARGS,
Mif_Callback_Reason_t reason)
{
switch (reason) {
case MIF_CB_DESTROY: {
Local_Data_t *loc = STATIC_VAR(locdata);
if (loc) {
if (loc->x)
free(loc->x);
if(loc->y)
free(loc->y);
free(loc);
STATIC_VAR(locdata) = loc = NULL;
}
break;
} /* end of case MIF_CB_DESTROY */
} /* end of switch over reason being called */
} /* end of function cm_d_pwm_callback */
/*=== CM_D_PWM ROUTINE ===*/
/*************************************************************
@ -179,15 +203,12 @@ void cm_d_pwm(ARGS)
slope; /* slope value...used to extrapolate
freq values past endpoints. */
int i, /* generic loop counter index */
cntl_size, /* control array size */
dc_size; /* duty cycle array size */
Local_Data_t *loc; /* Pointer to local static data, not to be included
in the state vector (save memory!) */
/**** Retrieve frequently used parameters... ****/
@ -195,7 +216,6 @@ void cm_d_pwm(ARGS)
dc_size = PARAM_SIZE(dc_array);
frequency = PARAM(frequency);
/* check and make sure that the control array is the
same size as the frequency array */
@ -204,10 +224,8 @@ void cm_d_pwm(ARGS)
return;
}
if (INIT) { /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/
/* Allocate storage for internal variables */
cm_analog_alloc(0, sizeof(double));
cm_analog_alloc(1, sizeof(double));
@ -220,15 +238,35 @@ void cm_d_pwm(ARGS)
t3 = (double *) cm_analog_get_ptr(2,0);
/*** allocate static storage for *loc ***/
STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t ));
loc = STATIC_VAR (locdata);
CALLBACK = cm_d_pwm_callback;
x = loc->x = (double *) calloc((size_t) cntl_size, sizeof(double));
if (!x) {
cm_message_send(d_pwm_allocation_error);
return;
}
y = loc->y = (double *) calloc((size_t) cntl_size, sizeof(double));
if (!y) {
cm_message_send(d_pwm_allocation_error);
if(x)
free(x);
return;
}
/* Retrieve x and y values. */
for (i=0; i<cntl_size; i++) {
x[i] = PARAM(cntl_array[i]);
y[i] = PARAM(dc_array[i]);
}
}
else { /*** This is not an initialization pass...retrieve storage
addresses and calculate new outputs, if required. ***/
/** Retrieve previous values... **/
/* assign internal variables */
phase = (double *) cm_analog_get_ptr(0,0);
phase_old = (double *) cm_analog_get_ptr(0,1);
@ -239,9 +277,6 @@ void cm_d_pwm(ARGS)
}
switch (CALL_TYPE) {
case ANALOG: /** analog call **/
@ -250,9 +285,7 @@ void cm_d_pwm(ARGS)
if ( AC == ANALYSIS ) { /* this model does not function
in AC analysis mode. */
return;
}
else {
@ -265,38 +298,17 @@ void cm_d_pwm(ARGS)
}
*phase = *phase / 360.0;
/* set phase value to init_phase */
*phase_old = *phase;
/* preset time values to harmless values... */
*t1 = -1;
*t3 = -1;
}
/* Allocate storage for breakpoint domain & duty cycle range values */
x = (double *) calloc((size_t) cntl_size, sizeof(double));
if (!x) {
cm_message_send(d_pwm_allocation_error);
return;
}
y = (double *) calloc((size_t) dc_size, sizeof(double));
if (!y) {
cm_message_send(d_pwm_allocation_error);
if(x) free(x);
return;
}
/* Retrieve x and y values. */
for (i=0; i<cntl_size; i++) {
x[i] = PARAM(cntl_array[i]);
y[i] = PARAM(dc_array[i]);
}
loc = STATIC_VAR (locdata);
x = loc->x;
y = loc->y;
/* Retrieve cntl_input value. */
cntl_input = INPUT(cntl_in);
@ -346,7 +358,6 @@ void cm_d_pwm(ARGS)
// cm_message_send(d_pwm_positive_dc_error);
}
/* calculate the instantaneous phase */
*phase = *phase_old + frequency * (TIME - T(1));
@ -354,7 +365,6 @@ void cm_d_pwm(ARGS)
the period */
dphase = *phase_old - floor(*phase_old);
/* Calculate the time variables and the output value
for this iteration */
@ -365,8 +375,6 @@ void cm_d_pwm(ARGS)
if(TIME < *t3) {
cm_event_queue(*t3);
}
}
else
@ -380,7 +388,6 @@ void cm_d_pwm(ARGS)
if(TIME < *t1) {
cm_event_queue(*t1);
}
}
else {
@ -395,23 +402,12 @@ void cm_d_pwm(ARGS)
}
*t3 = T(1) + (1 - dphase)/frequency;
}
if(x) free(x);
if(y) free(y);
}
break;
case EVENT: /** discrete call...lots to do **/
test_double = TIME;
if ( 0.0 == TIME ) { /* DC analysis...preset values,
@ -424,7 +420,6 @@ void cm_d_pwm(ARGS)
}
*phase = *phase / 360.0;
/* set phase value to init_phase */
*phase_old = *phase;
@ -433,16 +428,12 @@ void cm_d_pwm(ARGS)
*t3 = -1;
}
/* Calculate the time variables and the output value
for this iteration */
/* Output is always set to STRONG */
OUTPUT_STRENGTH(out) = STRONG;
if( *t1 == TIME ) { /* rising edge */
OUTPUT_STATE(out) = ONE;
@ -471,9 +462,7 @@ void cm_d_pwm(ARGS)
}
}
}
break;
}
}

View File

@ -75,3 +75,9 @@ Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
STATIC_VAR_TABLE:
Static_Var_Name: locdata
Description: "local static data"
Data_Type: pointer