Problem to write files in the flash memory!

I'm working on a project that I need to write a file in the flash memory, but when I calling the function to open file (fs_open), the microcontroller crashes completely and the following message appears:


->E: ***** MPU FAULT *****
->E: Stacking error (context area might be not valid)
->E: Data Access Violation
->E: MMFAR Address: 0x200159b8
->E: r0/a1: 0x8625890d r1/a2: 0x911daf84 r2/a3: 0x8779922f
->E: r3/a4: 0xfe8bd497 r12/ip: 0xd8dc16c8 r14/lr: 0xb98b5e52
->E: xpsr: 0x5fd38800
->E: Faulting instruction address (r15/pc): 0xac1da62a
->E: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0
->E: Current thread: 0x20001be8 (unknown)
->E: Halting system

- Libraries used to file system:

#include <zephyr/storage/flash_map.h>
#include <zephyr/fs/fs.h>
#include <zephyr/fs/littlefs.h>
- Functions to WriteFile, ReadFile, RemoveFile, etc:
ssize_t sirros_readFile(char * file_name, char* file_content, size_t file_size, off_t file_pos) {
	char caminho_arquivo[MAX_FILE_PATH_LEN];
	struct fs_file_t file;
	int ret;
	ssize_t read_size;
	snprintf(caminho_arquivo, sizeof(caminho_arquivo), "%s%s", mp->mnt_point, file_name);
	fs_file_t_init(&file);

	ret = fs_open(&file, caminho_arquivo, FS_O_READ);
	if (ret)
		return 0;
		
	if (file_pos != 0)
		fs_seek(&file, file_pos, FS_SEEK_SET);

	read_size = fs_read(&file, file_content, file_size);
	ret = fs_close(&file);
	file_content[read_size] = 0;
	return read_size;
}

bool sirros_writeFile(char * file_name, char* file_content, size_t file_size, off_t file_pos) {
	//printf("entrei na writeFile");
	char caminho_arquivo[MAX_FILE_PATH_LEN];
	struct fs_file_t file;
	int ret;
	size_t written_size = 0;
	//printf("parte 1");
	snprintf(caminho_arquivo, sizeof(caminho_arquivo), "%s%s", mp->mnt_point, file_name);
	//printf("parte 2");
	fs_file_t_init(&file);
	//printf("parte 3");
	ret = fs_open(&file, caminho_arquivo, FS_O_CREATE | FS_O_WRITE);
	//printf("parte 4");
	if(ret < 0)
		return false;
    //printf("parte 5");
	if (file_pos != 0)
		fs_seek(&file, file_pos, FS_SEEK_SET);
   
	if(file_size == 0)
		file_size = strlen(file_content);

	written_size = fs_write(&file, file_content, file_size);
	ret = fs_close(&file);
	return written_size == file_size;
}

bool sirros_appendFile(char * file_name, char* file_content, size_t file_size) {
	char caminho_arquivo[MAX_FILE_PATH_LEN];
	struct fs_file_t file;
	int ret;
	size_t written_size = 0;
	snprintf(caminho_arquivo, sizeof(caminho_arquivo), "%s%s", mp->mnt_point, file_name);
	fs_file_t_init(&file);
		ret = fs_open(&file, caminho_arquivo, FS_O_CREATE | FS_O_APPEND);
	if(ret < 0)
		return false;

	if(file_size == 0)
		file_size = strlen(file_content);

	written_size = fs_write(&file, file_content, file_size);
	ret = fs_close(&file);
	return written_size == file_size;
}

bool sirros_existsFile(char * file_name) {
	char caminho_arquivo[MAX_FILE_PATH_LEN];
	struct fs_file_t file;
	int ret;
	snprintf(caminho_arquivo, sizeof(caminho_arquivo), "%s%s", mp->mnt_point, file_name);
	fs_file_t_init(&file);
	ret = fs_open(&file, caminho_arquivo, 0);
	fs_close(&file);
	return ret == 0;
}

bool sirros_removeFile(char * file_name) {
	char caminho_arquivo[MAX_FILE_PATH_LEN];
	snprintf(caminho_arquivo, sizeof(caminho_arquivo), "%s%s", mp->mnt_point, file_name);
	int ret = fs_unlink(caminho_arquivo);
	return ret == 0;
}
Code snippet where I call the function:
- Write:
	sprintf(payload_id_char, "%d", payload_id);
	sirros_removeFile("/arq_id.txt");
	sirros_writeFile("/arq_id.txt", &payload_id_char, strlen(payload_id_char), 0);
- Read:
	sirros_readFile("/arq_id.txt", payload_id_char, sizeof(payload_id_char), 0);
	payload_id = atoi(payload_id_char);
	printf("payload_id: %i", payload_id);
OBS.: "payload_id" is an int variable and "payload_id_char" is a char variable.
Parents
  • Hi 
    Answering your question, yes I'm trying to connect, write and read from the same external flash device in both cases
    I will post here correctly what is and what is not working.

    WORKING:

    The code snippet below, is a function that I call in setup(). The idea is that when my device starts, it updates and assigns the value of the variables that are inside the "/parametros.json" file. (line 69-78)

    void sirros_begin() {  //função para inicializar a configuração do dispositivo
    	printf("BEGIN\n");
    	uint32_t ret = 0;
    	if (!fs_mounted) {
    		ret = littlefs_mount(mp);
    		if (ret < 0) {
    			printf("FALHA AO MONTAR O FS");
    			sirros_noParameters();
    			goto final_begin;
    		}
    		fs_mounted = true;
    	}
    
    	uint8_t baseMac[6];
    	get_mac_address(baseMac);
    	sprintf(sirros.mac_string, "%02X:%02X:%02X:%02X:%02X:%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
    	
    	normal = sirros_existsFile("/parametros.json");
    	backup = sirros_existsFile("/backup.json");
    	printf("normal: %i, backup: %i\n", normal, backup);
    	if ((normal | backup) == 0) {
    		sirros_noParameters();
    		goto final_begin;
    	}
    
    	char parameters_string[CONFIG_FILE_MAX_SIZE];
    	ssize_t read_size = sirros_readFile(normal ? "/parametros.json" : "/backup.json", parameters_string, sizeof(parameters_string), 0);
    	
    	if (read_size <= 0) {
    		printf("NÃO LEU:%i\n", read_size);
    		sirros_noParameters();
    		goto final_begin;
    	}
    
    		
    	printf("Parametros LIDO:%i\n%s\n", read_size, parameters_string);
    	ret = json_obj_parse(parameters_string,//string de entrada com o JSON
    					sizeof(parameters_string),
    					parametersFile_descr,//descrição da struct de configuração
    					ARRAY_SIZE(parametersFile_descr),
    					&sirros);//struct com todas as variáveis de configuração
    	
    	if (ret < 0) {
    		printf("JSON Parse Error: %i\n", ret);
    		if (normal)
    			sirros_removeFile("/parameters.json");
    		else
    			sirros_removeFile("/backup.json");
    		sirros_noParameters();
    	}
    	else {
    		printf("JSON Parse return code: "BYTE_TO_BINARY_PATTERN BYTE_TO_BINARY_PATTERN BYTE_TO_BINARY_PATTERN BYTE_TO_BINARY_PATTERN"\n", 
    				BYTE_TO_BINARY(ret >> 24), BYTE_TO_BINARY(ret >> 16), BYTE_TO_BINARY(ret >> 8), BYTE_TO_BINARY(ret));
    		if(!(ret & 0x01)) { 
    			//se o bit do nome não foi setado, ou seja não encontrou o campo do nome, considera que o arquivo tá bugado
    			sirros_noParameters();
    			goto final_begin;
    		}
    		strcpy(sirros.nome, sirros.nome_buf);		
    		strcpy(sirros.topico, sirros.topico_buf);
    		strcpy(sirros.subtopico, sirros.subtopico_buf);
    		printf("nome_buf: %s\n", sirros.nome_buf);
    		sirros.timeout = constrain(sirros.timeout, 20, 1000);
    		printf("nome: %s\n", sirros.nome);
    		printf("timezone: %i\n", sirros.timezone);
    		printf("readtime: %i\n", sirros.readtime);
    		printf("samples: %i\n", sirros.samples);
    		printf("payload_id: %i\n", sirros.payload_id);
    		if(normal) {
    			read_size = sirros_readFile("/parametros.json", parameters_string, sizeof(parameters_string), 0);
    			sirros_removeFile("/backup.json");
    			sirros_writeFile("/backup.json", parameters_string, strlen(parameters_string), 0);
    		} else {
    			read_size = sirros_readFile("/backup.json", parameters_string, sizeof(parameters_string), 0);
    			sirros_removeFile("/parametros.json");
    			sirros_writeFile("/parametros.json", parameters_string, strlen(parameters_string), 0);
    		}
    	}
    final_begin:
      	if (sirros.subtopico[0] != 0)
    		snprintf(sirros.topico_completo, sizeof(sirros.topico_completo), 
    			"/dev/%s/%s/%s/data", sirros.topico, sirros.subtopico, sirros.nome);
      	else
        	snprintf(sirros.topico_completo, sizeof(sirros.topico_completo), 
    			"/dev/%s/%s/data", sirros.topico, sirros.nome);
    	printf("TOPICO: %s\n", sirros.topico_completo);
    	printf("MAC: %s\n", sirros.mac_string);
    	sirros_bt_begin(sirros.nome);
    }

    NON-WORKING:


    The code snippet below, is a function that I call in loop() in some moments. The idea is write in file the value of variable named "payload_id", because my project works with sleep_mode, so when the code restart, I need the payload_id variable value to stay with its value. (line 23-26)

    void formata_payloads_json() {
    	for (uint8_t eixo = 0; eixo < 3; eixo++) {		
    		for (uint16_t pos = 0; pos < OUTPUT_PAYLOAD_SIZE; pos++) //limpa a string
    			output_payload[eixo][pos] = 0;
    		
    		snprintf(output_payload[eixo], 7, "{\"%c\":[", eixo + 'x');//printa o começo do payload
    
    		char payload_buf[110];
    		uint16_t pos = 0;
    		snprintf(payload_buf, sizeof(payload_buf), "%.2f", accel_real[eixo][pos]);
    		strcat(output_payload[eixo], payload_buf);
    		for (uint16_t pos = 1; pos < sirros.samples; pos++){
    			snprintf(payload_buf, sizeof(payload_buf), ",%.2f", accel_real[eixo][pos]);
    			strcat(output_payload[eixo], payload_buf);
    		}
    
    		snprintf(payload_buf, sizeof(payload_buf),"],\"leitura\":%i,\"unit\":\"us\",\"id\":%i,\"gravidadeZero\":%.2f,\"temperatura\":%f,\"firmware\":\"%s\"}", 
    			sirros.readtime, payload_id, (grav_zero[eixo]/ GRAVIDADE), temperatura_atual, sirros.firmware);
    
    		strcat(output_payload[eixo], payload_buf);
    		printf("Payload do eixo %c:\n%s\n", eixo + 'x', output_payload[eixo]);
    	}
    	payload_id++;
    	sprintf(payload_id_char, "%d", payload_id);
    	sirros_removeFile("/arq_id.txt");
    	sirros_writeFile("/arq_id.txt", &payload_id_char, strlen(payload_id_char), 0);
    }

    I read the file in setup(). Below is the function:

    void setup() {
    	nrf_gpio_cfg_output(MPU_VCC);
    	nrf_gpio_pin_write(MPU_VCC, 0);
    	strcpy(sirros.firmware, FIRMWARE_VERSION);
    	char cmd_response[100];
    	//sirros_parseCMD("set.config({\"nome\":\"beacon-01\",\"topico\":\"sirrosteste\",\"subtopico\":\"predicao\",\"timezone\":-3,\"readtime\":200,\"sleeptime\":120,\"samples\":200,\"timeout\":30})", cmd_response);
    	sirros_begin();
    	sirros_registerCallbackWithoutParameters("set.calibrate", calibrate);
    	sirros_registerCallbackWithoutParameters("get.id", id);
    
    	mpu6050 = DEVICE_DT_GET_ONE(invensense_mpu6050);
    	printf("MPU6050");
    	if (!device_is_ready(mpu6050)) 
    		printk(" nao");
    	printf(" respondeu\n");
    
    	max6675 = DEVICE_DT_GET_ONE(maxim_max6675);
    	printf("MAX6675");
    	if (!device_is_ready(max6675))
    		printk(" nao");
    	printf(" respondeu\n");
    
    	int rc = read_max6675(max6675, &temperatura_atual);
    	if (rc != 0) 
    		printf("MAX ERROR\n");
    
    	transfer_handler.readTransfer = &read_data_callback;
    	transfer_handler.startTransfer = &write_data_callback;
    
    	sirros_readFile("/arq_id.txt", payload_id_char, sizeof(payload_id_char), 0);
    	payload_id = atoi(payload_id_char);
    	printf("payload_id: %i", payload_id);
    
    	calibrate(NULL);
    	leitura();
    }

  • Hi
    Correcting a point that I expressed wrongly. I had commented that the function formata_payloads_json() was called inside the loop(), but it is actually called inside a bluettoth callback. Below is the code snippet of bluettoth callback:

    ssize_t write_data_callback(struct bt_conn *conn, const struct bt_gatt_attr *attr,
    			const void *buf, uint16_t len, uint16_t offset, uint8_t flags) {
    	const char *value = attr->user_data;
    	printf("Comando: %s\n", value);
    	if (strcmp(value, "startAxis") == 0) {
    		leitura();
    		formata_payloads_json();
    		transfer_handler.source = NULL;
    	}
    	if (strncmp(value, "get.", 4) == 0) {
    		uint8_t eixo = value[4] - 'x';
    		printf("eixo: %i\n", eixo);
    		sirros_bt_transfer_start(&transfer_handler, output_payload[eixo]);
    	}
    	return len;
    }

Reply
  • Hi
    Correcting a point that I expressed wrongly. I had commented that the function formata_payloads_json() was called inside the loop(), but it is actually called inside a bluettoth callback. Below is the code snippet of bluettoth callback:

    ssize_t write_data_callback(struct bt_conn *conn, const struct bt_gatt_attr *attr,
    			const void *buf, uint16_t len, uint16_t offset, uint8_t flags) {
    	const char *value = attr->user_data;
    	printf("Comando: %s\n", value);
    	if (strcmp(value, "startAxis") == 0) {
    		leitura();
    		formata_payloads_json();
    		transfer_handler.source = NULL;
    	}
    	if (strncmp(value, "get.", 4) == 0) {
    		uint8_t eixo = value[4] - 'x';
    		printf("eixo: %i\n", eixo);
    		sirros_bt_transfer_start(&transfer_handler, output_payload[eixo]);
    	}
    	return len;
    }

Children
Related