我在 Matlab 中定义了一个 Bus 对象,我将它传递给一个 C S-function,它会做一些处理。我已经在 mdlInitializeSizes
中像这样初始化了输入:
#if defined(MATLAB_MEX_FILE)
if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY)
{
DTypeId dataTypeIdReg;
ssRegisterTypeFromNamedObject(S, BUS_OBJ_NAME, &dataTypeIdReg);
if(dataTypeIdReg == INVALID_DTYPE_ID) return;
ssSetInputPortDataType(S, 0, dataTypeIdReg);
}
#endif
ssSetInputPortWidth(S, 0, 1);
ssSetBusInputAsStruct(S, 0, 1);
ssSetInputPortDirectFeedThrough(S, 0, 1);
ssSetInputPortRequiredContiguous(S, 0, 1);
我还自动生成了一个 C 结构,其中包含与 Bus 对象内的信号相同的变量。
Bus 中的一些信号也是总线,因此 C 结构体是递归生成的。例如:
struct myStruct
{
uint8_t var1[8];
uint32_t var2;
myOtherStruct1 var3;
myOtherStruct2 var4;
...
}
现在我想将 Bus 对象读入结构中。为此,我这样做:
const myStruct *busData = (const myStruct *) ssGetInputPortSignal(S, 0);
问题是 busData 没有 var4
和后续变量的正确数据。如果我打印从 ssGetInputPortSignal 收到的原始数据,我可以找到我期望的数据,但它不在数组中的正确位置;相反,它有一些填充。
因此我想问:
- 这是将 Bus 对象读入 C S-Function 结构的正确方法吗?
- 如何禁用填充以使所有数据都是连续的?
提前致谢!
最佳答案
我遇到了同样的问题。对我有帮助的是 MathWorks 提供的以下示例:
open('sldemo_sfun_counterbus.c')
open('counterbus.h')
下面是一些代码片段,展示了如何根据上述示例获取 simulink 总线对象的信息:
// Defined localy, could also be defined in a header
typedef struct
{
uint32_t ui32_header_val;
double f64_header_val;
} YOURSTRUCT;
static void mdlInitializeSizes(SimStruct *S)
{
// ... your code
// Specify I/O
if (!ssSetNumInputPorts(S,1)) return;
//Bus inport
DTypeId dataTypeIdReg;
ssRegisterTypeFromNamedObject(S, "YOURBUS", &dataTypeIdReg);
ssSetInputPortDataType(S, 0, dataTypeIdReg);
ssSetBusInputAsStruct(S, 0, true);
ssSetInputPortOverWritable(S, 0, 1);
ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
// This is important !!! Specifies that the signal elements entering the specified port must occupy contiguous areas of memory
ssSetInputPortRequiredContiguous(S, 0, 1);
// Configure the dwork (__dtBusInfo)
ssSetDWorkDataType(S, 0, SS_INT32);
ssSetDWorkUsageType(S, 0, SS_DWORK_USED_AS_DWORK);
ssSetDWorkName(S, 0, "dtBusInfo");
// This contains the offset and sizes of your struct
ssSetDWorkWidth(S, 0, 4);
// The DWorker needs a depth of 4, since it stores the size of each element and its offset
ssSetDWorkComplexSignal(S, 0, COMPLEX_NO);
// ... your code
}
static void mdlStart(SimStruct *S)
{
// ... your code
// Access bus/struct information
int32_T* __dtBusInfo = (int32_T*)ssGetDWork(S, 0);
// Get common data type Id
DTypeId __YOURBUSId = ssGetDataTypeId(S, "YOURBUS");
DTypeId __int32Id = ssGetDataTypeId(S, "int32");
DTypeId __doubleId = ssGetDataTypeId(S, "double");
// Get information for accessing YOURBUS.ui32_header_val
__dtBusInfo[0] = ssGetBusElementOffset(S, __YOURBUSId, 0);
__dtBusInfo[1] = ssGetDataTypeSize(S, __int32Id);
// Get information for accessing YOURBUS.f64_header_val
__dtBusInfo[2] = ssGetBusElementOffset(S, __YOURBUSId, 1);
__dtBusInfo[3] = ssGetDataTypeSize(S, __doubleId);
// ... your code
static void mdlOutputs(SimStruct *S, int_T tid)
{
// ... your code
char *inputPort = (char*)(ssGetInputPortSignal(S, 0)); // Cast it to an 8Bit long Pointer here char
YOURSTRUCT yourCStruct;
memcpy(&yourCStruct.ui32_header_val, inputPort + __dtBusInfo[0], __dtBusInfo[1]);
memcpy(&yourCStruct.f64_header_val, inputPort + __dtBusInfo[2], __dtBusInfo[3]);
// ... your code
}
关于c - 如何将 Bus 对象读入 C S-Function 中的 C 结构 [Matlab],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34359205/