Я разрабатывал блок в Scilab/Xcos (вариант Matlab/Simulink с открытым исходным кодом) с использованием языка C. Для этой цели Scilab/Xcos предлагает специальный блок под названием CBLOCK4. Как только я помещаю этот блок в симуляцию, автоматически генерируется заглушка языка C. Часть этой заглушки является шаблоном для функции, реализующей поведение блока. Эта функция принимает среди своих параметров указатель на структуру scicos_block
:
typedef struct {
int nevprt;
voidg funpt ;
int type;
int scsptr;
int nz;
double *z;
int noz;
int *ozsz;
int *oztyp;
void **ozptr;
int nx;
double *x;
double *xd;
double *res;
int nin;
int *insz;
void **inptr;
int nout;
int *outsz;
void **outptr;
int nevout;
double *evout;
int nrpar;
double *rpar;
int nipar;
int *ipar;
int nopar;
int *oparsz;
int *opartyp;
void **oparptr;
int ng;
double *g;
int ztyp;
int *jroot;
char *label;
void **work;
int nmode;
int *mode;
} scicos_block;
Пункт work
, вероятно, предназначен для хранения адреса, по которому хранится другой адрес, по которому хранятся внутренние переменные состояния блока. Я попытался реализовать блок Scilab/Xcos с использованием элемента work
:
#include "scicos_block4.h"
#define U ((double *)GetRealInPortPtrs(block, 1))
#define Y ((double *)GetRealOutPortPtrs(block, 1))
// parameters
#define Tu (GetRparPtrs(block)[0])
#define Td (GetRparPtrs(block)[1])
#define T (GetRparPtrs(block)[2])
void Ramp(scicos_block *block, int flag)
{
double *target;
double *inputDelta;
double *out;
if(flag == 4)
{
/* init */
if((*(block->work) = (double *)scicos_malloc(sizeof(double)*3)) == NULL)
{
set_block_error(-16);
return;
}
target = (double*)(*(block->work));
inputDelta = (double*)(*(block->work + 1));
out = (double*)(*(block->work + 2));
*target = 0;
*inputDelta = 0;
*out = 0;
}
else if(flag == 1)
{
/* output computation */
if(U[0] != *target)
{
*target = U[0];
if(*target - Y[0] < 0)
{
*inputDelta = Y[0] - *target;
}
else
{
*inputDelta = *target - Y[0];
}
}
if(*target > Y[0])
{
*out += *inputDelta*T/Tu;
if(*out > *target)
{
*out = *target;
}
}
else if(*target < Y[0])
{
*out -= *inputDelta*T/Td;
if(*out < *target)
{
*out = *target;
}
}
Y[0] = *out;
}
else if (flag == 5)
{
/* ending */
scicos_free(*(block->work));
}
}
Я могу успешно скомпилировать блок, содержащий этот код, но если я начну симуляцию, произойдет сбой. У меня есть сомнения относительно динамического распределения памяти и того, как я с ней работаю.
Пожалуйста, кто-нибудь может взглянуть на мой код (а именно на часть в теле if с флагом == 4) и сказать мне, что я делаю неправильно?