Author Topic: Storing a char array into FLASH memory through EEPROM emulation  (Read 3961 times)

0 Members and 1 Guest are viewing this topic.

Offline LuisTopic starter

  • Newbie
  • Posts: 6
  • Country: mx
Storing a char array into FLASH memory through EEPROM emulation
« on: November 02, 2017, 06:08:10 pm »
Hi, I'm using the EEPROM Emulation Example provided by the STM32CUBEmx library. Im using the STM32F429-Discovery, the project is working well, I was saving int values and everything is working well. Saving a variables is done by using the funtion EE_WriteVariable provided by the project example. The data should be uint16_t type, so when I save int values I don't have problems. Even saving char* there's no problem by doing a cast. The problem is when I want to save char array, when I recover the value with the function EE_ReadVariable the value isn't the one I saved. This is the code what Im doing:


char str[] = "Hello World";
char* redfinal="HOLA";

char *result = (char *)malloc(strlen(str)+1);
int index=0;
while(index <= strlen(str))
{
  result[index] = str[index];
  index++;
}

   
      char* a;
                char*c;
      EE_WriteVariable(VirtAddVarTab[5], *(uint16_t*)&result);
      EE_WriteVariable(VirtAddVarTab[6], *(uint16_t*)&redfinal);
      
          EE_ReadVariable(VirtAddVarTab[5], (uint16_t*)&c);   
      EE_ReadVariable(VirtAddVarTab[6], (uint16_t*)&a);   


the variable redfinal is stored and recover in the variable a. the variable result should be stored an recover in c, but It doesn't. Anyone knows why?
Thanks for all your previous help! Greetings
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Storing a char array into FLASH memory through EEPROM emulation
« Reply #1 on: November 03, 2017, 11:33:00 am »
Even saving char* there's no problem by doing a cast.
Yes there is; you just don't see it. I won't draw out the box and arrow pointer picture, but what you are saving to the EEPROM when you do       EE_WriteVariable(<PICK AN ADDRESS>, (uint16_t*)redfinal); is that you're storing the address of the string variable, not the contents of that string. So, if you read back that same address with the same program, then the pointer points to the same string. If you wrote the address of the string to the EEPROM, then reprogrammed the chip with a new program, the chance that the value you read back (what redfinal points to) would be the same is very low.
the variable redfinal is stored and recover in the variable a
No it's not (for the same reason as above).

What you need to do is to write the bytes of the string, not the address of the string, to the EEPROM.

I don't do STM, so the below is untested (I don't even know that it will compile):

Try:

Code: [Select]
// These two are the same type variable, by the way, so I prefer to write them both the second way.
char str[] = "Hello World";
char *redfinal="HOLA";

char *result = (char *)malloc(strlen(str)+1);

// This is a more idiomatic way of copying a string in C/C++ (though your way worked)
char *p = results, char *q = str;
while (*p++ = *q++);

// Here's how I'd actually do it:
// Use the FLASH_ProgramHalfWord() or FLASH_ProgramWord()  functions to write the string contents to a pre-determined location
// I'd probably write the string length first, then the string contents.


// Using the functions you've chosen to use, I'd write it like this
// still write the string length to the EEPROM first, then the contents, but if the string length is dynamic, it's going to screw up the rest of your variables, unless you only have one dynamic length string and it's the last one.

uint16_t len = strlen(result);

// Write the length
EE_WriteVariable(VirtAddVarTab[5], len);

// Loop over the string and write it two bytes at a time
for (int index = 0; index <= (len+1)/ 2; index++) {
    uint16_t temp = *((uint16_t *) (result+index*2));   // This doesn't strictly meet the C lang specs, but generally works
    EE_WriteVariable(VirtAddVarTab[6+index], temp);
}

uint16_t len2;
EE_ReadVariable(VirtAddVarTab[5], &len2);

char *str2 = (char *) malloc(len2+1);
for (int index = 0; index < ((len2 +1)/2); index++) {
    EE_ReadVariable(VirtAddVarTab[6+index], str2+index*2);
}
str2[len2] = 0;

My apologies if it doesn't compile or doesn't work straight out of the box. I had to just write it in the EEV forum editor; I couldn't really test it, but I'm happy to work with you more as you test it.

Edit: Changed the read loop to fix an off-by-one error. This code is some hacky shit; I'm sorry that I didn't have time to pretty it up, but this at least should show you how you need to do it.

Edit2: If you could come back to the thread and let us know it worked, that might help the next random dev who is searching for the answer to this problem. (Or if it didn't, let's help some more so we do get it fixed.)
« Last Edit: November 03, 2017, 04:49:29 pm by sokoloff »
 

Offline LuisTopic starter

  • Newbie
  • Posts: 6
  • Country: mx
Re: Storing a char array into FLASH memory through EEPROM emulation
« Reply #2 on: November 07, 2017, 03:40:15 pm »
I really appreciatte your help, I was trying during the last days to compile and probe the code you gave me; I just had to make two modifications to get it successfully compiled but It doesn't do anything :C, It's still without saving the value of the array pointer.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Storing a char array into FLASH memory through EEPROM emulation
« Reply #3 on: November 07, 2017, 08:19:19 pm »
I really appreciatte your help, I was trying during the last days to compile and probe the code you gave me; I just had to make two modifications to get it successfully compiled but It doesn't do anything :C, It's still without saving the value of the array pointer.
Sorry about the syntax error.

Post the code as you have it, and if you have a link handy to the STM development tools, post that.

I'll see if I can download the dev tools and have a deeper look.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf