简体   繁体   中英

How to properly read data from memory (memcpy)

I have some tables, for example one declared as uint8_t keyLock[16]; , and I have saved contents of these tables in the flash memory of my MCU. In this memory its looks like below:

Address    Data
00190008 - BA98B694
0019000C - E854B6E7
00190010 - 9200B2C9
00190014 - 42F8B048

When I copy the flash data into my table via the memcpy function ( memcpy(keyLock, 0x00190008, 32); ) the contents of table end up as if initialized this way:

keyLock = {
    0xBA, 0x98, 0xB6, 0x94, 0xE8, 0x54, 0xB6, 0xE7,
    0x92, 0x00, 0xB2, 0xC9, 0x42, 0xF8, 0xB0, 0x48
}

I want the contents to be as if the table were initialized like this:

keyLock = {
    0x94, 0xB6, 0x98, 0xBA, 0xE7, 0xB6, 0x54, 0xE8,
    0xC9, 0xB2, 0x00, 0x92, 0x48, 0xB0, 0xF8, 0x42
}

What is wrong with my memcpy() call, and how should I write it to fill the table with the desired content, as above?

When you store 4 bytes of memory as a 32 but integer whose value is BA98B694 , which byte goes first?

In your question, you implicitly assume the BA byte goes first, but on your system it appears that 94 goes first.

Your memcpy is doing everything right. Your problem is your expectation of endianness, or the layout of your table in flash.

You can fix it by simply swapping the order of each 4 byte dword.

void endian_4byte_swap( uint32_t* bytes ){
  std::swap(bytes[0],bytes[3]);
  std::swap(bytes[1],bytes[2]);
}
void endian_fix_table( uint32_t (&table)[16] ){
  for(int i=0;i<4;++i)
    endian_4byte_swap(&table[4*i]);
}

But that fixes the symptom rather than the disease. The real fix is to fix the table in flash, assuming you have control over it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM