/var/www/restricted/ssh/stm32/www/stm32circle/ STM CircleOS forum / My problem with SDcard

Username:     
Password:     
             

Forum

# 1   2009-05-14 14:14:35 My problem with SDcard

Marek
New member
Registered: 2009-03-21
Posts: 5

My problem with SDcard

On the beginning I appologize for my english.

The goal is,
based on information available on this forum, a couple weeks ago I wrote simple program:

/********************** (C) COPYRIGHT 2007-2009 RAISONANCE ********************
* File Name          :  w2f.c
* Author             :  Marek
* Date First Issued  :  8-Apr-2099
* Description        :  Circle_App CircleOS application template.
* Revision           :
*******************************************************************************/

/* Includes
------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "circle_api.h"
#include <string.h>


//#define _NVIC   1

/* Private defines
-----------------------------------------------------------*/

// The following should be the minimal CircleOS version needed by your
application
#define NEEDEDVERSION "V 3.6"

/* Private variables
---------------------------------------------------------*/
//DIRENT directory_entry;
    VOLINFO volume_info;
    FILEINFO file_info;
    DIRINFO directory_info;

u32 StartMBR;

/* Private functions
---------------------------------------------------------*/
enum MENU_code MsgVersion(void);
void delay( void);
//void DRAW_SetCursorPos( int x, int y );

/* Public variables
----------------------------------------------------------*/
const char Application_Name[8+1] = {"w2f"};      // Max 8 characters

    char    str_roboczy[100];
    int     operowana_liczba = 0;
    int     len=1;
    char    DataBuffer[ 15 ];
    u32     retval;
    int     count;
    u32     offset = 0;


/*******************************************************************************
* Function Name  : Application_Ini
* Description    : Initialization function of Circle_App. This function will
*                  be called only once by CircleOS.
* Input          : None
* Return         : MENU_CONTINUE_COMMAND
*******************************************************************************/
enum MENU_code Application_Ini ( void )
{



    NVIC_InitTypeDef    NVIC_InitStructure;
    //NVIC_InitTypeDef* NVIC_InitStruct;

    // Ensure that the current OS version is recent enough
    if(strcmp( (char *) UTIL_GetVersion(), NEEDEDVERSION) < 0)
    {
        return MsgVersion();
    }


    // TODO: Write your application initialization function here.

    StartMBR=FS_Mount(MMCSD_SDIO);

    NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init( & NVIC_InitStructure);

    if (StartMBR == 0xFFFFFFFF)
    {
        DRAW_DisplayString(0,100,"!!!No SDCARD!!!",19);
        return MENU_CONTINUE_COMMAND;
    }

    // Open volume on first partition (0)
    if (FS_GetVolumeInfo(0, StartMBR, &volume_info))
    {
        DRAW_DisplayString(0,100,"Err: GetVolInfo",15);
        return MENU_CONTINUE_COMMAND;
    }

    // Open root directory
    if (FS_OpenDirectory(&volume_info, "", &directory_info))
    {
        DRAW_DisplayString(0,100,"Err: Open Root",15);
        return MENU_CONTINUE_COMMAND;
    }

    return MENU_CONTINUE_COMMAND;
}

/*******************************************************************************
* Function Name  : Application_Handler
* Description    : Management of the Circle_App.
*
* Input          : None
* Return         : MENU_CONTINUE
*******************************************************************************/
enum MENU_code Application_Handler ( void )
{


    // TODO: Write your application handling here.
    TIM_Cmd( TIM2, DISABLE );


    memset( (void *) &file_info, offset, sizeof(file_info));
    retval = FS_OpenFile(&volume_info,"mj.txt",FS_READ,&file_info);

    // verify written data in memory debug window
    FS_Seek(&file_info, offset);
    memset(DataBuffer,0,sizeof(DataBuffer));
    retval = FS_ReadFile(&file_info,DataBuffer,&count,strlen(DataBuffer));
    FS_Close( &file_info);    // dummy, but looks fine

    DRAW_SetTextColor( RGB_BLUE);
    DRAW_DisplayString(10,100,&DataBuffer, 9 );

    atoi( DataBuffer, operowana_liczba );
    ++operowana_liczba;

    len = strlen( DataBuffer);
    memset(DataBuffer,0,sizeof(DataBuffer));
    UTIL_int2str( DataBuffer,operowana_liczba,len,   0    );

    memset( (void *) &file_info, offset, sizeof(file_info));
    retval = FS_OpenFile(&volume_info,"mj.txt",FS_WRITE,&file_info);

    FS_Seek(&file_info, offset);
    retval = FS_WriteFile(&file_info,DataBuffer,&count,strlen(DataBuffer));
    FS_Close( &file_info);    // dummy, but looks fine


    DRAW_SetTextColor( RGB_RED);
    DRAW_DisplayString(10,60,&DataBuffer, 9 );


    delay();
    DRAW_Clear();

    /* TIM2 enable counter */
    TIM_Cmd( TIM2, ENABLE );


#if 1
    if ( BUTTON_GetState() == BUTTON_PUSHED )
    {
        BUTTON_WaitForRelease();
        FS_Unmount( MMCSD_SDIO);

        return MENU_Quit();
    }
#endif

    //       This routine will get called repeatedly by CircleOS, until we
    return MENU_LEAVE

    return MENU_CONTINUE;   // Returning MENU_LEAVE will quit to CircleOS
}


void delay( void)
{
    u32 loop = 0;

    for( loop = 0; loop < 2000000; loop++)
        ;
}


/*******************************************************************************
* Function Name  : MsgVersion
* Description    : Display the current CircleOS version and the version needed
*                  exit to main menu after 4 secondes
*
* Input          : None
* Return         : MENU_CONTINUE
*******************************************************************************/
enum MENU_code MsgVersion(void)
    {
    int hh,mm,ss,ss2;

    DRAW_DisplayString(5,60,"CircleOS",17);
    DRAW_DisplayString(80,60,UTIL_GetVersion(),3);
    DRAW_DisplayString(5,34,NEEDEDVERSION,3);
    DRAW_DisplayString(40,34," required",12);

    RTC_GetTime(&hh,&mm,&ss);
    ss = ss + 4;                    // 4 seconds
    ss = ss%60;

    do
        {
        RTC_GetTime(&hh,&mm,&ss2);
        }
    while (ss2 != ss);              // do while < 4 seconds

        return MENU_REFRESH;
    }


Purpose is to read a value from file, increase them and write back to file.
After some time playing with this code, my SD card (new 2GB Kingston) became no more visible for Primer2. So I try format them outside the Primer2, first message after "format x:" was "format them with  /FS:FAT32 option" so, I follow this suggestion.
After that Primer2 and SD card works fine so I back to my program, and again, may by after 30-50 succeeded runs SD cards dissapear again,  I'm afraid this time forever - command "format x: /FS:FAT32" returns the message:

Type the file system is RAW.
The new file system is FAT32.
Check 0m
You can not specify the number of sectors on the volume.

Is my program damages the SD cards, or I just not have luck buying them?
Is there anyone who bump into the same problem?
Any suggestion will be appreciated.

Offline

 

# 2   2009-05-14 15:34:41 My problem with SDcard

Saulis
Member
From: Lithuania
Registered: 2009-04-09
Posts: 34

Re: My problem with SDcard

sd or other nand flash cards are not supposed to be rewriten to often (XD card has the analogy to nand flash chip, exept it is in wearable form case, SD has same mcu and nand flash memory). Thus As I figured out, that using FAT system is killer to the memory.Every atempt to write new file, log data or every manipulation rewrites fat table in memory itself. So without good wear leveling alghoritms is becomes unusable quite fast. Its the fat layer task to reduce erase/read/write tasks to the memory, thus extending memory lifetime.

Your desicion to write some config values to SD are not so good. and with the fat system, there is some critical routines that must be executed in time. OS complicates this. If something fails, file system structure is destroyed.

Solution is to improve fat layer, improve device power stability(including failsafe) and minimise time critical routines count.
Another solution is to use SD in raw memory mode, then you directly control witch data andthere you want to move or store. thus its easiest and fastest to to, but card will not be recognized by any card reader (but it can be controlled manualy by writing own soft for PC)

Offline

 

# 3   2009-05-19 13:39:32 My problem with SDcard

kubark42
Member
Registered: 2009-02-13
Posts: 46

Re: My problem with SDcard

I should add that one way around the NAND flash problem for loggers is simply to initialize a big file that's nothing but zeros and then write the the end of the non-zero section whenever you have enough data to fill a 512 byte buffer. This requires no rewriting, except of the blank section that will be filled with data, and thus neatly sidesteps the flash issue.

Of course, this approach doesn't work for all programs, but it is a very neat and effective way of preserving the FAT filesystem so that the card and data can be read by card readers, all while preserving the card from repeated writes.

Offline

 

# 4   2009-05-19 17:21:24 My problem with SDcard

Saulis
Member
From: Lithuania
Registered: 2009-04-09
Posts: 34

Re: My problem with SDcard

Zero array means "programmed" in NAND flash. Thus the idea to allocate some false big file is some workaround. Mine idea was then you initialize card and open file, you create copy of fat in memory, and all rewrites are made in memory(FAT area), so when you close file, this memory area is written back to flash. The better way would be all writes and rewrites to be on fat copy in memory until power down, but this is errorneous if mechanical disconect occours or similar problem.

Offline

 

Board footer