Getting Started

The following section shows an example on how to get started in a typical case comprising the following:

  • The generic controller layer implementation (included with the NAND driver)
  • The 1-bit software ECC implementation (included with the NAND driver)
  • The static part layer implementation (included with the NAND driver)
  • Your BSP layer implementation to adapt the driver to your specific platform

In case you need additional information and details regarding the different layers, please refer to the Architecture Overview.

To use the NAND driver, you must include the following ten files in the build, in addition to the generic file system files:

  • fs_dev_nand.c (\Micrium\Software\uC-FS\Dev\NAND.)
  • fs_dev_nand.h (\Micrium\Software\uC-FS\Dev\NAND.)
  • fs_dev_nand_ctrlr_gen.c (\Micrium\Software\uC-FS\Dev\NAND\Ctrlr)
  • fs_dev_nand_ctrlr_gen.h (\Micrium\Software\uC-FS\Dev\NAND\Ctrlr)
  • fs_dev_nand_part_static.c (\Micrium\Software\uC-FS\Dev\NAND\Part)
  • fs_dev_nand_part_static.h (\Micrium\Software\uC-FS\Dev\NAND\Part)
  • ecc_hamming.c (\Micrium\Software\uC-CRC\Source)
  • ecc_hamming.h (\Micrium\Software\uC-CRC\Source)
  • ecc.h (\Micrium\Software\uC-CRC\Source)
  • Your BSP layer implementation (derived from fs_dev_nand_ctrlr_gen_bsp.c in \Micrium\Software\uC-FS\Dev\NAND\BSP\Template).

The example in Listing - Opening a NAND device volume shows how to open a single NAND volume. The file system initialization function (FS_Init()) must have previously been called.

Listing - Opening a NAND device volume
#include  <ecc_hamming.h>
#include  <fs.h>
#include  <fs_err.h>
#include  <fs_vol.h>
#include  <fs_dev_nand.h>
#include  <fs_dev_nand_ctrlr_gen.h>
#include  <fs_dev_nand_ctrlr_gen_soft_ecc.h>
#include  <fs_dev_nand_part_static.h>
 
FS_NAND_FREE_SPARE_MAP  App_SpareMap[2] = { { 1, 63},
                                            {-1, -1} };
 
static  CPU_BOOLEAN  App_FS_AddNAND (void)
{
                                                      (1)
    FS_NAND_CFG                     cfg_nand     = FS_NAND_DfltCfg;
    FS_NAND_CTRLR_GENERIC_CFG       cfg_ctrlr    = FS_NAND_CtrlrGen_DfltCfg;
    FS_NAND_CTRLR_GEN_SOFT_ECC_CFG  cfg_soft_ecc = FS_NAND_CtrlrGen_SoftEcc_DfltCfg;
    FS_NAND_PART_STATIC_CFG         cfg_part     = FS_NAND_PartStatic_DfltCfg;
    FS_ERR                          err;
    FS_DevDrvAdd((FS_DEV_API *)&FS_NAND,              (2)
                               &err);
    if ((err != FS_ERR_NONE) &&
        (err != FS_ERR_DEV_DRV_ALREADY_ADDED)) {
        APP_TRACE_DBG(("    ...could not add driver w/err = %d\r\n\r\n", err));
        return (DEF_FAIL);
    }
                                                      (3)
    cfg_part.BlkCnt           = 2048;
    cfg_part.PgPerBlk         = 64;
    cfg_part.PgSize           = 2048;
    cfg_part.SpareSize        = 64;
    cfg_part.SupportsRndPgPgm = DEF_NO;
    cfg_part.NbrPgmPerPg      = 4;
    cfg_part.BusWidth         = 8;
    cfg_part.ECC_NbrCorrBits  = 1;
    cfg_part.ECC_CodewordSize = 512 + 16;
    cfg_part.DefectMarkType   = DEFECT_SPARE_L_1_PG_1_OR_N_ALL_0;
    cfg_part.MaxBadBlkCnt     = 40;
    cfg_part.MaxBlkErase      = 100000;
    cfg_part.FreeSpareMap     = &spare_map[0];
 
                                                      (4)
    cfg_ctrlr.CtrlrExt    = &FS_NAND_CtrlrGen_SoftECC;
    cfg_ctrlr.CtrlrExtCfg = &soft_ecc_cfg;
 
                                                      (5)
    cfg_soft_ecc.ECC_ModulePtr = (ECC_CALC *)&Hamming_ECC;
 
                                                      (6)
    cfg_nand.BSPPtr                 = (void              *)&FS_NAND_BSP_SAM9M10;
    cfg_nand.CtrlrPtr               = (FS_NAND_CTRLR_API *)&FS_NAND_CtrlrGeneric;
    cfg_nand.CtrlrCfgPtr            = &cfg_ctrlr;
    cfg_nand.PartPtr                = (FS_NAND_PART_API  *)&FS_NAND_PartStatic;
    cfg_nand.PartCfgPtr             = &cfg_part;
    cfg_nand.SecSize                = 512;
    cfg_nand.BlkCnt                 = 2038u;
    cfg_nand.BlkIxFirst             = 10u;
    cfg_nand.UB_CntMax              = 10u;
    cfg_nand.RUB_MaxAssoc           = 2u;
    cfg_nand.AvailBlkTblEntryCntMax = 10u;
 
                                                      (7)
    FSDev_Open(        "nand:0:",                       (a) 
               (void *)&cfg_nand,                       (b)
                       &err);
       switch (err) {             
        case FS_ERR_NONE:
             APP_TRACE_DBG(("    ...opened device.\r\n"));
             break;

        case FS_ERR_DEV_INVALID_LOW_FMT:
        case FS_ERR_DEV_INCOMPATIBLE_LOW_PARAMS:
        case FS_ERR_DEV_CORRUPT_LOW_FMT:
             APP_TRACE_DBG(("    ...opened device (not low-level formatted).\r\n"));
#if (FS_CFG_RD_ONLY_EN == DEF_ENABLED)
             FS_NAND_LowFmt("nand:0:", &err);         (8)
             if (err != FS_ERR_NONE) {
                APP_TRACE_DBG(("    ...low-level format failed.\r\n"));
                return 0;
             }
#else
             APP_TRACE_DBG(("    ...opening device failed w/err = %d.\r\n\r\n", err));
             return 0;
#endif
             break;
 
        case FS_ERR_DEV_ALREADY_OPEN:
             break;
 
        case FS_ERR_DEV:
        case FS_ERR_DEV_IO:
        case FS_ERR_DEV_TIMEOUT:
        case FS_ERR_DEV_NOT_PRESENT:
        default:
             APP_TRACE_DBG(("    ...opening device failed w/err = %d.\r\n\r\n", err));
             return (DEF_FAIL);
    }
                                                      (9)    
    FSVol_Open("nand:0:",                               (a)
               "nand:0:",                               (b)
                0,                                      (c)
                &err);*/
    switch (err) {
        case FS_ERR_NONE:
             APP_TRACE_DBG(("    ...opened volume (mounted).\r\n"));
             break;
 
        case FS_ERR_PARTITION_NOT_FOUND:             /* Volume error.            */
             APP_TRACE_DBG(("    ...opened device (not formatted).\r\n"));
#if (FS_CFG_RD_ONLY_EN == DEF_DISABLED)
             FSVol_Fmt("nand:0:", (void *)0, &err);   (10)
             if (err != FS_ERR_NONE) {
                APP_TRACE_DBG(("    ...format failed.\r\n"));
                return (DEF_FAIL);
             }
#else
             APP_TRACE_DBG(("    ...opening device failed w/err = %d.\r\n\r\n", err));
             return 0;
#endif
             break;

        case FS_ERR_DEV:                             /* Device error.            */
        case FS_ERR_DEV_IO:
        case FS_ERR_DEV_TIMEOUT:
        case FS_ERR_DEV_NOT_PRESENT:
             APP_TRACE_DBG(("    ...opened volume (unmounted).\r\n"));
             return (DEF_FAIL);
 
 
        default:
             APP_TRACE_DBG(("    ...opening volume failed w/err = %d.\r\n\r\n", err));
             return (DEF_FAIL);
    }
 
    return (DEF_OK);
}


(1) Declare and initialize configuration structures. Structures should be initialized to allow for forward compatibility in case some new fields in those structures are added in future µC/FS versions.

(2) Register the NAND device driver FS_NAND.

(3) The NAND part layer configuration structure should be initialized. For more information about these parameters, see Statically configured part layer.

(4) The NAND controller layer configuration structure should be initialized. For more information about these parameters, see Generic Controller Layer Implementation. Please note that you might need to use a different controller layer. If this is the case, the configuration might be different (see Controller Layer).

(5) The NAND generic controller software ECC extension should be initialized. For more information about these parameters, see Listing - NAND translation layer configuration structure. Please note that if you are using a different controller layer implementation, there probably won’t be a controller extension layer. Also, if using the generic controller, you might need to use a different extension. Refer to Table - Generic controller layer extensions provided for a list of available controller extensions.

(6) The NAND translation layer structure should be initialized. For more information about these parameters, see Translation Layer Configuration.

(7) FSDev_Open() opens/initializes a file system device. The parameters are the device name (a) and a pointer to a device driver-specific configuration structure (b). The device name (a) is composed of a device driver name (“nand”), a single colon, an ASCII-formatted integer (the unit number) and another colon.

(8) FS_NAND_LowFmt() low-level formats a NAND. If the NAND has never been used with µC/FS, it must be low-level formatted before being used. Low-level formatting will create and initialize the low-level driver metadata on the device.

(9) FSVol_Open() opens/mounts a volume. The parameters are the volume name (a), the device name (b) and the index of the partition that will be opened (c). There is no restriction on the volume name (a); however, it is typical to give the volume the same name as the underlying device. If the default partition is to be opened, or if the device is not partition, then the partition number (c) should be 0.

(10) FSVol_Fmt() formats a file system device. If the NAND has just been low-level formatted, there will be no file system on the corresponding volume after it is opened (it will be unformatted). The volume must be formatted before files can be created or accessed.

If the NAND initialization succeeds, the file system traces (if a sufficiently high trace level is configured) will produce an output similar to Listing - NAND detection trace output. See section Trace Configuration about configuring the trace level.

Listing - NAND detection trace output
===================================================================
=                        FS INITIALIZATION                        =
===================================================================
Initializing FS...
    ===========================================================    
    Adding/opening NAND volume "nand:0:"...
NAND Ctrlr Gen: found NAND manuf id=2c, dev id=aa.
FS_NAND_Open(): Using default blk cnt (all blocks): 2048.
FS_NAND_Open(): Default number of entries in avail blk tbl.
NAND FLASH FOUND: Name       : "nand:0:"
                  Sec Size   : 2048 bytes
                  Size       : 127360 sectors
                  Update blks: 10
FS_NAND_LowMountHandler(): Low level mount succeeded.
    ...opened device.
FSPartition_RdEntry(): Found possible partition: Start: 0 sector
                                                 Size : 0 sectors
                                                 Type : 00
FS_FAT_VolOpen(): File system found: Type     : FAT16 
                                     Sec  size: 2048 B  
                                     Clus size: 4 sec
                                     Vol  size: 127360 sec
                                     # Clus   : 31822    
                                     # FATs   : 2    
    ...opened volume (mounted).
...init succeeded.
===================================================================
===================================================================


Handling different use-cases

If the above example does not apply to your situation, we strongly recommend you read the sections about the different layers. This will help you determine if other existing implementations are suitable for you, or if you need to develop your own implementation of some of those layers.