JeffLowe Posted August 17, 2017 Share Posted August 17, 2017 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 More sharing options...
curtwilson Posted August 18, 2017 Share Posted August 18, 2017 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 More sharing options...
JeffLowe Posted August 22, 2017 Author Share Posted August 22, 2017 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 More sharing options...
curtwilson Posted August 25, 2017 Share Posted August 25, 2017 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 More sharing options...
Recommended Posts