1
\$\begingroup\$

I have following code in C++

#define NO_SECTORS  4
#define HEADER_SIZE 6
#define SECTOR_SIZE 64

union flash_rec_u{
    struct record{
        union header_u{
            struct header{
                uint32_t sector_number;
                uint16_t no_written_bytes;
            }header_items __attribute__((packed));
            uint8_t header_bytes[HEADER_SIZE];
        }header;
        uint8_t data_bytes[SECTOR_SIZE - HEADER_SIZE];
    }rec_items;
    uint8_t rec_bytes[SECTOR_SIZE];
};

typedef uint8_t SECTOR[SECTOR_SIZE];
typedef SECTOR FLASH[NO_SECTORS];

FLASH flash;

SECTOR initialStateSector_00[SECTOR_SIZE] = { 
    0x01, 0x00, 0x00, 0x00, 0x25, 0x00,
    0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
    0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
    0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00
};

void PrintSector(uint8_t sector){
  for(uint8_t curByte = 0; curByte < SECTOR_SIZE; curByte++){
    std::cout << std::setw(2);      
    std::cout << showbase << dec;   
    std::cout << hex << (uint16_t)flash[sector][curByte] << ", ";
    if(curByte % 16 == 15){
        std::cout << "\n";
    }
  }
  std::cout << "\n";  
}

void PrintFlash(void){
    for(uint8_t curSector = 0; curSector < NO_SECTORS; curSector++){
        std::cout << "SECTOR: " << (uint16_t)curSector << "\n";
        PrintSector(curSector);
    }
}

void EraseSector(uint16_t sector){
    for(uint16_t curByte = 0; curByte < SECTOR_SIZE; curByte++){
        flash[sector][curByte] = ERASED_BYTE;
    }
}

void EraseFlash(void){
    for(uint16_t curSector = 0; curSector < NO_SECTORS; curSector++){
        EraseSector(curSector);
    }
}

void WriteBytes2Sector(uint8_t sector, uint8_t *srcBytes){
    for(uint16_t curByte = 0; curByte < SECTOR_SIZE; curByte++){
        flash[sector][curByte] = *(srcBytes + curByte);
    }
}

void ReadSector(uint8_t sector, uint8_t *readBytes, uint16_t noBytes2bRead){

    for(uint16_t curSrcByte = 0; curSrcByte < noBytes2bRead; curSrcByte++){
        *(readBytes + curSrcByte) = flash[sector][curSrcByte];
    }
}

void StoreEventLog(uint8_t *eventBytes, uint16_t noEventBytes){

    flash_rec_u buffer;                             


    ReadSector(0, buffer.rec_bytes, 1);    

    for(uint8_t curByte = 0; curByte < SECTOR_SIZE; curByte++){
        std::cout << std::setw(2);      
        std::cout << showbase << dec;   
        std::cout << hex << (uint16_t)(buffer.rec_bytes[curByte]) << ", ";
        if(curByte % 16 == 15){
            std::cout << "\n";
        }
    }
    std::cout << "\n";

}


int main(int argc, char** argv) {

    uint8_t bytes2bStored[] = {
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
        0xBB, 0xBB, 0xBB, 0xBB, 0xBB
    };

    EraseFlash();
    PrintFlash();
    WriteBytes2Sector(0, *initialStateSector_00);
    PrintFlash();

    StoreEventLog(bytes2bStored, sizeof(bytes2bStored));
    PrintFlash();

    return 0;
}

The flash content after erasing:

SECTOR: 0
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 

SECTOR: 0x1
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 

SECTOR: 0x2
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 

SECTOR: 0x3
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

The flash content after writing into the sector 0:

SECTOR: 0
0x1,  0,  0,  0, 0x25,  0, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 

SECTOR: 0x1
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 

SECTOR: 0x2
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 

SECTOR: 0x3
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

Whenever I call the ReadSector function from the StoreEventLog function for reading content of the sector 0 into temporary variable buffer and then print content of the buffer variable I always get totally wrong content:

0x1, 0xcb, 0xff, 0xff,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
 0,  0,  0,  0,  0,  0,  0,  0, 0x67, 0x5b, 0x4c, 0xfe, 0x3,  0,  0,  0, 
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,  0,  0,  0,  0,  0,  0,  0,0,

It seems that the problem is in the ReadSector function, but I don't know where. Could anybody tell me what I do wrong? Thanks for any ideas.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ Type punning to unions isn't well-defined behavior in C++, which is one of the reasons why that language is unsuitable for embedded/hardware-related programming. It is well-defined in C though, so you could try to convert this snippet to C and re-compile in a C compiler. This code also relies on constructors getting called by the "CRT" during start-up, you should verify that they are indeed called. In addition, you have the struct padding issue in C and C++ both, which will be a problem if this is a 32 bit CPU. You'll have to ensure there's no padding. \$\endgroup\$
    – Lundin
    Commented Jan 14, 2019 at 9:45
  • \$\begingroup\$ What does this have to do with Electronic Design? which is what this site is for. \$\endgroup\$ Commented Jan 14, 2019 at 11:08
  • \$\begingroup\$ @Lundin Thank you very much for your reaction. I haven't taken into account padding at all. Do you have any experience how to solve the padding issue? \$\endgroup\$
    – Steve
    Commented Jan 14, 2019 at 11:47
  • 2
    \$\begingroup\$ @Bimpelrekkie The question is obviously about writing a flash driver for a MCU. Hardware-related programming of micrcontrollers is perfectly on-topic. \$\endgroup\$
    – Lundin
    Commented Jan 14, 2019 at 11:53
  • \$\begingroup\$ @Steve Depends on CPU and compiler. There will some non-standard command for your specific compiler, like for example #pragma pack(1), which enforces no padding. However, this could cause problems with misaligned access. If skipping padding is no option, then you either have to write serialization/de-serialization routines that puts the data in/out of the struct manually. Or alternatively skip the struct entirely in favour of a raw uint8_t array. \$\endgroup\$
    – Lundin
    Commented Jan 14, 2019 at 11:56

1 Answer 1

3
\$\begingroup\$

You are seeing uninitialized (stack) memory.

That's because in StoreEventLog you are dumping the contents of a local variable (buffer). The contents of buffer haven't yet been (fully) initialized.

In your code the call to ReadSector only copies the first byte (specified in the last argument of the function call). You probably want to copy the whole sector. Replace ...

ReadSector(0, buffer.rec_bytes, 1);

... with ...

ReadSector(0, buffer.rec_bytes, SECTOR_SIZE);

\$\endgroup\$
4
  • \$\begingroup\$ Thank you for your reaction. Do you have any idea what could be wrong in the ReadSector function? \$\endgroup\$
    – Steve
    Commented Jan 14, 2019 at 14:17
  • \$\begingroup\$ @Steve There's nothing wrong in the function. You simply just told it to only copy the first byte of the "sector". The bug is in the call, not in the function. \$\endgroup\$ Commented Jan 14, 2019 at 14:19
  • \$\begingroup\$ I made the proposed solution clearer. \$\endgroup\$ Commented Jan 14, 2019 at 14:22
  • \$\begingroup\$ Thank you very much for your help and sorry for such stupid question. I became totally blind after looking into the code for a long time. \$\endgroup\$
    – Steve
    Commented Jan 14, 2019 at 14:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.