Format flash chip with FAT

LINDOW, Phil phil.lindow at airbus.com
Tue May 29 16:18:52 UTC 2018


Hello all,

I want to format a flash chip (S29GL01GP) with a FAT filesystem. I've tried the following approach:

1. I've implemented IO functions for my chip

        int flash_init(void* start_addr, flash_device_t* handle);
        int flash_erase_block(flash_device_t* handle, void* blk_addr);
        int flash_program(flash_device_t* handle, void* dst, void* data, unsigned long size);

        (These functions are tested and they work...)

        I must use these functions since the CPU and the flash chip are connected through an FPGA in order to expand the addressable memory.
        We have only 8 address lines available. But to make a long story short: I can't use generic program and erase functions.

2. I've tried to use the rtems flashdisk driver (rtems/flashdisk.h) and found the files \c\src\libchip\flash\am29lv160.c and am29lv160.h.
Guided by these files I wrote the following code:

===================================================================================================
========================================== fdisk_driver.c =========================================
#include "fdisk_driver.h"
#include "../flash/flashlib.h"
#include "../utils/utils.h"

#include "errno.h"

flash_device_t handle;

void init_flash_filesystem_driver(void)
{
        flash_init((void*)FLASH_START_ADDR, &handle);
}

int fdisk_driver_read (const rtems_fdisk_segment_desc* sd,
               uint32_t                        device,
               uint32_t                        segment,
               uint32_t                        offset,
               void*                           buffer,
               uint32_t                        size)
{
        if(handle.size == 0)
                return EIO;

        unsigned char* addr = (unsigned char*)(handle.start_addr + (segment * sd->size) + offset);
        copy_mem(addr, buffer, size);
        return 0;
}

int fdisk_driver_write (const rtems_fdisk_segment_desc* sd,
                uint32_t                        device,
                uint32_t                        segment,
                uint32_t                        offset,
                const void*                     buffer,
                uint32_t                        size)
{
        if(handle.size == 0)
                return EIO;

        unsigned char* addr = (unsigned char*)(handle.start_addr + (segment * sd->size) + offset);

        return flash_program(&handle, addr, buffer, size);;
}

int fdisk_driver_blank (const rtems_fdisk_segment_desc* sd,
                uint32_t                        device,
                uint32_t                        segment,
                uint32_t                        offset,
                uint32_t                        size)
{
        uint32_t i;
        unsigned char* addr = (unsigned char*)(handle.start_addr + (segment * sd->size) + offset);

        for(i = 0; i < size; i++)
        {
                if(addr[i] != 0xff)
                        return EIO;
        }
        return 0;
}

int fdisk_driver_verify (const rtems_fdisk_segment_desc* sd,
                 uint32_t                        device,
                 uint32_t                        segment,
                 uint32_t                        offset,
                 const void*                     buffer,
                 uint32_t                        size)
{
        uint32_t i;
        unsigned char* addr = (unsigned char*) (handle.start_addr
                        + (segment * sd->size) + offset);

        unsigned char* cmp = (unsigned char*) buffer;

        for (i = 0; i < size; i++) {
                if (addr[i] != cmp[i])
                        return EIO;
        }
        return 0;
}

int fdisk_driver_erase (const rtems_fdisk_segment_desc* sd,
                uint32_t                        device,
                uint32_t                        segment)
{
        if(handle.size == 0)
                return EIO;

        void* blk_addr = (void*)(segment * sd->size);

        return flash_erase_block(&handle, blk_addr);
}

int fdisk_driver_erase_device (const struct rtems_fdisk_device_desc* dd,
                       uint32_t                              device)
{
        printf("Erase Device.\n");
        return 0;
}

const rtems_fdisk_driver_handlers driver_ops =
{
                .read = fdisk_driver_read,
                .write = fdisk_driver_write,
                .blank = fdisk_driver_blank,
                .verify = fdisk_driver_verify,
                .erase = fdisk_driver_erase,
                .erase_device = fdisk_driver_erase_device
};

const rtems_fdisk_segment_desc driver_segment_desc[1] =
{
                {
                                .count = 1024,
                                .segment = 0,
                                .offset = 0,
                                .size = 131072
                }
};

const rtems_fdisk_device_desc driver_device_desk[1] =
{
                {
                                .segment_count = 1,
                                .segments = driver_segment_desc,
                                .flash_ops = &driver_ops
                }
};

uint32_t rtems_flashdisk_configuration_size = 1;
const rtems_flashdisk_config rtems_flashdisk_configuration[1] =
{
                {
                        .block_size = 1024,
                        .device_count = 1,
                        .devices = driver_device_desk,
//                      .flags = RTEMS_FDISK_BACKGROUND_ERASE | RTEMS_FDISK_BACKGROUND_COMPACT,
                        .flags = 0,
                        .unavail_blocks = 2048,
                        .compact_segs = 8,
                        .avail_compact_segs = 2,
                        .info_level = 0
                }
};
===================================================================================================
===================================================================================================

===================================================================================================
============================================= main.c ==============================================

#include <rtems.h>
#include "rtems/blkdev.h"
#include "rtems/dosfs.h"
#include "rtems/flashdisk.h"
/* configuration information */

#define CONFIGURE_INIT

#include <bsp.h> /* for device driver prototypes */

rtems_task Init( rtems_task_argument argument); /* forward declaration needed */

/* configuration information */

#define CONFIGURE_INIT
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM

#define CONFIGURE_MAXIMUM_TASKS             10

#define CONFIGURE_RTEMS_INIT_TASKS_TABLE

#define CONFIGURE_EXTRA_TASK_STACKS         (4 * RTEMS_MINIMUM_STACK_SIZE)

#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
#define CONFIGURE_INIT_TASK_PRIORITY    100
#define CONFIGURE_MAXIMUM_DRIVERS 16

#define RTEMS_FDISK_TRACE 0

#include <rtems/confdefs.h>

/* If --drvmgr was enabled during the configuration of the RTEMS kernel */
#ifdef RTEMS_DRVMGR_STARTUP
 #ifdef LEON3
  /* Add Timer and UART Driver for this example */
  #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
   #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
  #endif
  #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
   #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
  #endif
 #endif

 #include <drvmgr/drvmgr_confdefs.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "filesystem/fdisk_driver.h"

rtems_task Init(
  rtems_task_argument ignored
)
{
        DIR* dir;
        struct dirent* dp;
        int status;

        printf("Errno at the very beginning: %i\n", errno);

        init_flash_filesystem_driver();

        rtems_status_code rc;
        rc = rtems_fdisk_initialize(/*major number*/ 99, 0, 0x0);
        printf("Return Value of rtems_fdisk_initialize: %u\n", rc);
        printf("Errno after rtems_fdisk_initialize: %i\n", errno);

        printf("Files in /dev/:\n");
        dir = opendir("/dev/");
        while((dp = readdir(dir)) != NULL)
        {
                printf("%s\n", dp->d_name);
        }

        status = mkdir("/mnt/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
        printf("Return value of mkdir: %i, errno: %i\n", status, errno);

        printf("Files in root directory:\n");
        dir = opendir("/");
        while ((dp = readdir(dir)) != NULL) {
                printf("%s\n", dp->d_name);
        }

        printf("Errno after opendir: %i\n", errno);

        status = msdos_format("/dev/fdda", 0x0);
        printf("Return value of msdos_format: %i, errno: %i\n", status, errno);

        status = mount("/dev/fdda", "/mnt/", "vfat", 0, "mode=0666");
        printf("Return value of mount: %i, errno: %i\n", status, errno);


        exit( 0 );
}


===================================================================================================
===================================================================================================

Running the code produces the following output:

Errno at the very beginning: 0
Return Value of rtems_fdisk_initialize: 0
Errno after rtems_fdisk_initialize: 22
Files in /dev/:
console
console_b
fdda                                            <= This should be the flashdisk device file
Return value of mkdir: 0, errno: 22
Files in root directory:
dev
mnt
Errno after opendir: 22
Return value of msdos_format: -1, errno: 9
Return value of mount: -1, errno: 22

Obviously something goes wrong but I have no idea why. Is this even the right approach or is there a much simpler solution for my problem?
I would appreciate any help.

Thanks in advance,
Phil


This email (including any attachments) may contain confidential and/or privileged information or information otherwise protected from disclosure. If you are not the intended recipient, please notify the sender immediately, do not copy this message or any attachments and do not use it for any purpose or disclose its content to any person, but delete this message and any attachments from your system. Astrium and Airbus Group companies disclaim any and all liability if this email transmission was virus corrupted, altered or falsified.
---------------------------------------------------------
Airbus Defence and Space GmbH 
Vorsitzender des Aufsichtsrates: Dr. Thomas Enders 
Geschäftsführer: Dirk Hoke (Chairman), Dr. Lars Immisch
Sitz der Gesellschaft: Ottobrunn, Amtsgericht München 
HRB 107 648, USt.Id.Nr. DE167015661
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20180529/115648c6/attachment-0001.html>


More information about the users mailing list