Simulink中的循环缓冲区 [英] Circular Buffer in Simulink

查看:520
本文介绍了Simulink中的循环缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在纯Simulink模型中实现一个非常大的(10 ^ 6个元素-固定大小)循环缓冲区(没有其他工具箱,没有S函数)。

I would like to implement a very huge (10^6 Elements - fixed size) circular buffer in pure Simulink model (no further toolboxes, no S-Function).

在某些时候,我需要阅读一些元素(任何地方,而不仅仅是开始或结束)。

At some points I need to read some elements (anywhere, not just begin or end).

我无法使用以下解决方案:

The following solutions I can not use:


  1. 队列块或缓冲区块(我没有信号处理工具箱)

  2. 离散延迟(我需要一个巨大的缓冲区,并且不会在模型中放置10 ^ 6延迟)

  3. 模拟事件(我需要从该模型生成代码

  1. "Queue Block" or "Buffer Block" (I have no Signal Processing Toolbox available)
  2. "Discrete Delay" ( I need a hugh buffer and will not place 10^6 delays into the model)
  3. "Sim Events" (I need to generate code from this model)

我尚未尝试的 S-Function,我正在寻找

The "S-Function" I tried not yet, and I am looking for an alternative solution.

您知道什么进一步的方法?

What further approach do you know?

推荐答案

首先,让我称赞您对纯Simulink的追求!这是完全有可能的,但是,Mathworks代码生成器无法处理此用例。它非常草率,并创建整个队列的缓冲副本。例如:

First, let me compliment you on your quest for pure Simulink! This is quite possible, however, the Mathworks code generator does not handle this use case. It is extremely sloppy and creates a buffered copy of the entire queue. Here's an example:



然后,看一些代码。

/* Model output function */
static void queue_output(int_T tid)
{
  {
    real_T rtb_MathFunction;

    /* DataStoreRead: '<S1>/Data Store Read' */
    memcpy((void *)(&queue_B.DataStoreRead[0]), (void *)(&queue_DWork.A[0]),
           100000U * sizeof(uint16_T));

    /* Outport: '<Root>/Out1' incorporates:
     *  DataStoreRead: '<S1>/Data Store Read1'
     *  Selector: '<S1>/Selector'
     */
    queue_Y.Out1 = queue_B.DataStoreRead[(int32_T)queue_DWork.idx];

    /* If: '<Root>/If' incorporates:
     *  ActionPort: '<S2>/Action Port'
     *  Constant: '<Root>/Constant'
     *  SubSystem: '<Root>/WriteToQueue'
     */
    if (queue_P.Constant_Value > 0.0) {
      /* DataStoreRead: '<S2>/Data Store Read3' */
      memcpy((void *)(&queue_B.Assignment[0]), (void *)(&queue_DWork.A[0]),
             100000U * sizeof(uint16_T));

      /* Math: '<S2>/Math Function' incorporates:
       *  Constant: '<S2>/Constant1'
       *  Constant: '<S3>/FixPt Constant'
       *  DataStoreRead: '<S2>/Data Store Read2'
       *  Sum: '<S3>/FixPt Sum1'
       */
      rtb_MathFunction = rt_mod_snf(queue_DWork.idx +
        queue_P.FixPtConstant_Value, queue_P.Constant1_Value);

      /* Assignment: '<S2>/Assignment' incorporates:
       *  Constant: '<S2>/Constant'
       */
      queue_B.Assignment[(int32_T)rtb_MathFunction] = queue_P.Constant_Value_h;

      /* DataStoreWrite: '<S2>/Data Store Write' */
      memcpy((void *)(&queue_DWork.A[0]), (void *)(&queue_B.Assignment[0]),
             100000U * sizeof(uint16_T));

      /* DataStoreWrite: '<S2>/Data Store Write1' */
      queue_DWork.idx = rtb_MathFunction;
    }
  }

Memcpy 10000 uint16的每个循环!在Mathworks以健壮的方式解决此问题之前,这里是需要硬编码索引的初始尝试,S函数是唯一的方法。

Memcpy 10000 uint16's every loop! Until the Mathworks address this issue in a robust manner, here's an initial attempt that requires hard coding indices, S-Functions are the only way.

这篇关于Simulink中的循环缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆