12-02-2009 09:39 AM
Appearently there is a difference when creating clusters in the size of the cluster. I had a cluster with 7 I32s. I figured out that beheavior changed when the size of the cluster exceeded 6 I32s (24 bytes?). When the cluster got larger, it stamped the cluster as a "big cluster".
When using the "optimize for speed" setting when building the application, building the target threw me this error:
..\..\Test_main_clone.c(118): error: #167: argument of type "cl_A0000 **" is incompatible with parameter of type "Cluster *"
The code on this line:
heap->c_PID_settings = *(cl_A0000**)PID_settings__236999976;
/* Cluster Inc Ref Count: */
if(heap->c_PID_settings) heap->c_PID_settings->refcnt += 1;
if (cluster_test_clone_Run( 0xA0000 | BigClusterDataType, &heap->c_PID_settings ) == eFail) CGenErr(); // <---- this line!
/* Free Cluster */
PDAClusterFree( PID_settings__236999976, 0xA0000 | BigClusterDataType );
Definition of function:
extern eRunStatus cluster_test_clone_Run(DataType dtPID_settings__237108688, Cluster * PID_settings__237108688 )
Definition of PID_settings:
cl_A0000 * c_PID_settings;
typedef struct cl_A0000 {
int64 refcnt;
int32 el_0;
int32 el_1;
int32 el_2;
int32 el_3;
int32 el_4;
int32 el_5;
int32 el_6;
} cl_A0000;
Code for only 6 I32s
MemMove(&heap->c_PID_settings, PID_settings__151607432, sizeof(cl_A0000));
if (cluster_test_clone_Run( 0xA0000 | ClusterDataType, &heap->c_PID_settings ) == eFail) CGenErr();
return eFinished;
Definition of function:
extern eRunStatus cluster_test_clone_Run(DataType dtPID_settings__151643168, Cluster PID_settings__151643168 )
definition of PID_settings:
cl_A0000 c_PID_settings;
typedef struct cl_A0000 {
int32 el_0;
int32 el_1;
int32 el_2;
int32 el_3;
int32 el_4;
int32 el_5;
} cl_A0000;
As the definition of cluster is:
typedef void* Cluster;
Am I correct to conclude that the code generation is wrong, and should have generated:
if (cluster_test_clone_Run( 0xA0000 | BigClusterDataType, heap->c_PID_settings ) == eFail) CGenErr();
Instead of:
if (cluster_test_clone_Run( 0xA0000 | BigClusterDataType, &heap->c_PID_settings ) == eFail) CGenErr();
My C is a bit rusty, so I could have missed something. Does anyone have any thoughts about this?
12-02-2009 09:43 AM
12-04-2009 03:38 PM - edited 12-04-2009 03:39 PM
This is indeed a bug, and it happens when I pass a Big Cluster into a subVI and I enable "Generate C function calls" in the build specification. However, it doesn't appear to be bad code, it's just not explicit enough for the compiler.
Try adding an explicit cast (Cluster *) to each assignment that is causing an error.
if (cluster_test_clone_Run( 0xA0000 | BigClusterDataType, (Cluster *)&heap->c_PID_settings ) == eFail) CGenErr();
To workaround this issue:
1) make changes in microvision
2) build through microvision (NOT LabVIEW)
3) use the Run command in LabVIEW
4) if LabVIEW ever re-generates the codes, you must repeat the fix.
Alternately, you could work around this by:
1) Disable "Generate C function calls", but this will decrease performance
2) Do not pass Big Clusters into subVIs (you could unbundle the clusters before passing)
12-07-2009 10:39 AM
Thanx, I understand the work around, but for me it is not an option to edit the code manually, and compile throught uVision. The whole point of using LabVIEW embedded is being able to write G code.
I created a work around by using a global array, which is indexed when needed. This should be faster than parsing the Cluster anyway.