FatFs on power cycle or unwanted removed

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

I've been able to create, mount a FatFs file system.  I've also been able to f_open() a new file for writing, store some bytes, close the files, and then later open f_open() for reading, and get back the expected data.  Given that, I have some confidence my interface to the SD Card is working correctly, and that the FatFs library is in general working.
 
What I'm not sure is after power cycling, how am I supposed to re-initialize and re associated my FatFs instance(s) with what is on the SD Card already, without wiping the data out on the card?  I've tried just calling f_mount() and or disk_initialize, but that doesn't access the physical drive by itself.  Calling f_mount() followed by f_mkfs() doesn't return errors, but the files I saved previously can't be found. and my program get stuck.
 
so my question is : what is the procedure for setting up the file system the very first time on the SD Card, and then what is the procedure to regain access to that file system after a power cycle.  Are there any special API calls needed when first initializing to tell the library a FatFs file system should already be present? What API calls can I use to know that?
 
and is there any procedure that i have to do, before i can remove the mmc safely? i tried f_mount(0,null) and/or 
re-disk_initialize after i put back mmc and what happened is FatFs got stuck, but timer interrupt for disk_timerproc still running.

Thanks, any information helps!

This topic has a solution.
Last Edited: Tue. Feb 9, 2016 - 01:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

zu_adha wrote:
but the files I saved previously can't be found

Do you see them if you simply stick the card into an SD/MMC socket/reader on your PC? IOW were they really created in the first place?

 

if they are there then you should be able to f_mount and then f_open() them again on the AVR. f_open() supports these options:

 

Value Description
FA_READ Specifies read access to the object. Data can be read from the file.
FA_WRITE Specifies write access to the object. Data can be written to the file. Combine with FA_READ for read-write access.
FA_OPEN_EXISTING Opens the file. The function fails if the file is not existing. (Default)
FA_OPEN_ALWAYS Opens the file if it is existing. If not, a new file will be created.
To append data to the file, use f_lseek function after the file open in this method.
FA_CREATE_NEW Creates a new file. The function fails with FR_EXIST if the file is existing.
FA_CREATE_ALWAYS

Creates a new file. If the file is existing, it will be truncated and overwritten.

 

You may want to use FA_OPEN_EXISTING if you believe the file should already exist.

 

if the files you were trying to create really do not exist then perhaps you removed power before the file was completely created and FatFs had flushed its buffer? If that's the case you might want to explore using f_close() after each write so that the file is "complete" each time. Better yet is to use f_sync() which makes sure everything that needs to be has been written out to the card.

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

i can see the file that has been created and appended on computer, i have procedure to close the open file before i remove, and f_sync right after write something.
this is my sequence :

 

char mmc_write(char modewrite)
{
			if(mmc_err != 0)//disk_initialize and f_mount if last check is error
			{
				res = disk_initialize(0);
				if(res == STA_NOINIT) //|| == STA_NODISK || res == STA_P
			 	{
					mmc_err = 1;
			 		res = f_mount(0, NULL);
					return mmc_err; //|| res == STA_NODISK || res == STA_PROTECT
			 	}
			 	else
			 	mmc_err = 0;

			 	res = f_mount(0, &fs);
			}

			res = f_open(&fin, "LOG.TXT", FA_OPEN_ALWAYS | FA_WRITE);
	 		if (res == FR_OK)
	 		{
	 			lcd_goto_xy(4,4);
	 			lcd_str("FR_OK1");
	 			//_delay_ms(900);
	 			// for checking sequence only, break here
				if(f_lseek(&fin,f_size(&fin)) == FR_OK) // go to the end of file
				{
					mmc_err = 0;
					if(modewrite == 1)
					{
						//res = f_printf(&fin,"************\r\nsave every : 3h 0m 23s\r\n************\r\n",fvalue,pvalue);
						f_printf(&fin,"----------\r\nsave every\r\n%05ds\r\n----------\r\n",fvalue);
						f_sync(&fin);
						modewrite = 0;
					}
					else
					{
						//res = f_printf(&fin,"%d%d%d.%d%d cm\r\n",n[0],n[1],n[2],n[3],n[4]); //res = put data here
						res=f_printf(&fin,"%03d.%02d cm\r\n",fvalue,pvalue);
						f_sync(&fin);
						lcd_goto_xy(4,5);
						lcd_printf("pr:%d",res);
					}
				}//if res error give notificarion  error on writing
				else //mmc error
				{
					lcd_goto_xy(4,4);
				        lcd_str("FR_NO1");
	 			        //_delay_ms(900);
	 			        f_mount(0, NULL);
				        mmc_err = 1;
				}
			}
			else //mmc error
			{
			      lcd_goto_xy(4,4);
			      lcd_str("FR_NO2");
	 		      //_delay_ms(900);
	 		      //f_mount(0, NULL);
			      mmc_err = 2;// give notification error on open or create file
			}
			//f_close(&fin);
			//lcd_goto_xy(1,1);
			//lcd_printf("%01d ",mmc_err);
			return mmc_err;

			//if mmc error next check will include disk_initialize and f_mount
}

if i plug the mmc on start or in the middle program running, FatFs read and write/append successfully, if i un-amount after this procedure called, FatFs also recognize that mmc is pulled off (without cd/wp pin).

(and this is the problem) once i plug the mmc on again,

 

1st case : if i use f_mount and/ or disk_initialize, Fatfs got stuck, and my loop get stuck too, but the timer interrupt still firing disk_timerproc,.

 

2nd case if i disable f_mount and disk_initialize,  FatFs not stuck but can't recognize the mmc, but my loop sequence can work perfectly.

 

 

so i try something "fool proof" code, to see what happened 

 

        if(disk_initialize(0) == STA_NOINIT)mmc_err = 2;
	else
	mmc_err=0;

	f_mount(0, &fs);
	//f_mount(0, NULL);
	lcd_printf("1:%d",mmc_err);
	_delay_ms(900);
	lcd_clear();
	_delay_ms(900);	

	disk_initialize(0);
	f_mount(0, &fs);
	res = f_open(&fin, "LOG.TXT", FA_OPEN_EXISTING);
	f_close(&fin);
	//if(res==FR_OK)
	f_mount(0, NULL);
	lcd_printf("2:%d",res);
	_delay_ms(900);
	lcd_clear();
	_delay_ms(900);

	disk_initialize(0);
	f_mount(0, &fs);
	res = f_open(&fin, "LOG.TXT", FA_OPEN_EXISTING);
	f_close(&fin);
	//if(res==FR_OK)
	f_mount(0, NULL);
	lcd_printf("3:%d",res);
	_delay_ms(900);
	lcd_clear();
	_delay_ms(900);

	disk_initialize(0);
	f_mount(0, &fs);
	res = f_open(&fin, "LOG.TXT", FA_OPEN_EXISTING);
	f_close(&fin);
	//if(res==FR_OK)
	f_mount(0, NULL);
	lcd_printf("4:%d",res);
	_delay_ms(900);*/

and this is what i got if i run this program (sd card has LOG.TXT file already on it, and this is just before the loop sequence)

 

1st.(not using f_mount on next procedure only once at the begining) if i plug the mmc in the middle program right after program print something to lcd (i got 1800ms delay to plug the mmc in) the next open work fine.

 

2nd.  but if i plug off the mmc after program can open the file (in the middle of delay too) the program just give me FR_OK, even though there is no mmc.

 

3rd if i using f_mount(0,NULL) or f_mount(0,&fs) and/or disk_initialize, it got FatFs stuck when i pull off the mmc between the delay.

 

4th. if i change all the f_close with f_sync, it give me same result like 1st and 2nd case above. and if i using f_mount  and disk_initialize it give me same result like 3rd case.

 

 

so the result is : i do f_close or/and f_sync but once program give me FR_OK, it will give me FR_OK even though mmc is not there and FatFs stuck if i put f_mount and/or disk_initialize.
and if i pull on the mmc in the middle of delay, FatFs can recognize the mmc. and if i pull off again, it will error. i've tried FA_READ too but same problem.
 

 

 

note : if error occurred it will work again if i push the reset button, it seems FatFs not flushing the data after i close the file, 

Last Edited: Tue. Feb 9, 2016 - 11:38 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you don't have CP (card present) or CD (card detect) signal then you have to physically ensure the user simply cannot remove or insert the card while powered or they could pull the card at any moment while the FAT structure is inconsistent. Put the card socket underneath the battery or something so the user has to power off and remove power before they can access the card. Otherwise get a socket with a card present/detected switch.

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

clawson wrote:

If you don't have CP (card present) or CD (card detect) signal then you have to physically ensure the user simply cannot remove or insert the card while powered or they could pull the card at any moment while the FAT structure is inconsistent. Put the card socket underneath the battery or something so the user has to power off and remove power before they can access the card. Otherwise get a socket with a card present/detected switch.

 

WOW thanks Cliff you just give me an idea to manipulate STA_NODISK, STA_NOINIT on disk_timerproc just after write procedure, and it works !!! 

 

i thing i need to manipulate this status, since the device logger is un-stable/vibrate condition such as on bike or car. and sometimes cd/wp/cp pin not recognize the absence of sd card.

so even though i don't have any pin to detect card present/detected. i can add feature "safely removed" to the system.

Last Edited: Tue. Feb 9, 2016 - 02:19 PM