nvs key_name problem

ikerbelloso
Posts: 20
Joined: Wed Jul 27, 2016 7:34 am

nvs key_name problem

Postby ikerbelloso » Tue Apr 04, 2017 1:14 pm

Hi there,
I'm trying to implement a flash log of relevant events using nvs api. The idea was having nvs namespace were events are stored sequentially and then they can be retrieved when required.
For that I've set a name pattern, like "entryXX" where XX is the number of event. So each time a new event happens, y set a blob into the nvs space with key_name "entry00", "entry01"... etc..
Then I wanted to retrieve the events in reverse order and I was getting always one entry OK and then the following with ESP_ERR_NVS_NOT_FOUND error.
This is a simplified version of what I was doing... (I've removed some verification for simplicity)

Code: Select all

typedef struct{
	uint8_t var1;
	uint16_t var2;
	uint64_t var3;
	char var4[27];
}test_struct;

void Test_blob(void){

	nvs_handle out_handle;
	size_t test_size = sizeof(test_struct);
	char key_name[16];
	test_struct str1= {1,1000,1000000,"struct1"};
	test_struct str2= {2,2000,2000000,"struct2"};
	test_struct str3= {3,3000,3000000,"struct3"};
	test_struct str4= {4,4000,4000000,"struct4"};


	ESP_ERROR_CHECK(nvs_open("blob_test", NVS_READWRITE, &out_handle))

	sprintf(key_name,"str%x",1);
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name,(const void*)&str1,sizeof(test_struct)));
	sprintf(key_name,"str%x",2);
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name,(const void*)&str2,sizeof(test_struct)));
	sprintf(key_name,"str%x",3);
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name,(const void*)&str3,sizeof(test_struct)));
	sprintf(key_name,"str%x",4);
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name,(const void*)&str4,sizeof(test_struct)));

	memset(&str1,0x00,sizeof(test_struct));
	memset(&str2,0x00,sizeof(test_struct));
	memset(&str3,0x00,sizeof(test_struct));
	memset(&str4,0x00,sizeof(test_struct));

	sprintf(key_name,"str%x",4);
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,( void*)&str4,&test_size));

	sprintf(key_name,"str%x",3);
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,( void*)&str3,&test_size));

	sprintf(key_name,"str%x",2);
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,( void*)&str2,&test_size));

	sprintf(key_name,"str%x",1);
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,( void*)&str1,&test_size));

}
the error arises getting "str3" item size.
Then making some tests, I noticed that if I retrieved them into the input order, I had no problem:

Code: Select all

typedef struct{
	uint8_t var1;
	uint16_t var2;
	uint64_t var3;
	char var4[27];
}test_struct;

void Test_blob(void){

	nvs_handle out_handle;
	size_t test_size = sizeof(test_struct);
	char key_name[16];
	test_struct str1= {1,1000,1000000,"struct1"};
	test_struct str2= {2,2000,2000000,"struct2"};
	test_struct str3= {3,3000,3000000,"struct3"};
	test_struct str4= {4,4000,4000000,"struct4"};


	ESP_ERROR_CHECK(nvs_open("blob_test", NVS_READWRITE, &out_handle))

	sprintf(key_name,"str%x",1);
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name,(const void*)&str1,sizeof(test_struct)));
	sprintf(key_name,"str%x",2);
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name,(const void*)&str2,sizeof(test_struct)));
	sprintf(key_name,"str%x",3);
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name,(const void*)&str3,sizeof(test_struct)));
	sprintf(key_name,"str%x",4);
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name,(const void*)&str4,sizeof(test_struct)));

	memset(&str1,0x00,sizeof(test_struct));
	memset(&str2,0x00,sizeof(test_struct));
	memset(&str3,0x00,sizeof(test_struct));
	memset(&str4,0x00,sizeof(test_struct));

	sprintf(key_name,"str%x",1);
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,( void*)&str4,&test_size));

	sprintf(key_name,"str%x",2);
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,( void*)&str3,&test_size));

	sprintf(key_name,"str%x",3);
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,( void*)&str2,&test_size));

	sprintf(key_name,"str%x",4);
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name,( void*)&str1,&test_size));

}
Then Iv'e noticed that the nvs_get_blob function requires a "const char" as key name so switching to this approach :

Code: Select all

typedef struct{
	uint8_t var1;
	uint16_t var2;
	uint64_t var3;
	char var4[27];
}test_struct;

void Test_blob(void){

	nvs_handle out_handle;
	size_t test_size = sizeof(test_struct);
	const char key_name[4][5]={"str1","str2","str3","str4"};
	test_struct str1= {1,1000,1000000,"struct1"};
	test_struct str2= {2,2000,2000000,"struct2"};
	test_struct str3= {3,3000,3000000,"struct3"};
	test_struct str4= {4,4000,4000000,"struct4"};


	ESP_ERROR_CHECK(nvs_open("blob_test", NVS_READWRITE, &out_handle))


	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name[0],(const void*)&str1,sizeof(test_struct)));
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name[1],(const void*)&str2,sizeof(test_struct)));
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name[2],(const void*)&str3,sizeof(test_struct)));
	ESP_ERROR_CHECK(nvs_set_blob(out_handle, key_name[3],(const void*)&str4,sizeof(test_struct)));

	memset(&str1,0x00,sizeof(test_struct));
	memset(&str2,0x00,sizeof(test_struct));
	memset(&str3,0x00,sizeof(test_struct));
	memset(&str4,0x00,sizeof(test_struct));

	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name[3],NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name[3],( void*)&str4,&test_size));

	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name[2],NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name[2],( void*)&str3,&test_size));

	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name[1] ,NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name[1],( void*)&str2,&test_size));

	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name[0],NULL,&test_size));
	ESP_ERROR_CHECK(nvs_get_blob(out_handle, key_name[0],( void*)&str1,&test_size));
	
}
I solved the order problem using const cha* keynames but it forces me to have a huge const char keyname array to be able to save a useful number of events.
Is there any alternative solution to have dynamic key_names?
Thank you

ESP_igrr
Posts: 2067
Joined: Tue Dec 01, 2015 8:37 am

Re: nvs key_name problem

Postby ESP_igrr » Tue Apr 04, 2017 2:51 pm

This is indeed a bug, thanks for the report. Will fix.

Who is online

Users browsing this forum: Google [Bot] and 203 guests