Migrating to the New Flash Filesystem

Home
Developer Resources
PDF Documents
Caution: This version of this document is no longer maintained. For the latest documentation, see http://www.qnx.com/developers/docs.

Migrating to the New Flash Filesystem

Target OS: 6.2.1 Supplemental and 6.3.0

The purpose of this technote is to help you migrate to the new flash filesystem (FS) efficiently. This new flash FS supports a compatibility mode and enhances the reliablity of your driver at a small performance cost. The main benefits of this new FS include:

The following discussion is intended for users of BSP flash FS drivers from a previous version of Neutrino. Using this technote, you can modify your drivers to support either the old or the new flash FSs. These two flash FSs, however, are not compatible.


Note: QNX Neutrino flash filesystem version 3 no longer provides built-in decompression. The flash filesystem's decompression functionality has moved into the inflator resource manager. You should now use the deflate utility to compress files.

New and old libraries

In this release, you get a brand new flash FS library (libfs-flash3.a) in addition to the flash library (libfs-flash.a) you already purchased with your previous version of QNX Neutrino.

While writing the flash FS driver, you use the FS library along with the low-level flash library (libmtd-flash.a), also called the memory technology driver (MTD). This particular MTD library is hardware dependent, and is required to access particular flash devices. Like the FS library, the MTD library has also two versions. Unlike the FS libraries, however, the new MTD version is fully backward compatible with the old MTD version. In fact, the new version is a superset of the old one with additional interface APIs. This is also the reason QNX has shipped only one version of the libmtd-flash.a library.

Versioning

The source code for the FS and MTD libraries contains different API versions:

libfs-flash.a
v2
libfs-flash3.a
v3
libmtd-flash.a
v1, v2

Note: Notice that the version number of the old flash FS is 2, whereas the version number for the new FS system is 3.

In order for your driver to work, you should employ only the following working combinations of these versions:

For this version of the FS: Use this version of the MTD library:
FSv2 MTDv1
FSv3 MTDv1
FSv3 MTDv2

Each combination describes the driver as follows:

FSv2 MTDv1
Original driver.
FSv3 MTDv1
Driver that provides:
  • compatibility with v1 MTD drivers
  • minimal MTD changes
  • new reliable FS
  • improper error reporting of HW errors
  • no block write protection.
FSv3 MTDv2
Driver with full features (i.e. reliable FS, proper error reporting, and block write protection).

Updating the variant code


Note: This procedure assumes a familiarity with the "C" programming language and that you've read the Customizing the Flash Filesystem chapter in the Building Embedded Systems guide.

In order to migrate to the new flash FS, you need to update the variant code. The variant code is linked with the FS and MTD libraries to build the driver (e.g. devf-generic). Look for the variant code in the bsp_working_dir/src/hardware/flash/boards directory -- you'll find a subdirectory for each board we support. The variant code describes what combinations of MTD callouts the flash FS should use.

To update the variant code:

  1. Fix the includes in all .c and .h files:

    Include <sys/f3s_mtd.h> instead of <sys/f3s_api.h>, <sys/f3s_spec.h>, <sys/f3s_socket.h>, <sys/f3s_comp.h>, or <sys/f3s_flash.h>.

  2. Add MTD v2 callouts to support compatibility mode. For example, you add the following compatibility code snippets in the main.c file:

    #if MTD_VER == 2
    .
    .
    #else
    .
    #endif
    
    
  3. Place the original f3s_flash_t definition between the #else and #endif statements.
  4. Copy the entire original f3s_flash_t definition and place it between the #if and #else statements.
  5. In the copied code, you'll need to:
    • Change f3s_flash_t to f3s_flash_v2_t for each array element.
    • For each array element, insert six NULL entries between the _reset() and _read() structure members.

      Note: Many drivers have NULL for the _read() member. This NULL doesn't count as one of the six.

    • Insert four NULL entries after the _sync() entry, or the corresponding flash lock/unlock routines, if applicable.

      Note: The last entry should contain nineteen zeroes or NULLS.

    • Change every _write(), _erase(), _suspend(), _resume(), and _sync() function to its corresponding "v2" function. For example, f3s_a29f040_write changes to f3s_a29f040_v2write.

    This ensures that each of the combinations works properly. See the updated main.c example below for details.


    Note: You may receive a warning message in main.c that the pointer to the flash argument in the
    f3s_init(argc, argv, flash)
    and
    f3s_start(service, flash)
    calls is incorrect.

    The warning is generated because of the difference between the old and new MTD versions.

    You can ignore the warning, or cast the pointer as follows:

    f3s_init(argc, argv, (f3s_flash_t *)flash;
    f3s_start(service, (f3s_flash_t *)flash;

    It is important to note that due to the nature of the new MTDv1 API, certain MTDv1 callouts have been combined into a single new MTDv2 callout. The table below lists these consolidations:

    MTDv1 MTDv2
    f3s_i28f008_erase() f3s_iCFI_v2erase()
    f3s_i28f008_resume() f3s_iCFI_v2resume()
    f3s_i28f008_suspend() f3s_iCFI_v2suspend()
    f3s_i28f008_sync(), f3s_i28f800_sync() f3s_iCFI_v2sync()
    f3s_a29f004_sync(), f3s_a29f040_sync() f3s_a29f040_v2sync()
  6. Update the common.mk file. This file is included with the MTD source.
    cp bsp_root/libs/src/hardware/flash/boards/common.mk
      bsp_working_dir/src/hardware/flash/boards/common.mk
  7. Copy two files as follows:
    cp bsp_root/libs/src/hardware/flash/mtd-flash/usagev2.use
      bsp_working_dir/src/hardware/flash/mtd-flash/usagev2.use
    
    cp bsp_root/libs/src/hardware/flash/mtd-flash/usagev3.use
      bsp_working_dir/src/hardware/flash/mtd-flash/usagev3.use

Example of updated file: main.c

#include <sys/f3s_mtd.h>
#include "f3s_800fads.h"

int main(int argc, char **argv)
{
   int error;
   static f3s_service_t service[] =
   {
      {
         sizeof(f3s_service_t),
         f3s_800fads_open,
         f3s_800fads_page,
         f3s_800fads_status,
         f3s_800fads_close
      },
      {
         0, 0, 0, 0, 0  /* mandatory last entry */
      }
   };

#if MTD_VER == 2
   static f3s_flash_v2_t flash[] =
   {
      {
         sizeof(f3s_flash_v2_t),
         f3s_a29f040_ident,       /* Common Ident            */
         f3s_a29f040_reset,       /* Common Reset            */

         /* v1 Read/Write/Erase/Suspend/Resume/Sync (Unused) */
         NULL, NULL, NULL, NULL, NULL, NULL,

         NULL,                   /* v2 Read (Use default)    */

         f3s_a29f040_v2write,    /* v2 Write                 */
         f3s_a29f040_v2erase,    /* v2 Erase                 */
         f3s_a29f040_v2suspend,  /* v2 Suspend               */
         f3s_a29f040_v2resume,   /* v2 Resume                */
         f3s_a29f040_v2sync,     /* v2 Sync                  */

         /* v2 Islock/Lock/Unlock/Unlockall (not supported)  */
         NULL, NULL, NULL, NULL
      },
      {
         /* mandatory last entry */
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
      }
   };
#else
   static f3s_flash_t flash[] =
   {
      {
         sizeof(f3s_flash_t),
         f3s_a29f040_ident,      /* Common Ident             */
         f3s_a29f040_reset,      /* Common Reset             */

         NULL,                   /* v1 Read (Use default)    */
         f3s_a29f040_write,      /* v1 Write                 */
         f3s_a29f040_erase,      /* v1 Erase                 */
         f3s_a29f040_suspend,    /* v1 Suspend               */
         f3s_a29f040_resume,     /* v1 Resume                */
         f3s_a29f040_sync        /* v1 Sync                  */
      },
      {
         /* mandatory last entry */
         0, 0, 0, 0, 0, 0, 0, 0, 0
      }
   };
#endif
  
   /* init f3s */
   f3s_init(argc, argv, flash);

   /* start f3s */
   error = f3s_start(service, flash);

   return error;
}

Updating MTD overrides

In rare circumstances, you may have to override an MTD callout implementation to support your hardware. In this case, you will have to modify your overrides to conform to the new MTDv2 API. Please refer to the Building Embedded Systems guide for the new behavior and bsp-dir/libs/hardware/flash/mtd-flash for examples. As an alternative, you can use your existing MTD overrides with the new file system via the compatibility mode.

Building the drivers

Use any of the following commands to make the driver:

make F3S_VER=3 MTD_VER=1

or:

make F3S_VER=2 MTD_VER=1

or:

make F3S_VER=3 MTD_VER=2

The first command is called the compatibility mode -- you use it to build the driver using version 3 of the FS library and version 1 of the MTD library. The second command is the original mode -- you use it to build the driver using version 2 of the FS library along with version 1 of the MTD library. The last command will build the latest version of the driver.

Creating the image for the new and old flash filesystem:

The mkefs utility will create the image for different flash FS as follows:

To create an image for: Use this command:
old FS mkefs -t ffs2 [-l inputline] [-v] [buildfile [outputfile]]
new FS (default) mkefs -t ffs3 [-l inputline] [-v] [buildfile [outputfile]]