2

I have read this, this and this but none of them answers what I like to know

A set of PId's (3 bytes each) are returned from a hardware which is saved into a raw array (buffer). This device returns exactly 84 bytes.

Then I need to copy these PIds to an array or arrays which is readable by API library for this device.

Here is my code

#pragma pack (1)
typedef unsigned char PId[3];
typedef PId PIDs[28];

int GetList(PId* plist){

    unsigned char buffer[84];

    //... Reads the data from hardware memory to buffer
    if (RunCMD(0xCD, &buffer)){
        // buffer has the correct data now 'AAAA...'

        memcpy(&plist,buffer, 84);

        printf("%02X%02X%02X\n", buffer[0], buffert[1], buffer[2]); 
        printf("%02X%02X%02X\n", buffer[3], buffer[4], buffer[5]); 

        return 0;
    } 
    return 1;
}

int main(void) {
    ...

    PId plist_a;
    GetList(&plist_a);

    printf("%02X%02X%02X\n", plist_a[0][0], plist_a[0][1], plist_a[0][2]); 
    printf("%02X%02X%02X\n", plist_a[1][0], plist_a[1][1], plist_a[1][2]); 
    ...
}

Somehow this code does not copy proper data to PIDs array. buffer have the proper data but after memcpy, pids does not have the same data.

I know I'm doing something wrong but I can't find it.

if it helps, I'm compiling my code with windows GCC for ARM CPU

EDIT: I apologize for confusing everyone, actually the code was working, however I missed a part of code. which I corrected. pids is not of type PIDs it is a pointer to it.

Community
  • 1
  • 1
AaA
  • 3,600
  • 8
  • 61
  • 86
  • 5
    Not the answer, just a note. Note that for arrays, you don't need pass the address-of. Just do `memcpy(pids, buffer, 84)` – Jack Oct 31 '12 at 02:40
  • What data are you getting then? Compare the contents of buffer with pids after memcpy to see if there is any correlation. You can also zero out pids before the memcpy to see what exactly got overwritten. – apalopohapa Oct 31 '12 at 02:43
  • @apalopohapa, the data is not related at all, it shows a set of pointers instead of data. my test data is `AAAA....` but the result in pids is 0x5FFE76 0x5FFE79 0x5FFE7B – AaA Oct 31 '12 at 02:48
  • Have you declared the hardware pointer to be volatile? If not then the code might be getting optimized away. – dave Oct 31 '12 at 02:53
  • I miss typed part of code, which re-typed. I apologize from everyone – AaA Oct 31 '12 at 02:59
  • 2
    Those results are in increments of 3 (same number of bytes in a PId), so somehow you are writing the PId addresses instead of their contents. You should post your actual code because this is surely one of c's gotchas. – apalopohapa Oct 31 '12 at 03:00
  • How is the data read from the hardware? What does the library API that you're interfacing with look like? – Adam Rosenfield Oct 31 '12 at 03:11
  • @apalopohapa, you were right, `memcpy(&plist,buffer, 84);` should be `memcpy(plist,buffer, 84);` I didn't notice until I read the first comment on my question. – AaA Oct 31 '12 at 03:30
  • @Jack please post your comment as answer so I can choose as correct answer, thanks – AaA Oct 31 '12 at 03:31
  • @BobSort: sorry for don't see it before, but was done, If still matter. – Jack Oct 31 '12 at 04:29

4 Answers4

3

Take a look at the answer to this question. You probably don't want to use typedefs of arrays directly.

Try something like this:

Declarations:

#pragma pack (1)

typedef struct PId
{
    unsigned char pid[3];
} PId;


typedef struct PIDs
{
    PId pids[28];
} PIDs;

Then, for the memcpy...

Other people have pointed out that you are passing around pointers, such as PId* plist, but you are trying to use memcpy like memcpy(&plist, buffer, 84);. The & symbol will mess you up there, since it would refer to the address of the pointer itself. What you want is:

//plist should probably be a pointer to PIDs, not PId
int GetList(PIDs* plist){

    unsigned char buffer[84];

    //... Reads the data from hardware memory to buffer
    if (RunCMD(0xCD, &buffer)){
        // buffer has the correct data now 'AAAA...'

        //remove the & symbol
        memcpy(plist,buffer, 84);

    //etc
}
Community
  • 1
  • 1
Geoff Montee
  • 2,587
  • 13
  • 14
2

Note that for arrays, you don't need pass the address-of. Just do

memcpy(pids, buffer, 84);
Jack
  • 16,276
  • 55
  • 159
  • 284
0

I'm confused why this even compiles. Instead of

typedef PIDs PId[28];

you need

typedef PId PIDs[28];

With a typedef, you put the name of the new type where the variable would normally go.

j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
  • Sorry it was a typo, I removed the real names which was 32 chars long to make it simple to read – AaA Oct 31 '12 at 02:48
0

This may work:

#pragma pack (1)

struct PId{
  unsigned char pid[3];
};

int main(){    
  unsigned char buffer[84];
  struct PId pids[28];

  /* buffer gets populated somewhere here */    

  memcpy(pids, buffer, 84);
}
apalopohapa
  • 185
  • 3
  • 11