string storing on Flash

Thread Starter

chandimajaya85

Joined Sep 27, 2023
25
hi,
I initialized string array with strings and type cast to uint32_t to store in flash memory as uint32_t. And then read the array as uint32_t. I update one of the string of the array and type cast uint32_t to store that array in Flash memory back. But whenever I update string value and store on the flash memory. The string has strange characters on it. If you see the string that I am trying to store in string array "21.76".
string.jpg

But in flash memory showing as "yyyy6.Its not storing properly.If you see the picture below in memory browser its showing as "yyyy6".
memory.jpg
 

Thread Starter

chandimajaya85

Joined Sep 27, 2023
25
hi,
I initialized string array with strings and type cast to uint32_t to store in flash memory as uint32_t. And then read the array as uint32_t. I update one of the string of the array and type cast uint32_t to store that array in Flash memory back. But whenever I update string value and store on the flash memory. The string has strange characters on it. If you see the string that I am trying to store in string array "21.76".
View attachment 320499

But in flash memory showing as "yyyy6.Its not storing properly.If you see the picture below in memory browser its showing as "yyyy6".
View attachment 320500
I am using one of the library to write into flash. Here is the code that I am using for write into flash. https://github.com/MYaqoobEmbedded/STM32-Tutorials/blob/master/Tutorial 30 - FLASH Memory/MY_FLASH.c.I am using HAL_FLASH_WriteN on that library.
I put some breakpoints on the library file (MY_FLASH.c) just before the HAL_FLASH_Lock() on the HAL_FLASH_WriteN. I can see in that sector 0x08040000 characters are not written properly into the flash memory. I dont know whats going on there. Is there possibility that sector is bad or processor gets interrupted during the write operation. Or the flashAddress is not sequencing?
 

trebla

Joined Jun 29, 2019
550
You can't store this string array as uint32 because 32 bit integer is 4 bytes long but your string array is 10 bytes long. Even if you want store only string "21.76" it takes 6 bytes.
 

trebla

Joined Jun 29, 2019
550
IMO simplest way to use this write function is set data type to DATA_TYPE_8 and in while(char[index]) loop call this write function for each byte, increasing the index variable after every write.
 

Irving

Joined Jan 30, 2016
4,045
MY_FLASH_WriteN already supports strings...


Code:
int main() {
uint32_t idx =<some index>;

char myString[10] = {'2', '1', '.', '7', '6', 0, 0, 0, 0, 0};

MY_FLASH_WriteN(idx, myString, 10, DATA_TYPE_8);

char anotherString[10];
MY_FLASH_ReadN(idx, anotherString, 10, DATA_TYPE_8);

printf("Read: %s\n", anotherString);
}
 

Thread Starter

chandimajaya85

Joined Sep 27, 2023
25
IMO simplest way to use this write function is set data type to DATA_TYPE_8 and in while(char[index]) loop call this write function for each byte, increasing the index variable after every write.
Thank you for the reply. My string array is as multidimensional array. CStore is initialized as "static char CStore[4][10]={0}. On your code you have initialized as MY_FLASH_WriteN as DATA_TYPE_8. On your string contains 5 bytes of data. Is it not DATA_TYPE_32 or may be MY_FLASH_WriteN needs change to adopt DATA_TYPE_64.

Here is my code:
Code:
if(strncmp((char*)ptr, "tc", 5) == 0)
   {
   MY_FLASH_SetSectorAddrs(6, 0x08040000);
   if (strncmp((char*)ptr, "tc1", 6) == 0)
       {
        Counter = 0;
       }

    MY_FLASH_ReadN(0, (uint32_t*)CStore, sizeof(Ctore),DATA_TYPE_32);
    HAL_Delay(100);
    memset(&CStore[Counter], '\0', 10);

     for(char *str =strtok((char*)ptr, " "); str; str = strtok(NULL, " "))
     {
     if(strncmp((char*)str, "tc", 5) == 0)
       continue;

     strncpy(CStore[Counter], str, strlen(str)); 
     Counter++;
     }

     MY_FLASH_WriteN(0, (uint32_t*)CStore, sizeof(CStore), DATA_TYPE_32);
     HAL_Delay(100);
 

Thread Starter

chandimajaya85

Joined Sep 27, 2023
25
MY_FLASH_WriteN already supports strings...


Code:
int main() {
uint32_t idx =<some index>;

char myString[10] = {'2', '1', '.', '7', '6', 0, 0, 0, 0, 0};

MY_FLASH_WriteN(idx, myString, 10, DATA_TYPE_8);

char anotherString[10];
MY_FLASH_ReadN(idx, anotherString, 10, DATA_TYPE_8);

printf("Read: %s\n", anotherString);
}
My string array is as multidimensional array. CStore is initialized as "static char CStore[4][10]={0}. On your code you have initialized as MY_FLASH_WriteN as DATA_TYPE_8. On your string contains 5 bytes of data. Is it not DATA_TYPE_32 or may be MY_FLASH_WriteN needs change to adopt DATA_TYPE_64.
 

trebla

Joined Jun 29, 2019
550
Char type is 8 bit long, so the DATA_TYPE_8 is right. For multidimensional arrays you must write one dimension at a time, for example start at *CStore[0], or if the flash write function can not handle strings, one byte element at a time like CStore[0][0]. For string writing function you must ensure that next string is writed at new flash memory location after the previous string ending. If the string data is not with constant lenght then you must rewrite entire flash sector every time if some data changes in your array or write every string with maximum allowed size by array definiton.
 

Thread Starter

chandimajaya85

Joined Sep 27, 2023
25
Char type is 8 bit long, so the DATA_TYPE_8 is right. For multidimensional arrays you must write one dimension at a time, for example start at *CStore[0], or if the flash write function can not handle strings, one byte element at a time like CStore[0][0]. For string writing function you must ensure that next string is writed at new flash memory location after the previous string ending. If the string data is not with constant lenght then you must rewrite entire flash sector every time if some data changes in your array or write every string with maximum allowed size by array definiton.
Thank you very much for the reply. Looking at my code above what do I need to do make changes to it. What should I change on my code.
 

Irving

Joined Jan 30, 2016
4,045
My string array is as multidimensional array. CStore is initialized as "static char CStore[4][10]={0}. On your code you have initialized as MY_FLASH_WriteN as DATA_TYPE_8. On your string contains 5 bytes of data. Is it not DATA_TYPE_32 or may be MY_FLASH_WriteN needs change to adopt DATA_TYPE_64.
I initialize my string as 10 bytes (Inc terminating 0s).

No, your fundamental data type is a char, a byte, 8 bits. The fact it's an array of such is a higher level construct. The MY_FLASH_xxx routines only cater for bytes, words (16bits) and double-words (32bits). To store your array of 4strings of 10 chars you have to iterate over each string as per my code with an outer loop iterating over each string.

Code:
int main() {
uint32_t idx =<some index to base of array in flash>;

char myArray[4][10];//array of 4 x 10 char strings
//initialise first string... 
strncpy(myArray[0], "21.76",10);
strncpy(myArray[1], "hello 2",10);
//to do:   init rest... 

for(int row=0;row<4;row++){ // write whole array
   MY_FLASH_WriteN(idx+row*10*sizeof(char), myArray[row], 10, DATA_TYPE_8);
}

char anotherArray[4][10];
for(int row=0;row<4;row++){ //read whole array
   MY_FLASH_ReadN(idx+row*10*sizeof(char), anotherArray[row], 10, DATA_TYPE_8);
}

printf("Read 1st row as %s\n", anotherArray[0]);

// read out 2nd row only
char myString[10];
uint32_t row=2;
uint32_t newidx = idx+(row-1) *10*sizeof(char);
MY_FLASH_ReadN(newidx, myString, 10, DATA_TYPE_8);
printf("Read 2nd row as %s\n", myString);

}
 

Thread Starter

chandimajaya85

Joined Sep 27, 2023
25
I initialize my string as 10 bytes (Inc terminating 0s).

No, your fundamental data type is a char, a byte, 8 bits. The fact it's an array of such is a higher level construct. The MY_FLASH_xxx routines only cater for bytes, words (16bits) and double-words (32bits). To store your array of 4strings of 10 chars you have to iterate over each string as per my code with an outer loop iterating over each string.

Code:
int main() {
uint32_t idx =<some index to base of array in flash>;

char myArray[4][10];//array of 4 x 10 char strings
//initialise first string...
strncpy(myArray[0], "21.76",10);
strncpy(myArray[1], "hello 2",10);
//to do:   init rest...

for(int row=0;row<4;row++){ // write whole array
   MY_FLASH_WriteN(idx+row*10*sizeof(char), myArray[row], 10, DATA_TYPE_8);
}

char anotherArray[4][10];
for(int row=0;row<4;row++){ //read whole array
   MY_FLASH_ReadN(idx+row*10*sizeof(char), anotherArray[row], 10, DATA_TYPE_8);
}

printf("Read 1st row as %s\n", anotherArray[0]);

// read out 2nd row only
char myString[10];
uint32_t row=2;
uint32_t newidx = idx+(row-1) *10*sizeof(char);
MY_FLASH_ReadN(newidx, myString, 10, DATA_TYPE_8);
printf("Read 2nd row as %s\n", myString);

}
Thank you very much for the reply. It is very helpful. However
MY_FLASH_WriteN(0, (uint8_t*)CStore, sizeof(CStore), DATA_TYPE_8);
works on its own without a for loop.But I get a strange character store infront of the string character. instead of -21.72 on the flash, I am getting c (copyright symbol)21.72 infront of the string. I dont know why. It it because of the length specifiy is wrong.
 

Irving

Joined Jan 30, 2016
4,045
Thank you very much for the reply. It is very helpful. However <code> works on its own without a for loop
Of course, if you don't need to modify flash at the string level and can afford the time to read or write all 40 bytes, then that's great.

But I get a strange character store infront of the string character. instead of -21.72 on the flash, I am getting c (copyright symbol)21.72 infront of the string.
Hmm, not obvious. Can you post your code from where you initialise CStore to where you encounter the problem...
 

Thread Starter

chandimajaya85

Joined Sep 27, 2023
25
Of course, if you don't need to modify flash at the string level and can afford the time to read or write all 40 bytes, then that's great.


Hmm, not obvious. Can you post your code from where you initialise CStore to where you encounter the problem...
If you see in the CStore, I can see that it has -2.39 on it.

CStore.JPG

But, I checked the memory browser of that particular address. It does not contain "-" sign. Its very strange. I dont know whats going on there. Do I need a delay?

memory browser.JPG
 

Irving

Joined Jan 30, 2016
4,045
The HAL routines already have delays built in IIRC. Maybe something else is writing to that location, see the blocks following.. - try changing your index.
 

BobaMosfet

Joined Jul 1, 2009
2,123
hi,
I initialized string array with strings and type cast to uint32_t to store in flash memory as uint32_t. And then read the array as uint32_t. I update one of the string of the array and type cast uint32_t to store that array in Flash memory back. But whenever I update string value and store on the flash memory. The string has strange characters on it. If you see the string that I am trying to store in string array "21.76".
View attachment 320499

But in flash memory showing as "yyyy6.Its not storing properly.If you see the picture below in memory browser its showing as "yyyy6".
View attachment 320500
You need more help in how to address memory in whatever way you want, whether accessing a uint32 as a uchar array or as a ulong, or as 2 shorts. Once you can understand that, then memory work is easy with whatever you've got.
 
Top