cancel
Showing results for 
Search instead for 
Did you mean: 

[SOLVED]storing struct into flash

Erkan Ersoy
Associate II
Posted on August 31, 2015 at 11:04

Hello

I am trying to save my settings into flash. I use a struct that storing settings, then put a pointer begining of it and store all the bytes into flash along the size of that struct. But it seems struct is scattered in RAM. Is there an instruction that puts in Flash without scattered. I tried

struct __attribute__((packed, aligned(4))) network_settings_t{
unsigned char DHCP;
ipAddress_t ip;
ipAddress_t subnet_mask;
ipAddress_t gateway;
ipAddress_t dns;
char MAC_ADDRESS[6];
};

but it didn't work I am using old drivers with GCC on STM32F107RTC

uint32_t address = FLASH_USER_START_ADDR;
uint32_t *ptr;
ptr = data; 
FLASHStatus = FLASH_ErasePage(FLASH_USER_START_ADDR);
FLASH_WaitForLastOperation(100);
FLASH_ProgramWord(FLASH_USER_START_ADDR,*ptr);
FLASH_WaitForLastOperation(100);
ptr = &network_settings;
address += 4;
while(ptr <= (&network_settings + sizeof(network_settings))){
FLASH_ProgramWord(address,*ptr);
FLASH_WaitForLastOperation(100);
address += 4;
ptr += 4;
}

and to read it:

unsigned int *mem;
unsigned int *ptr;
printf(''Load Settings From Flash\n'');
printf(''Loading Settings...\r\n'');
ptr = &network_settings;
mem = (unsigned int*)FLASH_USER_START_ADDR;
while(ptr <= (&network_settings+sizeof(network_settings))){
*ptr = *mem;
ptr += 4;
mem +=4;
}

Thank you...
7 REPLIES 7
Posted on August 31, 2015 at 14:08

You want the struct in RAM, you're copying it in and out of FLASH. If you just want the linker to place a FIXED object in FLASH you should use something like ''static const'' and define the content of the structure where you allocated it.

You ignore whatever errors/status are returned by the flashing code. You write the size for no particular purpose, and your read code copies that into the structure instead of jumping over it. You could use memcpy() to move the FLASH version into RAM.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Erkan Ersoy
Associate II
Posted on August 31, 2015 at 15:15

Thanks for the reply

Yes i ignored the errors. Because i wanted to see the code work quickly and i don't know why it goes error while reading flash i mean i shouldn't see error while internal operation (unless i make mistake). i guess.. I will add error part... I thought it like there is an original version of settings on flash and i will copy it to RAM i order to use it (I used lots of pic so i am thinking it's like EEPROM and i cant read it freely). I am adding size to struct pointer so I will know end of struct(in while loop ptr<network_settings+sizeof(networksettings)) ) code doesnt work right. First struct i am copying right but other structs values are all wrong. I will try your suggestions here is mt whole functions: i changesd structs to struct pointer so i can use malloc and stack them like block

#include ''settings.h''
#include ''EE_ethernet.h''
#include ''stm32f10x_flash.h''
//Settings
network_settings_t *network_settings;
port_settings_t *port1_settings;
port_settings_t *port2_settings;
/**
* Data saklama baþlangýç adresi : 0x803F800
* Data saklama bitiþ adresi0 : 0x8040000
*
*
*---------------------------------------------------------------------------------------
* | HEADER | NETWORK SETTINGS | PORT1 SETTINGS | PORT2 SETTINGS | IO SETTINGS |
*---------------------------------------------------------------------------------------
* | erka |
*/
void settings_save(){
FLASH_Status FLASHStatus = FLASH_COMPLETE;
printf(''SAVE SETTINGS SKETCH
'');
char data[] = ''erka'';
uint32_t address = FLASH_USER_START_ADDR;
uint32_t *ptr;
ptr = data;
printf(''FLASH Settings are saving...

'');
printf(''network settings size: %d
'',sizeof(network_settings_t));
printf(''network settings address: %
X'',network_settings);
printf(''port 1 settings address: %
X'',port1_settings);
printf(''port 2 settings address: %
X'',port2_settings);
printf(''network settings size: %d
'',sizeof(network_settings_t));
printf(''port1 settings size: %d
'',sizeof(port_settings_t));
printf(''port2 settings size: %d
'',sizeof(port_settings_t));
FLASH_Unlock();
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASHStatus = FLASH_ErasePage(FLASH_USER_START_ADDR);
FLASH_WaitForLastOperation(100);
FLASH_ProgramWord(FLASH_USER_START_ADDR,*ptr);
FLASH_WaitForLastOperation(100);
ptr = network_settings;
address += 4;
while(ptr < (network_settings + sizeof(network_settings_t))){
FLASH_ProgramWord(address,*ptr);
FLASH_WaitForLastOperation(100);
address += 4;
ptr += 4;
}
ptr = port1_settings;
while(ptr < (port1_settings + sizeof(port_settings_t))){
FLASH_ProgramWord(address,*ptr);
FLASH_WaitForLastOperation(100);
address += 4;
ptr += 4;
}
ptr = port2_settings;
while(ptr < (port2_settings + sizeof(port_settings_t))){
FLASH_ProgramWord(address,*ptr);
FLASH_WaitForLastOperation(100);
address += 4;
ptr += 4;
}
FLASH_Lock();
printf(''settings saved 
'');
}
void settings_set_defaults(){
network_settings->DHCP = 1;
network_settings->gateway.ip1 = 192;
network_settings->gateway.ip2 = 168;
network_settings->gateway.ip3 = 1;
network_settings->gateway.ip4 = 1;
network_settings->ip.ip1 = 192;
network_settings->ip.ip2 = 168;
network_settings->ip.ip3 = 1;
network_settings->ip.ip4 = 157;
network_settings->subnet_mask.ip1 = 255;
network_settings->subnet_mask.ip2 = 255;
network_settings->subnet_mask.ip3 = 255;
network_settings->subnet_mask.ip4 = 0;
network_settings->MAC_ADDRESS[0] = 0;
network_settings->MAC_ADDRESS[1] = 2;
network_settings->MAC_ADDRESS[2] = 0;
network_settings->MAC_ADDRESS[3] = 0;
network_settings->MAC_ADDRESS[4] = 0;
network_settings->MAC_ADDRESS[5] = 1;
port1_settings->baud_rate = 9600;
port1_settings->data_bit = 8;
port1_settings->parity = 0;
port1_settings->port = 4444;
port1_settings->stop_bit = 0;
port2_settings->baud_rate = 9600;
port2_settings->data_bit = 8;
port2_settings->parity = 0;
port2_settings->port = 4445;
port2_settings->stop_bit = 0;
printf(''IP SET: %u %u %u %u 
'',network_settings->ip.ip1, network_settings->ip.ip2, network_settings->ip.ip3, network_settings->ip.ip4);
printf(''IP MASK: %u %u %u %u 
'',network_settings->subnet_mask.ip1, network_settings->subnet_mask.ip2, network_settings->subnet_mask.ip3, network_settings->subnet_mask.ip4);
}
void settings_load(){
unsigned int *mem;
unsigned int *ptr;
printf(''Load Settings From Flash
'');
printf(''Loading Settings...

'');
ptr = network_settings;
mem = (unsigned int*)FLASH_USER_START_ADDR;
mem +=4;
while(ptr < (network_settings+sizeof(network_settings))){
*ptr = *mem;
ptr += 4;
mem +=4;
}
ptr = port1_settings;
while(ptr < (port1_settings+sizeof(port1_settings))){
*ptr = *mem;
ptr += 4;
mem +=4;
}
ptr = port2_settings;
while(ptr < (port2_settings+sizeof(port2_settings))){
*ptr = *mem;
ptr += 4;
mem +=4;
}
printf(''IP SET READ: %u %u %u %u 
'',network_settings->ip.ip1, network_settings->ip.ip2, network_settings->ip.ip3, network_settings->ip.ip4);
printf(''IP MASK READ: %u %u %u %u 
'',network_settings->subnet_mask.ip1, network_settings->subnet_mask.ip2, network_settings->subnet_mask.ip3, network_settings->subnet_mask.ip4);
printf(''MAC ADDRESS READ: %x %x %x %x %x %x 
'',network_settings->MAC_ADDRESS[0],network_settings->MAC_ADDRESS[1],network_settings->MAC_ADDRESS[2],network_settings->MAC_ADDRESS[3],network_settings->MAC_ADDRESS[4],network_settings->MAC_ADDRESS[5]);
printf(''port 1 settings: %u 
'', port1_settings->port);
printf(''port 1 settings: %x 
'',port1_settings->stop_bit);
printf(''port 2 settings: %u 
'', port2_settings->port);
printf(''port 2 settings: %x 
'',port2_settings->stop_bit);
}
void settings_init(){
network_settings = (network_settings_t*)malloc(sizeof(network_settings_t));
port1_settings = (port_settings_t*)malloc(sizeof(port_settings_t));
port2_settings = (port_settings_t*)malloc(sizeof(port_settings_t));
}

(sorry english is not my mother languagei may mess up in sentences)
Posted on August 31, 2015 at 17:03

First struct i am copying right but other structs values are all wrong.

Ok, we're using a medium where I can't see what results you're getting, it would be helpful to show them because it might suggest where the problem is.

FLASHStatus = FLASH_ErasePage(FLASH_USER_START_ADDR); // Use address
FLASH_WaitForLastOperation(100);
FLASH_ProgramWord(FLASH_USER_START_ADDR,*ptr); // WHAT DOES THIS DO WITH AN UNASSIGNED POINTER? Use address
FLASH_WaitForLastOperation(100);

If you step through your code in a debugger, do you see the data showing up in the flash memory?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Erkan Ersoy
Associate II
Posted on August 31, 2015 at 23:17

Debug process didn't go as i expected. Software runs a little before debug process begins so Flash addresses already written when i was trying to debug. except the first struct and heade r other struct values are wrong.

I am using coocox and stmf0 discovery for debugging and programming.

My output:

IP SET READ: 192 168 1 157               (correct)

IP MASK READ: 255 255 255 0            (correct)

MAC ADDRESS  READ: 0 2 0 0 0 1     (correct)

port 1 settings: 2158137817                    (wrong)

port 1 settings: 44dbc55b                          (wrong)

port 2 settings: 8

port 2 settings: 91594a50

Posted on August 31, 2015 at 23:52

An 'unsigned int *ptr;' advances 4 bytes when you increment it by one.

So address += 4; ptr++; mem++;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 01, 2015 at 00:12

#include ''settings.h''
#include ''EE_ethernet.h''
#include ''stm32f10x_flash.h''
//Settings
network_settings_t *network_settings;
port_settings_t *port1_settings;
port_settings_t *port2_settings;
/**
* Data saklama baþlangýç adresi : 0x803F800
* Data saklama bitiþ adresi0 : 0x8040000
*
*
*---------------------------------------------------------------------------------------
* | HEADER | NETWORK SETTINGS | PORT1 SETTINGS | PORT2 SETTINGS | IO SETTINGS |
*---------------------------------------------------------------------------------------
* | erka |
*/
void settings_save(){
FLASH_Status FLASHStatus = FLASH_COMPLETE;
printf(''SAVE SETTINGS SKETCH
'');
char data[] = ''erka'';
uint32_t address = FLASH_USER_START_ADDR;
uint32_t *ptr;
printf(''FLASH Settings are saving...

'');
printf(''network settings size: %d
'',sizeof(network_settings_t));
printf(''network settings address: %
X'',network_settings);
printf(''port 1 settings address: %
X'',port1_settings);
printf(''port 2 settings address: %
X'',port2_settings);
printf(''network settings size: %d
'',sizeof(network_settings_t));
printf(''port1 settings size: %d
'',sizeof(port_settings_t));
printf(''port2 settings size: %d
'',sizeof(port_settings_t));
FLASH_Unlock();
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASHStatus = FLASH_ErasePage(address);
FLASH_WaitForLastOperation(100);
ptr = data; // Signature
FLASH_ProgramWord(address,*ptr++);
FLASH_WaitForLastOperation(100);
address += 4;
ptr = network_settings;
while(ptr < (network_settings + sizeof(network_settings_t))){
FLASH_ProgramWord(address,*ptr++);
FLASH_WaitForLastOperation(100);
address += 4;
}
ptr = port1_settings;
while(ptr < (port1_settings + sizeof(port_settings_t))){
FLASH_ProgramWord(address,*ptr++);
FLASH_WaitForLastOperation(100);
address += 4;
}
ptr = port2_settings;
while(ptr < (port2_settings + sizeof(port_settings_t))){
FLASH_ProgramWord(address,*ptr++);
FLASH_WaitForLastOperation(100);
address += 4;
}
FLASH_Lock();
printf(''settings saved 
'');
}
void settings_set_defaults(){
network_settings->DHCP = 1;
network_settings->gateway.ip1 = 192;
network_settings->gateway.ip2 = 168;
network_settings->gateway.ip3 = 1;
network_settings->gateway.ip4 = 1;
network_settings->ip.ip1 = 192;
network_settings->ip.ip2 = 168;
network_settings->ip.ip3 = 1;
network_settings->ip.ip4 = 157;
network_settings->subnet_mask.ip1 = 255;
network_settings->subnet_mask.ip2 = 255;
network_settings->subnet_mask.ip3 = 255;
network_settings->subnet_mask.ip4 = 0;
network_settings->MAC_ADDRESS[0] = 0;
network_settings->MAC_ADDRESS[1] = 2;
network_settings->MAC_ADDRESS[2] = 0;
network_settings->MAC_ADDRESS[3] = 0;
network_settings->MAC_ADDRESS[4] = 0;
network_settings->MAC_ADDRESS[5] = 1;
port1_settings->baud_rate = 9600;
port1_settings->data_bit = 8;
port1_settings->parity = 0;
port1_settings->port = 4444;
port1_settings->stop_bit = 0;
port2_settings->baud_rate = 9600;
port2_settings->data_bit = 8;
port2_settings->parity = 0;
port2_settings->port = 4445;
port2_settings->stop_bit = 0;
printf(''IP SET: %u %u %u %u 
'',network_settings->ip.ip1, network_settings->ip.ip2, network_settings->ip.ip3, network_settings->ip.ip4);
printf(''IP MASK: %u %u %u %u 
'',network_settings->subnet_mask.ip1, network_settings->subnet_mask.ip2, network_settings->subnet_mask.ip3, network_settings->subnet_mask.ip4);
}
void settings_load(){
unsigned int *mem;
unsigned int *ptr;
printf(''Load Settings From Flash
'');
printf(''Loading Settings...

'');
ptr = network_settings;
mem = (unsigned int*)FLASH_USER_START_ADDR;
mem++; // Step over sig
ptr = network_settings;
while(ptr < (network_settings+sizeof(network_settings)))
*ptr++ = *mem++;
ptr = port1_settings;
while(ptr < (port1_settings+sizeof(port1_settings)))
*ptr++ = *mem++;
ptr = port2_settings;
while(ptr < (port2_settings+sizeof(port2_settings)))
*ptr++ = *mem++;
printf(''IP SET READ: %u %u %u %u 
'',network_settings->ip.ip1, network_settings->ip.ip2, network_settings->ip.ip3, network_settings->ip.ip4);
printf(''IP MASK READ: %u %u %u %u 
'',network_settings->subnet_mask.ip1, network_settings->subnet_mask.ip2, network_settings->subnet_mask.ip3, network_settings->subnet_mask.ip4);
printf(''MAC ADDRESS READ: %x %x %x %x %x %x 
'',network_settings->MAC_ADDRESS[0],network_settings->MAC_ADDRESS[1],network_settings->MAC_ADDRESS[2],network_settings->MAC_ADDRESS[3],network_settings->MAC_ADDRESS[4],network_settings->MAC_ADDRESS[5]);
printf(''port 1 settings: %u 
'', port1_settings->port);
printf(''port 1 settings: %x 
'',port1_settings->stop_bit);
printf(''port 2 settings: %u 
'', port2_settings->port);
printf(''port 2 settings: %x 
'',port2_settings->stop_bit);
}
void settings_init(){
network_settings = (network_settings_t*)malloc(sizeof(network_settings_t));
port1_settings = (port_settings_t*)malloc(sizeof(port_settings_t));
port2_settings = (port_settings_t*)malloc(sizeof(port_settings_t));
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Erkan Ersoy
Associate II
Posted on September 01, 2015 at 12:14

Thank you

I learnt Adding pointer 1 means size of that pointer so that applies network_settings+sizeof(network_settings) line too. So i was adding square of the size Changing code like that fixed problem:

#include ''settings.h''
#include ''EE_ethernet.h''
#include ''stm32f10x_flash.h''
//Settings
network_settings_t *network_settings;
port_settings_t *port1_settings;
port_settings_t *port2_settings;
/**
* Data saklama baþlangýç adresi : 0x803F800
* Data saklama bitiþ adresi0 : 0x8040000
*
*
*---------------------------------------------------------------------------------------
* | HEADER | NETWORK SETTINGS | PORT1 SETTINGS | PORT2 SETTINGS | IO SETTINGS |
*---------------------------------------------------------------------------------------
* | erka |
*/
void settings_save(){
FLASH_Status FLASHStatus = FLASH_COMPLETE;
printf(''SAVE SETTINGS SKETCH
'');
char data[] = ''erka'';
uint32_t address = FLASH_USER_START_ADDR;
uint32_t *ptr;
uint32_t limitAddress = 0;
ptr = data;
printf(''FLASH Settings are saving...

'');
printf(''network settings size: %d
'',sizeof(network_settings_t));
printf(''network settings address: %
X'',network_settings);
printf(''port 1 settings address: %
X'',port1_settings);
printf(''port 2 settings address: %
X'',port2_settings);
printf(''network settings size: %d
'',sizeof(network_settings_t));
printf(''port1 settings size: %d
'',sizeof(port_settings_t));
printf(''port2 settings size: %d
'',sizeof(port_settings_t));
FLASH_Unlock();
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASHStatus = FLASH_ErasePage(FLASH_USER_START_ADDR);
FLASH_WaitForLastOperation(100);
FLASH_ProgramWord(FLASH_USER_START_ADDR,*ptr);
FLASH_WaitForLastOperation(100);
ptr = network_settings;
address += 4;
// limitAddress = network_settings + 1);
while(ptr < 
network_settings
+1){
FLASH_ProgramWord(address,*ptr);
FLASH_WaitForLastOperation(100);
address += 4;
ptr ++;
}
//
limitAddress
= 
port1_settings
+ 1);
ptr
= 
port1_settings
;
while(ptr < port1_settings+1){
FLASH_ProgramWord(address,*ptr);
FLASH_WaitForLastOperation(100);
address += 4;
ptr++;
}
//
limitAddress
= 
port2_settings
+ 1);
ptr
= 
port2_settings
;
while(ptr < port2_settings+1){
FLASH_ProgramWord(address,*ptr);
FLASH_WaitForLastOperation(100);
address += 4;
ptr++;
}
FLASH_Lock();
printf(''settings saved 
'');
}
void settings_set_defaults(){
network_settings->DHCP = 1;
network_settings->gateway.ip1 = 192;
network_settings->gateway.ip2 = 168;
network_settings->gateway.ip3 = 1;
network_settings->gateway.ip4 = 1;
network_settings->ip.ip1 = 192;
network_settings->ip.ip2 = 168;
network_settings->ip.ip3 = 1;
network_settings->ip.ip4 = 157;
network_settings->subnet_mask.ip1 = 255;
network_settings->subnet_mask.ip2 = 255;
network_settings->subnet_mask.ip3 = 255;
network_settings->subnet_mask.ip4 = 0;
network_settings->MAC_ADDRESS[0] = 0;
network_settings->MAC_ADDRESS[1] = 2;
network_settings->MAC_ADDRESS[2] = 0;
network_settings->MAC_ADDRESS[3] = 0;
network_settings->MAC_ADDRESS[4] = 0;
network_settings->MAC_ADDRESS[5] = 1;
port1_settings->baud_rate = 9600;
port1_settings->data_bit = 8;
port1_settings->parity = 0;
port1_settings->port = 4444;
port1_settings->stop_bit = 0;
port2_settings->baud_rate = 9600;
port2_settings->data_bit = 8;
port2_settings->parity = 0;
port2_settings->port = 4445;
port2_settings->stop_bit = 0;
printf(''IP SET: %u %u %u %u 
'',network_settings->ip.ip1, network_settings->ip.ip2, network_settings->ip.ip3, network_settings->ip.ip4);
printf(''IP MASK: %u %u %u %u 
'',network_settings->subnet_mask.ip1, network_settings->subnet_mask.ip2, network_settings->subnet_mask.ip3, network_settings->subnet_mask.ip4);
}
void settings_load(){
unsigned int *mem;
unsigned int *ptr;
printf(''Load Settings From Flash
'');
printf(''Loading Settings...

'');
ptr = network_settings;
mem = (unsigned int*)FLASH_USER_START_ADDR;
mem ++; //step over header
ptr = network_settings;
while(ptr < (network_settings+1))
*ptr++ = *mem++;
ptr = port1_settings;
while(ptr < (port1_settings+1))
*ptr++ = *mem++;
ptr = port2_settings;
while(ptr < (port2_settings+1))
*ptr++ = *mem++;
printf(''IP SET READ: %u %u %u %u 
'',network_settings->ip.ip1, network_settings->ip.ip2, network_settings->ip.ip3, network_settings->ip.ip4);
printf(''IP MASK READ: %u %u %u %u 
'',network_settings->subnet_mask.ip1, network_settings->subnet_mask.ip2, network_settings->subnet_mask.ip3, network_settings->subnet_mask.ip4);
printf(''MAC ADDRESS READ: %x %x %x %x %x %x 
'',network_settings->MAC_ADDRESS[0],network_settings->MAC_ADDRESS[1],network_settings->MAC_ADDRESS[2],network_settings->MAC_ADDRESS[3],network_settings->MAC_ADDRESS[4],network_settings->MAC_ADDRESS[5]);
printf(''port 1 port read: %u 
'', port1_settings->port);
printf(''port 1 stop bit read: %x 
'',port1_settings->stop_bit);
printf(''port 1 baudrate read: %u 
'',port1_settings->baud_rate);
printf(''port 2 port read: %u 
'', port2_settings->port);
printf(''port 2 stop bit read: %x 
'',port2_settings->stop_bit);
printf(''port 2 baudrate read: %u 
'',port2_settings->baud_rate);
}
void settings_init(){
network_settings = (network_settings_t*)malloc(sizeof(network_settings_t));
port1_settings = (port_settings_t*)malloc(sizeof(port_settings_t));
port2_settings = (port_settings_t*)malloc(sizeof(port_settings_t));
}