【问题标题】:Represent C struct of pointers using Simulink Bus使用 Simulink Bus 表示 C 指针结构
【发布时间】:2015-05-23 01:50:01
【问题描述】:

如何将 C 指针结构与 Simulink.Bus 关联?

假设我有 C 结构:

typedef struct 
{
    int32_T *a;
    uint8_T *b;
} Bus_X ;

那么对于Simulink.Bus.objectToCell

 { ...
           'Bus_X', ...
           'Bus.h', ...
           sprintf(''), ...
           'Imported', {...
           {'a', 1, '???', -1, 'real', 'Sample', 'Fixed'}; ...
           {'b', 1, '???', -1, 'real', 'Sample', 'Fixed'}; ...
           } ...
 } ...

'???'应该是什么

我想像在外部 C 代码中那样使用它

Bus_X x_data = { &a_sig, &b_sig  };
Bus_X* x_ptr = &x_data;

x_ptr 在 Simulink Signal 上将是 ImportedExternPointer

那么,如果可能的话,Simulink 应该在生成的代码中发挥神奇的作用,例如:

*(x_ptr->a) = 42.0 ;

【问题讨论】:

    标签: c matlab simulink


    【解决方案1】:

    可以在 Simulink Buses 中处理指针,这些指针可以在 C 中生成的代码或 S-Function 中使用,而不是在纯 Simulink 中。

    最后一个,我觉得simulink有个范式:从输入到输出的数据流。指针提供了将数据从输出总线向后设置到模块的可能性。这是不希望的,因此首先不支持总线中的指针。但是对于 C 环境中的解决方案,指针可能是一个兴趣点。

    在头文件中你应该定义一个联合:

    typedef struct MyBus_t { union { int32 myRefBus_int[2]; MyRefBus* myRefBus; } /*unnamed union*/ ; //... some more elements; } MyBus;

    Simulink Bus 定义应仅包含 myRefBus_int 元素作为二维的 int32 数组。下一个主题是 S-Function,它将任何所需的总线转换为 int32[]。如果输入是模型级别的总线,则 S-Function 将指针作为输入。数组也显示为指针。因此 S-Function "Bus2ptr" 在 mex.c 文件中有如下定义:

    static void mdlInitializeSizes(SimStruct *simstruct) {
    
    ssSetInputPortWidth(simstruct, 0, 1);
    ssSetInputPortDataType(simstruct, 0, DYNAMICALLY_TYPED);
    ssSetOutputPortDataType(simstruct, 0, SS_INT32);
    ssSetOutputPortWidth(simstruct, 0, 2);
    
    
    }
     static void mdlOutputs(SimStruct *simstruct, int_T tid)
     {  
      void const*const* ptrs = ssGetInputPortSignalPtrs(simstruct, 0);  //InputPtrsType, InputRealPtrsType etc.
      void** x = (void**) ptrs[0];  
      int32* y = (int32*)ssGetOutputPortSignal(simstruct, 0);
      int64 ptr = (int64)(*x);
      y[0] = (int32)ptr;
      y[1] = (int32)(ptr >>32);  //assume little endian. It is proper for all PC processors.
     }
    

    使用了两个 int32,因为它应该在 64 位 PC 上运行。 tlc 文件包含以下行:

     %function Outputs(block, system) Output
      %assign u1_ptr = LibBlockInputSignal(0, "", "", 0)
      %assign y1_ptr = LibBlockOutputSignalAddr(0, "", "", 0)
      *(int32*)(u1_ptr) = (int32)(u1_ptr);
    

    对于 32 位目标系统,您只需要 1 个元素。使用此 S-function,您可以将任何总线转换为 int32-array 并存储 int32 值,即总线结构中的地址。在 C 级别,您可以使用总线头结构中的其他联合元素。

    如果这个周末我有足够的时间,我会在我的网页www.vishia.org 上描述更多内容。然而,那里没有存储任何关于 simulink 的信息。不过下次我会开一个simulink的演示角。

    【讨论】:

    • 抱歉,我在调试时发现了一个错误:正确的代码:static void mdlOutputs(.... void const* x = ptrs[0]; int32* y = (int32*)ssGetOutputPortSignal (simstruct, 0); int64 ptr = (int64)(x); } 我已经调试了使用 tlc 文件生成的代码,它运行良好。但是我没有使用 S 存储在总线中的值-模拟级别的功能。我现在已经调试和检查了。
    猜你喜欢
    • 2021-05-03
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 2018-11-03
    • 2010-09-25
    • 1970-01-01
    • 2015-08-25
    相关资源
    最近更新 更多