FreeRTOS, read file from SD card

C,C++,C#

Moderátori: psichac, Moderátori

Používateľov profilový obrázok
jirka.jirka.
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1236
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

FreeRTOS, read file from SD card

Príspevok od používateľa jirka.jirka. » 30 Mar 2020, 18:18

Zdravím přátelé, kamarádi,

do firmwaru jsem se rozhodl implementovat načtení IP adres atp z SD karty. Ale veznu popořadě.

Kód: Vybrať všetko

FLAG ReadConfigFileFromSD(char **_ip_address, char **_ip_mask, char **_ip_gateway,
		char **_ip_sntp, char **_ip_modbus, int32_t *_port_modbus) {

	FIL file;
	FRESULT fresult;
	char SD_Buffer[16*1024];
	volatile uint32_t NumberLines;
	int32_t temp_val;

	//
	InfoPrint("opening SDCARD file -> /code/ip.conf  ...");

	// try to open - read only
	fresult = f_open((FIL*) &file, (char*) "0:/code/ip.config", FA_READ);

	// open and valid ?
	if (FR_OK != fresult) {
		ErrPrint("FILE NOT FOUND on sd-card -> FAIL");
		return FALSE;
	}
	/* Read the file */
	fresult = f_read((FIL*) &file, SD_Buffer, sizeof SD_Buffer, NULL);

	/* Close file */
	fresult = f_close((FIL*) &file);

	/* split buffer for lines */
	char** arr = strsplit(SD_Buffer, "\n");

	for (uint32_t i = 0; SD_Buffer[i] != '\0'; ++i) {
		if ('\n' == SD_Buffer[i])
			++NumberLines;
	}

	for(uint8_t i=0; i <= NumberLines; i++)
	{
		if (strstr(arr[i], "IP_ADDR") != NULL) {
			char **temp = strsplit(arr[i], " ");
			//InfoPrint("IP ADRESA: %s", temp[1]);
			*_ip_address = temp[1];
			free(temp);
		}
		if (strstr(arr[i], "IP_MASK") != NULL) {
			char **temp = strsplit(arr[i], " ");
			//InfoPrint("IP MASK: %s", temp[1]);
			*_ip_mask = temp[1];
			free(temp);
		}
		if (strstr(arr[i], "IP_GTW") != NULL) {
			char **temp = strsplit(arr[i], " ");
			//InfoPrint("IP GATEWAY: %s", temp[1]);
			*_ip_gateway = temp[1];
			free(temp);
		}
		if (strstr(arr[i], "IP_SNTP") != NULL) {
			char **temp = strsplit(arr[i], " ");
			//InfoPrint("IP SNTP: %s", temp[1]);
			*_ip_sntp = temp[1];
			free(temp);
		}
		if (strstr(arr[i], "IP_MODBUS") != NULL) {
			char **temp = strsplit(arr[i], " ");
			//InfoPrint("IP MODBUS: %s", temp[1]);
			*_ip_modbus = temp[1];
			free(temp);
		}
		if (strstr(arr[i], "PORT_MODBUS") != NULL) {
			char **temp = strsplit(arr[i], " ");
			//InfoPrint("PORT MODBUS: %s", temp[1]);
			temp_val = atoi(temp[1]);
			*_port_modbus = temp_val;
			free(temp);
		}
	}

	//InfoPrint("%s", ip_address_str[ip_adrr]);

	free(arr);

	return TRUE;
}
Funkce, funguje dobře.

Kód: Vybrať všetko

strsplit
Dále, pokud funkci zavolám a vytisknu si hodnoty do konzole z funkce "ReadConfigFileFromSD", tak je všechno načteno dobře. Ale problém nastane, když tu funkci zavolám z tasku...

Kód: Vybrať všetko

void vCoreTask(void *pvParameters) {
	char *ip_address, *ip_mask, *ip_gateway, *ip_sntp, *ip_modbus, *ip_syslog, *ip_influx;
	int32_t port_modbus;

	ip_address = (char*)malloc(18*sizeof(char));
	ip_mask = (char*)malloc(18*sizeof(char));
	ip_gateway = (char*)malloc(18*sizeof(char));
	ip_sntp = (char*)malloc(18*sizeof(char));
	ip_modbus = (char*)malloc(18*sizeof(char));
if (ReadConfigFileFromSD(&ip_address, &ip_mask, &ip_gateway, &ip_sntp,
			&ip_modbus, &port_modbus, &ip_syslog, &port_syslog, &ip_influx,
			&port_influx, &port_azimuth) == TRUE)
	{
		InfoPrint("read IP addresses from memory: OK");
	}
	else
	{
		ErrPrint("read IP addresses from memory: FAIL");
	}

	InfoPrint("IP: %s", ip_address);
	InfoPrint("MASK: %s", ip_mask);
	InfoPrint("GTW: %s", ip_gateway);
	InfoPrint("SNTP: %s", ip_sntp);
	InfoPrint("MOD: %s", ip_modbus);
	InfoPrint("PMOD: %d", port_modbus);

while(1)
{}
}
A v7stup je potom>
  • IP: "10.1.1.7"
    MASK: _PORT
    GTW: PORT
    SNTP: ORT
    MOD: T
    PMOD: 502
A vstupní data:

Kód: Vybrať všetko

# Nastaveni IP adresy desky
IP_BOARD "10.1.1.7"
IP_BOARD "255.255.255.0"
IP_GTW "10.1.1.2"

# Nastaveni IP adresy ntp serveru
IP_SNTP "10.1.1.106"

# Nastaveni IP adresy a portu pro MODbus
IP_MODBUS "10.1.1.30"
PORT_MODBUS 502
A zde se mi nedaří najít, proč se mi přepisují data. Spíše kde, nebo čím. Nějaký nápad?
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2074
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 53
Kontaktovať používateľa:

Príspevok od používateľa peterple » 30 Mar 2020, 18:42

nebude to tým že strsplit nie je reentrantná?
http://www.martinbroadhurst.com/split-a ... -in-c.html
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Používateľov profilový obrázok
jirka.jirka.
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1236
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Príspevok od používateľa jirka.jirka. » 30 Mar 2020, 19:18

Nebude. :biggrin:

V mé fci ReadConfigFileFromSD jsem udělal temp:

Kód: Vybrať všetko

char **temp;
	temp = (char**)malloc(100*sizeof(char));
A free jsem smazal a dal až nakonec.

Nyní už je to OK.

Tzn:

Kód: Vybrať všetko

	

char **temp;
temp = (char**)malloc(100*sizeof(char));
...
...
...
if (strstr(arr[i], "IP_ADDR") != NULL) {
	temp = strsplit(arr[i], " ");
	*_ip_mask = temp[1];
}
...
...
...
free(temp);
0

Používateľov profilový obrázok
jirka.jirka.
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1236
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Príspevok od používateľa jirka.jirka. » 30 Mar 2020, 20:21

Jinak, ano je reentantná. :thumbup:

Ale použil jsem ji v mém tasku, kde ještě žádný task neběží a zde jej teprve inicializuji. Kde teprve setuju lwIP, RTC, modbus, syslogy, influx, láduju FPGA a atp. A ještě jsem tasky nespustil.

Takže si to můžu dovolit. Ale nacpat to někam jinam bych nepochodil. :thumbup: To bych skončil typuju pádem celého MCU.
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2074
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 53
Kontaktovať používateľa:

Príspevok od používateľa peterple » 30 Mar 2020, 20:58

Práveže nie je reentrantná. Teda že nemôže byť prerušená a neskôr opakovane vyvolaná, dokiaľ sa tá prerušená nedokončí.
Ale myslím len že si sa len zle vyjadril.

Pádom by to skončiť nemalo. Celý problém je len v tom že používa nejaké globálne premenné, ktoré sa tým pádom prepíšu. Teraz neviem či to je nejaký ukazateľ alebo nie. Ale aj keby, asi ten system nemá nejakú ochranu pamäte a teda to zbehne aj keby tá pamäť bolo dealokovaná.
Použitie takejto funkcie v multitaskingu vedie zvyčajne k prúseru, ktorý sa objaví iba raz začas (samozrejme v ten najnevhodnejší).
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok