【问题标题】:How to develop own block in Scilab/Xcos with C language usage如何使用 C 语言在 Scilab/Xcos 中开发自己的块
【发布时间】:2020-09-25 07:14:47
【问题描述】:

我一直在使用 CBLOCK4 在 Scilab/Xcos 中开发自己的块。 块内的C语言代码如下:

#include <stdio.h>
#include "scicos_block4.h"

#define U  ((SCSREAL_COP *)GetRealInPortPtrs(block, 1))
#define Y  ((SCSREAL_COP *)GetRealOutPortPtrs(block, 1))
#define X  ((SCSREAL_COP *)GetState(block))
#define dX ((SCSREAL_COP *)GetDerState(block))
#define Xk ((SCSREAL_COP *)GetDstate(block))
#define W  ((SCSREAL_COP *)GetWorkPtrs(block))

// parameters
#define N (GetIparPtrs(block)[0])

typedef struct
{
    double *buffer;
    double *sum;
    int    *index;
}MovingAverage_t;

FILE *f;

void MovingAverage(scicos_block *block,int flag)
{

  MovingAverage_t *ptr;
  int bufferPos;

  if(flag == 4) 
  {
    /* init */

    f = fopen("Debug.txt", "w");

    if((*(block->work) = (MovingAverage_t *)scicos_malloc(sizeof(MovingAverage_t))) == NULL)
    {
        set_block_error(-16);
        return;
    }
    ptr = (MovingAverage_t*)*block->work;       

    fprintf(f, "ptr: %ld \n", ptr);

    if((ptr->buffer = (double*)scicos_malloc(sizeof(double)*N)) == NULL)
    {
        scicos_free(*(block->work));
        fclose(f);
        set_block_error(-16);
        return;
    }
    
    if((ptr->sum = (double*)scicos_malloc(sizeof(double))) == NULL)
    {
        scicos_free(*(ptr->buffer));
        scicos_free(*(block->work));
        fclose(f);
        set_block_error(-16);
        return;
    }

    if((ptr->index  = (int*)scicos_malloc(sizeof(int))) == NULL)
    {
        scicos_free(*(ptr->buffer));
        scicos_free(*(ptr->sum));
        scicos_free(*(block->work));
        fclose(f);
        set_block_error(-16);
        return;
    }

    fprintf(f, "ptr->buffer: %ld \n", ptr->buffer);
    fprintf(f, "ptr->sum: %ld \n", ptr->sum);
    fprintf(f, "ptr->index: %ld \n", ptr->index);

    int i;
    for(i = 0; i < N; i++)
    {
        ptr->buffer[i] = 0;
    }
    *(ptr->sum) = 0;
    *(ptr->index) = 0;

    for(i = 0; i < N; i++)
    {
        fprintf(f, "buffer[%d]: %f\n", i, ptr->buffer[i]);
    }

    fprintf(f, "*(ptr->sum): %f\n", *(ptr->sum));
    fprintf(f, "*(ptr->index): %d\n", *(ptr->index));
        
  }
  else if(flag == 1) 
  {
    fprintf(f, "In: %f \n", U[0]);  

    ptr->buffer[0] = U[0];

    int i;
    for(i = 0; i < N; i++)
    {
        fprintf(f, "buffer[%d]: %f\n", i, ptr->buffer[i]);
    }
    
  } 
  else  if (flag == 5) 
  {
    /* ending */
    scicos_free(*(block->work));
    fclose(f);
  }
}

为了完整起见,我还附上了 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 *xprop;
    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;
    char *uid;
}scicos_block;

我能够成功编译代码,但如果我运行包含以下内容的模拟 我的 CBLOCK4 块我总是收到以下错误消息:

警告!!! Scilab 发现了一个严重错误 (EXCEPTION_ACCESS_VIOLATION) 具有“scicosim”功能。 保存您的数据并重新启动 Scilab。

并且模拟也不会开始。我发现如果我删除 CBLOCK4 块内的以下代码行,模拟就会开始工作:

ptr->buffer[0] = U[0];

int i;
for(i = 0; i < N; i++)
{
    fprintf(f, "buffer[%d]: %f\n", i, ptr->buffer[i]);
}

我怀疑我的 C 代码中有一些错误(可能与内存有关 分配),但我找不到。有人对 Scilab/Xcos 有经验吗 CBLOCK4 用法?

【问题讨论】:

  • 多么大的结构啊!看起来是重复的(xblock、zblock、parblock等等),为什么不提取公共部分呢?
  • @KamilCuk 谢谢你的反应。该结构是我无法影响的 API 的一部分。乍一看我的代码有什么问题吗?

标签: c memory-management scilab xcos


【解决方案1】:

我体验到在 cblock4 上获得好的信息/示例可能非常困难,但经过大量谷歌搜索后,我现在使用以下实现缓冲区(采用实数,输出 N 个最后样本的向量):

#include "scicos_block4.h"

#define r_IN(n, i)  ((GetRealInPortPtrs(block, n+1))[(i)]) 
#define r_OUT(n, i) ((GetRealOutPortPtrs(block, n+1))[(i)]) 

#define in          (r_IN(0, 0))                // input, single real
#define out(n)      (r_OUT(0, n))               // output, vector(1,N) real
#define nSamples    (GetOutPortSize(block, 1, 2))

#define setting0    (GetIparPtrs(block)[0])
#define X           (GetState(block)[0])        // state 
#define Xdot        (GetDerState(block)[0])     // derivative of the state 
#define surface0    (GetGPtrs(block)[0]) 
#define mode0       (GetModePtrs(block)[0]) 
#define wrk(i)      (((double*)GetWorkPtrs(block))[i])

void buffer(scicos_block *block, int flag)
{
    int i;
    switch(flag){
        case 0:            // calculate derivative
            break;
        case 1:            // calculate output
            for(i=1; i<nSamples; i++) out(i-1)=out(i);
            out(nSamples-1)=in;
            break;
        case 2:            // update states
            break;
        case 3:            // event
            break;
        case 4:            // init
            break;
        case 5:            // done, deinit
            break;
        case 6:            // re-initialization
            break;
        case 9:            // calculate surfaces and modes
            break;
    }
}

注意没有malloc,它只是将输出用作缓冲区...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多