Fatfs Atmega328p problem while working with string

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would like to build a gps tracker, which sends datas to UART, and after I process this, I save the interesting datas to sdcard in gpx format. I debug the code in UART. I noticed, if I remove the sdcard commands from my code, on the serial terminal the datas appear correctly. But, if I want to write to the sdcard, some of the valuable datas are lost. In this case on the serial terminal show the same thing, which is in the sdcard. Now I'm trying to find out what happenin, that I seperated the sdcard module, and only the ISP programmer, and the USB--TTL adapter connected to the uc. Same results. Can anybody help me to find out what happening? I attach the full atmel studio solution to save space. In realterm I use the send function, to send the "send.txt" file byte by byte with 1 ms delay. 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At most you will write 2 lines to the file, because you close the file with an f_close() after the f_write( , sddata_buffer, );

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the writing function would be good, I'd put the f_close() function to an interrupt, which is generated by a switch. I found out, if the f_mount function missing from the code, the sddata_buffer will not be empty. Otherwise, it is. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When you examine the file "log1.txt" on a PC, what does it contain ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Only the header.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I haven't looked at the code but the general technique if you want to be sure nothing could be lost because of a power outage is: open file, seek to end, write, flush, close file, open file, seek to end, write, flush, close....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I cleared the code, and removed all the sdcard functions, except fmount. Seems to be this is the problem. On serial Terminal gpgga, gprmc and gpvtg variables empty, if fmount is used. If don't use the fmount, the variables are full with values. So now i am not trying to write to the sdcard, just debugging on serial terminal.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

I haven't looked at the code but the general technique if you want to be sure nothing could be lost because of a power outage is: open file, seek to end, write, flush, close file, open file, seek to end, write, flush, close....

 

Oh i like this idea for power outage issues!

 

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SOS wrote:

clawson wrote:

I haven't looked at the code but the general technique if you want to be sure nothing could be lost because of a power outage is: open file, seek to end, write, flush, close file, open file, seek to end, write, flush, close....

 

Oh i like this idea for power outage issues!

 

Thanks.

Interesting.  Using an older version of FATFS in a family of production apps for over five years for "log" files, I've never seen anything "lost" after a power cycle or AVR reset or similar, and I don't close and reopen the log file.  I do, however, burn the extra milliseconds doing FATFS f_sync() after every write at the end of the file.  I'd have to dig -- perhaps the f_sync() effectively does the good stuff that close and reopen does for you?  Perhaps so...

Description

The f_sync function performs the same process as f_close function but the file is left opened and can continue read/write/seek operations to the file. This is suitable for the applications that open files for a long time in write mode, such as data logger. Performing f_sync function of periodic or immediataly after f_write function can minimize the risk of data loss due to a sudden blackout or an unintentional media removal. For more information, refer to application note.

However there is no sense in f_sync function immediataly before f_close function because it performs f_sync function in it. In other words, the differnce between those functions is that the file object is invalidated or not.

I'd think that f_sync() wold be more lightweight than close/reopen. 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Tue. Oct 18, 2016 - 01:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

f_sync() is effectively the "flush" I was talking about - I guess that's the key operation. I guess when the FATFS structure is just 568 bytes and only has room for a single sector buffer so it's not like it can be caching things like FAT sectors at the same time (as might happen in other systems where power fail can corrupt FAT). I was simply outlining a "belts and braces" general approach for all FAT systems. Not necessarily something FatFs specific. Because of limited resources I guess it cannot afford to do the kind of RAm caching that might be find in "big" OS.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I figured out, that when I call the f_mount function, it reset the uc. I will investigate it later, but another problem happened. Today I got a micro sdcard module, this: http://www.tronicsbd.com/wp-content/uploads/2015/07/Free-Shipping-10pcx-Micro-SD-Card-Module-SPI-interface-mini-TF-card-reading-and-writing.jpg_350x350.jpg. Hooking up to the AVR I noticed that mount is successful, but f_open returns FR_NOT_READY. (For this time I use this code, with the corrections of SS pin: https://www.avrfreaks.net/forum/help-fatfs-r011a-and-atmega328p , because it worked :) ). However after flashing the code I can use the sdcard, until I reset the chip. Ideas? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you might have buffer-overflow problems.

...<br />
if(gpgga != NULL)<br />
{<br />
	trunk=strtok(gpgga,",");<br />
	while(trunk != NULL)<br />
	{<br />
		i++;<br />
		strcpy(gpgga_datas,trunk);<br />
		//memmove(gpgga_datas[i],trunk,sizeof(trunk));<br />
		trunk = strtok (NULL, ",");<br />
	}<br />
	i=0;<br />
}<br />
...

because ;
1)
at the start of that block of code, the index 'i' might not be what you expect it to be.


2)
some of the arrays are too small for the inputs,
example ;
[i]char gpgga_datas[10][10]; /* For truncated gpgga datas *//
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47


3)
if(gpgga != NULL) will always be true, I think you want if(*gpgga != NULL)
but you will then need to put a NULL into gpgga[0] (or *gpgga) to indicate that you have finished with that gpgga message and are now waiting to receive another gpgga message.

Last Edited: Tue. Oct 18, 2016 - 09:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you looked at the code, your points are right, I have to think it over.