Jump to content
OMRON Forums

C access of Data Structure Elements


JeffLowe

Recommended Posts

I am trying to dynamically fill a 2d comp table.

 

My other C statements like this:

pshm->CompTable[12].Ctrl = 0x02;

compile and operate fine.

 

This statement in C reports

pshm->CompTable[12].Data[xindex][cindex] = pointval;

reports: Error : subscripted value is neither array nor pointer

 

Can anyone educate me?

Thanks

Link to comment
Share on other sites

  • Replies 3
  • Created
  • Last Reply

Top Posters In This Topic

All of the "header" elements for the table can be accessed by the technique you show, because that structure is fixed in size.

 

The actual table data points are managed differently, because they can be of any size, and so are located in a different part of memory.

 

You want to declare a variable like:

 

float *TableDataPtr;

 

then assign:

 

TableDataPtr = pshm->CompTable[12].Data;

 

You now have a pointer to the first data point of the table -- Data[0][0] in Script terms.

 

The data points are accessed as a 1D array even for a 2D table. I haven't worked out which index goes first, but a little experimentation will figure it out.

 

Something like:

 

TableDataPtr[ColumnIndex*NumOfRows + RowIndex] = pointval;

 

or

 

TableDataPtr[RowIndex*NumOfColumns + ColumnIndex] = pointval;

Link to comment
Share on other sites

All of the "header" elements for the table can be accessed by the technique you show, because that structure is fixed in size.

The actual table data points are managed differently, because they can be of any size, and so are located in a different part of memory.

You want to declare a variable like:

float TableDataPtr;

then assign:

TableDataPtr = pshm->CompTable[12].Data;

You now have a pointer to the first data point of the table -- Data[0][0] in Script terms.

The data points are accessed as a 1D array even for a 2D table. I haven't worked out which index goes first, but a little experimentation will figure it out.

Something like:

TableDataPtr[ColumnIndex*NumOfRows + RowIndex] = pointval;

or

TableDataPtr[RowIndex*NumOfColumns + ColumnIndex] = pointval;

 

With a comp table defined with CompTable[12].Nx[0] = 10; CompTable[10].Nx[1] = 1

 

Simplyfing for a test to write the first element of data in the comp table, I have this code fragment:

InitLibrary();

volatile struct SHM *pshm = GetSharedMemPtr();

float *compdataptr;

compdataptr = pshm->CompTable[12].Data;

*(compdataptr) = 11.0 ;

 

This throws a segmentation fault. Any ideas why?

Link to comment
Share on other sites

The issue is an offset in the pointers to shared memory (pshm) between kernel-mode routines (like the ones that execute in the servo interrupt to execute the table) and user-mode routines (like the one you tried). If you had run this as a user-written servo, it would have worked.

 

The key is to add OffsetTblSHM to your pointer address. Here is some code (including some extra lines and commented-out debugging print statements):

 

#include // Global Gp Shared memory pointer

int main(void)

{

float *fptr;

InitLibrary(); // Required for accessing Power PMAC library

pshm->P[200] = 200;

 

CompData *CTptr;

 

CTptr = pshm->CompTable;

printf("CTptr: %X\n",CTptr);

//fptr = CTptr->Data;

//printf("fptr: %X\n",fptr);

printf("OffsetTblSHM: %X\n",OffsetTblSHM);

printf("Data: %X\n",pshm->CompTable[0].Data);

fptr = pshm->CompTable[0].Data + OffsetTblSHM;

printf("pshm->CompTable[0].Data + OffsetTblSHM: %X\n",pshm->CompTable[0].Data + OffsetTblSHM);

pshm->P[201] = CTptr->Source[0];

pshm->P[202] = CTptr->Nx[0];

pshm->P[203] = *fptr;

pshm->P[204] = *fptr+1;

pshm->P[205] = *fptr+2;

CloseLibrary();

return 0;

}

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.

×
×
  • Create New...