cancel
Showing results for 
Search instead for 
Did you mean: 

stm32cubeide fatfs f_close FS_DISK_ERR

MSilv.1
Associate III

I have a board with stm32f407zgt6. I'm using freertos and fatfs. The board has a connection for an SDCARD, I'm using a 4GB SDCARD with fat32.

For reading, F_open, f_read, f_close, everything works. When I use it to write, f_close takes a long time and returns FS_DISK_ERR.

What do you need, files, the .ioc, the sources, no problem, to help me find the problem? I tried to configure it as correctly as possible, but I think I left something behind.

The write process it's in the file ESP8266_HALL.cpp, this file I put in the body of the post, because the forum did not accept the file for a reason that I did not understand, but I will not fight with the forum, I really want help.

Thank you very much.

PS: f_write return the correct amount of bytes written, with what I ordered to be written. the file, after the f_close error, has 0 bytes on the disk. This happens both for already existing files and for new files

 

 

/*
 * ESP8266_HAL.c
 *
 *  Created on: Apr 14, 2020
 *      Author: Controllerstech
 */


#include "UartRingbuffer_multi.h"
#include "ESP8266_HAL.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "fatfs.h"
#include "MCUFRIEND_kbv.h"

extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;

extern TIM_HandleTypeDef htim11;
extern TIM_HandleTypeDef htim13;

#define wifi_uart &huart1
#define pc_uart &huart2

#define FORWARD  1
#define BACKWARD 2
#define BRAKE    3
#define RELEASE  4

extern MCUFRIEND_kbv tft;

char buffer[20];

char *Basic_inclusion = (char*)"<!DOCTYPE html> <html>\n<head><meta name=\"viewport\"\
		content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n\
		<title>MMSJ800</title>\n<style>html { font-family: Helvetica; \
		display: inline-block; margin: 0px auto; text-align: center;}\n\
		body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\
		h3 {color: #444444;margin-bottom: 50px;}\n.p {font-size: 14px;color: #888;margin-bottom: 10px;}\n\
		</style>\n</head>\n<body>\n<h1>MMSJ800</h1>\n";

char *Terminate = (char*)"</body></html>";



/*****************************************************************************************************************************************/

//--------------------------------------------------------------------------------
char ESP_Init (char *SSID, char *PASSWD)
{
	char data[80];
	Ringbuf_init();
	char vError = 0;

	Uart_sendstring("\r\n\r\nStarting...\r\n", pc_uart);

	tft.print(".");
	Uart_sendstring("AT+RST\r\n", wifi_uart);
	Uart_sendstring("RESETTING.", pc_uart);
	for (int i=0; i<5; i++)
	{
		HAL_Delay(1000);
	}

	/********* AT **********/
	Uart_flush(wifi_uart);
	Uart_sendstring("AT\r\n", wifi_uart);
	while(1)
	{
		if (Wait_for((char*)"OK\r\n", wifi_uart))
		{
			Uart_sendstring("OK\r\n", pc_uart);
			break;
		}
		else if (Wait_for((char*)"Error\r\n", wifi_uart))
		{
			Uart_sendstring("Error\r\n", pc_uart);
			vError = 1;
			break;
		}
	}
	if (vError)
	{
		tft.print("...Error!!!");
		Uart_sendstring("\r\nAT---->ERROR\r\n", pc_uart);
		return -1;
	}

	tft.print(".");
	Uart_sendstring("\r\nAT---->OK\r\n", pc_uart);

//	tft.fillScreen(TFT_BLACK);
//	tft.setCursor(0, 16);

	/********* AT+CWJAP="SSID","PASSWD" **********/
	Uart_flush(wifi_uart);
	Uart_sendstring("connecting... to the provided AP\r\n", pc_uart);
	sprintf (data, "AT+CWJAP=\"%s\",\"%s\"\r\n", SSID, PASSWD);
	Uart_sendstring(data, wifi_uart);
	HAL_Delay(3000);
	while(1)
	{
		if (Wait_for((char*)"OK\r\n", wifi_uart))
			break;
		else if (Wait_for((char*)"Error\r\n", wifi_uart))
		{
			vError = 1;
			break;
		}
	}
	if (vError)
	{
		Uart_sendstring("Error Connecting\r\n", pc_uart);
		return -1;
	}

	tft.println(".");
	sprintf (data, "Connected to \"%s\"", SSID);
	tft.print(data);
	Uart_sendstring(data,pc_uart);
	Uart_sendstring("\r\n",pc_uart);

	/********* AT+CWMODE=1 **********/
	Uart_flush(wifi_uart);
	Uart_sendstring("AT+CWMODE=1\r\n", wifi_uart);
	while(1)
	{
		if (Wait_for((char*)"OK\r\n", wifi_uart))
			break;
		else if (Wait_for((char*)"Error\r\n", wifi_uart))
		{
			vError = 1;
			break;
		}
	}
	if (vError)
	{
		Uart_sendstring("CW MODE---->ERROR\r\n", pc_uart);
		return -1;
	}

	tft.print(".");
	Uart_sendstring("CW MODE---->OK\r\n", pc_uart);

	/********* AT+CIFSR **********/
/*	Uart_flush(wifi_uart);
	Uart_sendstring("AT+CIFSR\r\n", wifi_uart);
	HAL_Delay(3000);
	while(1)
	{
		if (Wait_for((char*)"CIFSR:STAIP,\"", wifi_uart))
			break;
		else if (Wait_for((char*)"Error\r\n", wifi_uart))
		{
			vError = 1;
			break;
		}
	}
	if (vError)
	{
		Uart_sendstring("CIFSR---->ERROR\r\n", pc_uart);
		return -1;
	}
	while (!(Copy_upto((char*)"\"",buffer, wifi_uart)));
	while(1)
	{
		if (Wait_for((char*)"OK\r\n", wifi_uart))
			break;
		else if (Wait_for((char*)"Error\r\n", wifi_uart))
		{
			vError = 1;
			break;
		}
	}
	if (vError)
	{
		Uart_sendstring("Error Getting IP\r\n", pc_uart);
		return -1;
	}

	int len = strlen (buffer);
	buffer[len-1] = '\0';
	sprintf (data, "IP ADDR: %s\r\n", buffer);
	Uart_sendstring(data, pc_uart);*/

	/********* AT+CIPSTA **********/
	Uart_flush(wifi_uart);
	Uart_sendstring("Setting Static IP...\r\n", pc_uart);
	sprintf (data, "AT+CIPSTA=\"192.168.0.67\",\"192.168.0.1\",\"255.255.255.0\"\r\n");
	Uart_sendstring(data, wifi_uart);
	HAL_Delay(3000);
	while(1)
	{
		if (Wait_for((char*)"OK\r\n", wifi_uart))
			break;
		else if (Wait_for((char*)"Error\r\n", wifi_uart))
		{
			vError = 1;
			break;
		}
	}
	if (vError)
	{
		Uart_sendstring("Error Connecting\r\n", pc_uart);
		return -1;
	}

	tft.print(".");
	sprintf (data, "Static IP set to 192.168.0.67\r\n");
	Uart_sendstring(data,pc_uart);

	/********* AT+CIPMUX **********/
	Uart_flush(wifi_uart);
	Uart_sendstring("AT+CIPMUX=1\r\n", wifi_uart);
	while(1)
	{
		if (Wait_for((char*)"OK\r\n", wifi_uart))
			break;
		else if (Wait_for((char*)"Error\r\n", wifi_uart))
		{
			vError = 1;
			break;
		}
	}
	if (vError)
	{
		Uart_sendstring("CIPMUX---->ERROR\r\n", pc_uart);
		return -1;
	}

	tft.print(".");
	Uart_sendstring("CIPMUX---->OK\r\n", pc_uart);

	/********* AT+CIPSERVER **********/
	Uart_flush(wifi_uart);
	Uart_sendstring("AT+CIPSERVER=1,80\r\n", wifi_uart);
	while(1)
	{
		if (Wait_for((char*)"OK\r\n", wifi_uart))
			break;
		else if (Wait_for((char*)"Error\r\n", wifi_uart))
		{
			vError = 1;
			break;
		}
	}
	if (vError)
	{
		Uart_sendstring("CIPSERVER---->ERROR\r\n", pc_uart);
		return -1;
	}

	tft.println(".");
	tft.print(data);
	Uart_sendstring("CIPSERVER---->OK\r\n", pc_uart);
	Uart_sendstring("Now Connect to the IP ADRESS\r\n", pc_uart);

	return 0;
}

//--------------------------------------------------------------------------------
int Server_Send (char *str, int Link_ID)
{
	int len = strlen (str);
	char data[80];

	sprintf (data, "AT+CIPSEND=%d,%d\r\n", Link_ID, len);
	Uart_sendstring(data, wifi_uart);
	while (!(Wait_for((char*)">", wifi_uart)));
	Uart_sendstring (str, wifi_uart);
	while (!(Wait_for((char*)"SEND OK", wifi_uart)));
	sprintf (data, "AT+CIPCLOSE=5\r\n");
	Uart_sendstring(data, wifi_uart);
	while (!(Wait_for((char*)"OK\r\n", wifi_uart)));
	return 1;
}

//--------------------------------------------------------------------------------
void Server_Handle (char *str, char *resphttpcode, int Link_ID)
{
	int len = strlen (str);
	char response[200];

    sprintf(response,
        "HTTP/1.1 %s\r\n"
        "Content-Type: text/plain\r\n"
        "Content-Length: %d\r\n"
        "Connection: close\r\n"
        "\r\n"
        "%s", resphttpcode, len, str);

	Server_Send(response, Link_ID);
}

//--------------------------------------------------------------------------------
void Server_Start (void)
{
	char buftocopyinto[512] = {0};
	char Link_ID, cRec;
	int ix, indx;
	unsigned int postLen, lenSave, vhead, vtail, timeout;
	char* vPosIni;
	char data[320];
	char slen[10];
	char filename[12];
	FIL basicFile;
	FRESULT res;

	while (!(Get_after((char*)"+IPD,", 1, &Link_ID, wifi_uart)));

	Link_ID -= 48;

	while (!(Copy_upto((char*)"\r\n\r\n", buftocopyinto, wifi_uart)));

//	Uart_sendstring(buftocopyinto, pc_uart);

	if (strstr(buftocopyinto, "/PING")) 
	{
		Server_Handle((char*)"...PONG",(char*)"200 OK",Link_ID);
		Uart_flush(wifi_uart);
	}
	else if (strstr(buftocopyinto, "/SendBasic"))
	{
		// Rotina pra Receber o Arquivo e salvar no SD
		// Somente Arquivos Textos
		// Recebe até, inclusive, o EOF (CHR(26))

		// Pega o nome do arquivo
		memset(filename,0,12);
		GetDataFromBuffer((char*)"filename=", (char*)"&", buftocopyinto, filename);

		// Procura o content-length
		vPosIni = strstr(buftocopyinto,"Content-Length:");
		indx = 0;
		slen[0] = 0;
		if (vPosIni)
		{
			while (1)
			{
				if (*vPosIni >= 0x30 && *vPosIni <= 0x39)
				{
					slen[indx++] = *vPosIni;
					slen[indx] = 0;
				}
				
				if (*vPosIni < 0x20)
					break;
				
				vPosIni++;
			}
		}
		postLen = atoi(slen);

		// Le o corpo
		timeout = 999999;
		memset(buftocopyinto, 0, 512);
		while (!(Get_after((char*)"MMSJ800BEGINOFFILE", (postLen - 18), buftocopyinto, wifi_uart)) && timeout) timeout--;

		if (!timeout)
			strcpy(buftocopyinto, "Incorrect Data Submission Structure\r\n");

		postLen -= 18;

		// Salva Arquivo no Disco
		res = f_open(&basicFile, filename, FA_OPEN_ALWAYS | FA_WRITE);
		if (res == FR_OK)
		{
			res = f_write(&basicFile, buftocopyinto, postLen, &lenSave);
			if (res == FR_OK)
			{
				sprintf(data, "Closing File %s, Size %lu, Written %lu...\r\n", filename, postLen, lenSave);
				Uart_sendstring(data, pc_uart);

				Uart_sendstring((char*)"Returning Response...\r\n", pc_uart);

				res = f_close(&basicFile);
				if (res == FR_OK)
				{
					if (lenSave < postLen)
					{
						sprintf(data, "[301]WARNING! Disk is full, bytesToWrite = %lu, bytesWritten = %lu", postLen, lenSave);
						Server_Handle(data,(char*)"200 OK",Link_ID);
					}
					else
						Server_Handle((char*)"[100]File saved successfully",(char*)"200 OK",Link_ID);
				}
				else
				{
					sprintf(data, "[403][%d]Failed to close file", res);
					Server_Handle(data,(char*)"400 Bad Request",Link_ID);
				}
			}
			else
			{
				sprintf(data, "[401][%d]Failed to save file", res);
				Server_Handle(data,(char*)"400 Bad Request",Link_ID);
			}
		}
		else
		{
			sprintf(data, "[402][%d]Failed to open file to save", res);
			Server_Handle(data,(char*)"400 Bad Request",Link_ID);
		}

		Uart_flush(wifi_uart);
	}
	else if (strstr(buftocopyinto, "/LoadFile"))
	{
		// Rotina pra Enviar Arquivo
		// Somente Arquivos Textos
		// Envia até, inclusive, o EOF (CHR(26))

		// Retorna Resposta
		Server_Handle((char*)"File Sent Successfully",(char*)"200 OK",Link_ID);
	}
	else if (strstr(buftocopyinto, "/Exemplo")) // Apenas Exemplo Rec Parametros
	{
		// Apenas exemplo rec parametro
		/*vPosIni = strstr(buftocopyinto, "/Exemplo");
		if (vPosIni != 0)
		{
			vPosIni += 9;	// Comeca a pegar dados depois da posicao (Len + 1)
			ix = 0;
			sSpeed[ix] = 0;
			while(1)
			{
				if (*vPosIni == ' ')
					break;

				sSpeed[ix++] = *vPosIni++;
				sSpeed[ix] = 0;
			}

			vSpeed = atoi(sSpeed);
		}*/

		// Setar valor PWM
		Server_Handle((char*)"/Exemplo",(char*)"200 OK",Link_ID);
	}
	else
		Server_Handle((char*)"Bad Request",(char*)"400 Bad Request",Link_ID);
}

 

 

 

16 REPLIES 16

@MSilv.1 wrote:

f_close takes a long time and returns FS_DISK_ERR.


So what debugging have you done to find where &  why it does that?

It's open-source - so you can step into the f_close() function ...

Thanks for the reply. I appreciate it. Yes, only after looking at the code and trying to identify where the problem is, I opened the post here on the forum. I didn't identify a problematic point. It seems that when it writes to the disk, it loses some reference or can't access the SD even.

The debug you mentioned, this week I upgraded from cubeide 1.13.0 to 1.17.0, and lost the configuration or changed something, and it doesn't work anymore. It doesn't recognize the ST-LINK. I'll see if I can try to configure it again tonight...

At the same time, I'm doing a hardcode debug, putting messages and showing variables inside the program (sending to usart). I want to see if this way I can at least find the exact location of the delay.

So, I did the hard debug and I reached a dead end. I got to the ff.c file in the f_sync function. It is very slow on the following line, returning FR_DISK_ERR:

if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);

It is passing ds->drv = 0, I didn't look at fp->buf but it is a character buffer, and in fp->sect it is passing 1747.

I don't know what this disk_write does, because the function is below:

DRESULT disk_write (
BYTE pdrv, /* Physical drive numuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res;

res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
return res; 
}

 

See that it is part of a struct, and in the struct, this:

typedef struct
{
DSTATUS (*disk_initialize) (BYTE); /*!< Initialize Disk Drive */
DSTATUS (*disk_status) (BYTE); /*!< Get Disk Status */
DRESULT (*disk_read) (BYTE, BYTE*, DWORD, UINT); /*!< Read Sector(s) */
#if _USE_WRITE == 1
DRESULT (*disk_write) (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT (*disk_ioctl) (BYTE, BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */
#endif /* _USE_IOCTL == 1 */

}Diskio_drvTypeDef;

A pointer to some place that I couldn't find in any source, nothing.

Could someone help me see where this is? Because I couldn't get the debugging to work through st-link... I don't know what version 1.17 did.


@MSilv.1 wrote:

A pointer to some place that I couldn't find in any source, nothing.


It's a pointer to a function which does the actual writing.

Use the IDE's 'Find References' feature to find where the pointer gets set ...

> A pointer to some place that I couldn't find in any source, nothing.

Somebody has obviously emulated C++ member functions here.
I had done this 30 years ago ...

You can switch your debugger to instruction/assember single stepping, and try to step into this function this way. Perhaps use the "mixed view" (C source and assembler), if you need it - and your IDE/Debugger supports it.


@MSilv.1 wrote:

I couldn't get the debugging to work through st-link...


Perhaps raise that as a separate issue?

Having a working debugger is pretty fundamental!

Dear Andrew Neil,

 

Yeah, I will, thanks for the tip... 

Dear Ozone,

First of all, thank you very much for your answer.

So speaking of programming experiences, since you started with that, I started programming in C around your time, and I went back to using it about 15 years ago because I used MCUs (PIC18F, 32F, Arduino, etc.). And now I'm on the STM32, which is an excellent MCU, by the way, but I've never needed to use that kind of thing, so no, I don't know how it works.

And finally, my ST-LINK is not working with DEBUG, since I upgraded from 1.13 to 1.17, it messed up a lot of things, luckily it is still compiling, but I am not even using the IDE editor, because it is very bad after the upgrade. So I can't do your idea now, but as soon as I solve this, I will do it with great pleasure, and with the tip of ​​"Andrew Neil" above, I'm going to open a post to help me get the debug working again, in fact, I should, before, even uninstall and reinstall it, to see if a fresh install doesn't solve all the problems.

Ozone
Lead III

As a side note ...

> I have a board with stm32f407zgt6. I'm using freertos and fatfs. The board has a connection for an SDCARD, I'm using a 4GB SDCARD with fat32.

> For reading, F_open, f_read, f_close, everything works. When I use it to write, f_close takes a long time and returns FS_DISK_ERR.

I very well remember that a size if 4GB should be supported, even some while ago.
However, I found the SD card /fatfs support of many Cortex M boards is generally quite wonky. Some sizes and manufacturers worked, others simply did not. And "across the board", i.e. other vendor's boards have the same problem. I had a similiar issue with a LPC device. Create, open and read seemed to work, but write always failed.

You could try a FAT16 file system, SDs of other size, or other vendors.