Accessing structs with byte pointer

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
//Machine Vars For Save/Restore
struct MachVars {
  byte save_valid;                  // marks if the save flash has been written
  unsigned long slope[9];           // slope corrections
  unsigned long offset[9];          // offset corrections
  unsigned int seq[8][64][8];       // Main preset setting
  unsigned int encseq[8][64][8];    // Stores offsets from encoder
  byte gateseq[8][64][8];           // Stores offsets from encoder
} saves;

// the call to save to flash
writePageOfBytes(0,&saves,256);

void writePageOfBytes(uint32_t addr, const void* buf, uint16_t len) {
for (uint16_t i = 0; i < len; i++)
  {
    SPI.transfer(OUT_DAC_CS,((uint8_t*) buf)[i] );
  }

I need to store some variables in a flash chip which takes pages of 256 bytes. My thought was to set a pointer of type uint8_t to the beginning of the structure then step through it. I have verified the flash and the read/write routines work with test data in arrays. But when I use the pointer to the above structure the data gets messed up, the values appear scrambled. It looks like it should work to me. What am I missing?

Tim Ressel
Portland, OR
timr@earthling.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
writePageOfBytes(0,&saves,256);

???

The struct is way bigger than 256 bytes.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm saving the whole struct, 256 bytes (1 page in the flash chip) at a time.

Tim Ressel
Portland, OR
timr@earthling.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is a test program but should demonstrate how to do;

 

#include <avr/io.h>

void writePageOfBytes(uint32_t, const uint8_t*, uint16_t);

//Machine Vars For Save/Restore
struct MachVars {
    uint8_t save_valid;                  // marks if the save flash has been written
    unsigned long slope[9];           // slope corrections
    unsigned long offset[9];          // offset corrections
    unsigned int seq[9];       // Main preset setting
    unsigned int encseq[9];    // Stores offsets from encoder
    uint8_t gateseq[9];           // Stores offsets from encoder
} saves;

    uint8_t buf[155];

int main(void)
{
    int i = 0;
    
    saves.save_valid = 1;
    for (i = 0; i < 9; i++)
    {
        saves.slope[i] = 0x32 + i;
        saves.offset[i] = 0x33 + i;
        saves.seq[i] = 0x34 + i;
        saves.encseq[i] = 0x35 + i;
    }
    
    // the call to save to flash
    writePageOfBytes(0, (uint8_t*) &saves, sizeof(saves));

    i = 32;
    
    while(1)
    {
        //TODO:: Please write your application code
    }
}

    void writePageOfBytes(uint32_t addr, const uint8_t* pbuf, uint16_t len) {
        for (uint16_t i = 0; i < len; i++)
        {
            buf[i] = *pbuf++;
        }
    }

Happy Trails,

Mike

JaxCoder.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

madhun wrote:
I'm saving the whole struct, 256 bytes (1 page in the flash chip) at a time.
Then show the code for saving the whole struct.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What you are really trying to do here is called serialization. If it has to be divided up into chunks I would do something like:

struct MachVars {
  byte save_valid;                  // marks if the save flash has been written
  unsigned long slope[9];           // slope corrections
  unsigned long offset[9];          // offset corrections
  unsigned int seq[8][64][8];       // Main preset setting
  unsigned int encseq[8][64][8];    // Stores offsets from encoder
  byte gateseq[8][64][8];           // Stores offsets from encoder
} saves;

div_t sizeData;

int main(void) {
    uint8_t * p;
    int n, page;
    sizedata = div(sizeof(saves), 256);
    p = (uint8_t *)&saves;
    page = 0;
    for (n = 0; n < sizeData.quot; n++) {
        writePageOfByes(page++, p, 256);
        p += 256;
    }
    if (sizeData.rem) {
        writePageOfByes(page, p, sizeData.rem);
    }
}

Which will write n full 256 byte pages and then one last page of the "spillage" into the last page (if any).

 

I had to guess what the first 0 in writePageOfBytes() was - I assume it is an incrementing page number rather a byte address? If it is a byte address then page++ is not enough and would need to be brought out as "page += offset;"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
What you are really trying to do here is called serialization

Indeed: https://en.wikipedia.org/wiki/Serialization

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

How to properly post source code: https://www.avrfreaks.net/comment...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...