shithub: lwext4

Download patch

ref: d60475e89d4ed87a2237a8e093e8c6198f419712
parent: 096dcc3aa448b462dc386fa000c632f38b3cd6aa
author: gkostka <kostka.grzegorz@gmail.com>
date: Sun Jan 12 11:25:13 EST 2014

Update USB demo.

--- a/demos/stm32f429_disco/hw_init.c
+++ b/demos/stm32f429_disco/hw_init.c
@@ -31,6 +31,13 @@
 USB_OTG_CORE_HANDLE     USB_OTG_Core;
 USBH_HOST               USB_Host;
 
+static volatile uint32_t _systick_;
+
+void SysTick_Handler(void)
+{
+    _systick_++;
+}
+
 void hw_init(void)
 {
     pll_init();
@@ -39,6 +46,8 @@
     STM_EVAL_LEDInit(LED3);
     STM_EVAL_LEDInit(LED4);
 
+    SysTick_Config(CFG_CCLK_FREQ / 1000);
+
     /*Init USB Host */
     USBH_Init(&USB_OTG_Core,
         USB_OTG_HS_CORE_ID,
@@ -66,6 +75,11 @@
     return HCD_IsDeviceConnected(&USB_OTG_Core);
 }
 
+bool hw_usb_enum_done(void)
+{
+    return USB_Host_Application_Ready;
+}
+
 void hw_led_red(bool on)
 {
     on ? STM_EVAL_LEDOn(LED4) : STM_EVAL_LEDOff(LED4);
@@ -74,4 +88,9 @@
 void hw_led_green(bool on)
 {
     on ? STM_EVAL_LEDOn(LED3) : STM_EVAL_LEDOff(LED3);
+}
+
+uint32_t hw_get_ms(void)
+{
+    return _systick_;
 }
--- a/demos/stm32f429_disco/hw_init.h
+++ b/demos/stm32f429_disco/hw_init.h
@@ -18,13 +18,15 @@
 
 #include <config.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 void hw_init(void);
 void hw_usb_process(void);
 bool hw_usb_connected(void);
+bool hw_usb_enum_done(void);
 
 void hw_led_red(bool on);
 void hw_led_green(bool on);
-
+uint32_t hw_get_ms(void);
 
 #endif /* HW_INIT_H_ */
--- a/demos/stm32f429_disco/main.c
+++ b/demos/stm32f429_disco/main.c
@@ -1,28 +1,410 @@
-/**
- * @file    main.c
- * @version 0.01
- * @date    Oct 2, 2012
- * @author  Grzegorz Kostka, kostka.grzegorz@gmail.com
- * @brief   ...
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * All rights reserved.
  *
- * @note
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  *
- * @addtogroup group
- * @{
- *      @addtogroup subgroup
- *      @{
- **********************************************************/
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #include <config.h>
 #include <hw_init.h>
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <time.h>
+#include <unistd.h>
 
+#include <usb_msc_lwext4.h>
+#include <ext4.h>
+
+/**@brief   Input stream name.*/
+char input_name[128] = "ext2";
+
+/**@brief   Read-write size*/
+#define READ_WRITE_SZIZE 1024 * 8
+
+/**@brief   Read-write size*/
+static int rw_szie  = READ_WRITE_SZIZE;
+
+/**@brief   Read-write size*/
+static int rw_count = 1000;
+
+/**@brief   Directory test count*/
+static int dir_cnt  = 10;
+
+/**@brief   Static or dynamic cache mode*/
+static bool cache_mode = false;
+
+/**@brief   Cleanup after test.*/
+static bool cleanup_flag = false;
+
+/**@brief   Block device stats.*/
+static bool bstat = false;
+
+/**@brief   Superblock stats.*/
+static bool sbstat = false;
+
+/**@brief   File write buffer*/
+static uint8_t wr_buff[READ_WRITE_SZIZE];
+
+/**@brief   File read buffer.*/
+static uint8_t rd_buff[READ_WRITE_SZIZE];
+
+/**@brief   Block device handle.*/
+static struct ext4_blockdev *bd;
+
+/**@brief   Block cache handle.*/
+static struct ext4_bcache   *bc;
+
+static char* entry_to_str(uint8_t type)
+{
+    switch(type){
+    case EXT4_DIRENTRY_UNKNOWN:
+        return "[UNK] ";
+    case EXT4_DIRENTRY_REG_FILE:
+        return "[FIL] ";
+    case EXT4_DIRENTRY_DIR:
+        return "[DIR] ";
+    case EXT4_DIRENTRY_CHRDEV:
+        return "[CHA] ";
+    case EXT4_DIRENTRY_BLKDEV:
+        return "[BLK] ";
+    case EXT4_DIRENTRY_FIFO:
+        return "[FIF] ";
+    case EXT4_DIRENTRY_SOCK:
+        return "[SOC] ";
+    case EXT4_DIRENTRY_SYMLINK:
+        return "[SYM] ";
+    default:
+        break;
+    }
+    return "[???]";
+}
+
+static void dir_ls(const char *path)
+{
+    int j = 0;
+    char sss[255];
+    ext4_dir d;
+    ext4_direntry *de;
+
+    printf("********************\n");
+
+    ext4_dir_open(&d, path);
+    de = ext4_dir_entry_get(&d, j++);
+    printf("ls %s\n", path);
+
+    while(de){
+        memcpy(sss, de->name, de->name_length);
+        sss[de->name_length] = 0;
+        printf("%s", entry_to_str(de->inode_type));
+        printf("%s", sss);
+        printf("\n");
+        de = ext4_dir_entry_get(&d, j++);
+    }
+    printf("********************\n");
+    ext4_dir_close(&d);
+}
+
+static void mp_stats(void)
+{
+    struct ext4_mount_stats stats;
+    ext4_mount_point_stats("/mp/", &stats);
+
+    printf("********************\n");
+    printf("ext4_mount_point_stats\n");
+    printf("inodes_count = %u\n", stats.inodes_count);
+    printf("free_inodes_count = %u\n", stats.free_inodes_count);
+    printf("blocks_count = %u\n", (uint32_t)stats.blocks_count);
+    printf("free_blocks_count = %u\n", (uint32_t)stats.free_blocks_count);
+    printf("block_size = %u\n", stats.block_size);
+    printf("block_group_count = %u\n", stats.block_group_count);
+    printf("blocks_per_group= %u\n", stats.blocks_per_group);
+    printf("inodes_per_group = %u\n", stats.inodes_per_group);
+    printf("volume_name = %s\n", stats.volume_name);
+
+    printf("********************\n");
+
+}
+
+static void block_stats(void)
+{
+    uint32_t i;
+
+    printf("********************\n");
+    printf("ext4 blockdev stats\n");
+    printf("bdev->bread_ctr = %u\n", bd->bread_ctr);
+    printf("bdev->bwrite_ctr = %u\n", bd->bwrite_ctr);
+
+
+    printf("bcache->ref_blocks = %u\n", bc->ref_blocks);
+    printf("bcache->max_ref_blocks = %u\n", bc->max_ref_blocks);
+    printf("bcache->lru_ctr = %u\n", bc->lru_ctr);
+
+    printf("\n");
+    for (i = 0; i < bc->cnt; ++i) {
+        printf("bcache->refctr[%d]= %u\n", i, bc->refctr[i]);
+    }
+
+    printf("\n");
+    for (i = 0; i < bc->cnt; ++i) {
+        printf("bcache->lru_id[%d] = %u\n", i, bc->lru_id[i]);
+    }
+
+    printf("\n");
+    for (i = 0; i < bc->cnt; ++i) {
+        printf("bcache->free_delay[%d] = %d\n", i, bc->free_delay[i]);
+    }
+
+    printf("\n");
+    for (i = 0; i < bc->cnt; ++i) {
+        printf("bcache->lba[%d] = %u\n", i, (uint32_t)bc->lba[i]);
+    }
+
+    printf("********************\n");
+}
+
+static clock_t get_ms(void)
+{
+    return hw_get_ms();
+}
+
+static bool dir_test(int len)
+{
+    ext4_file f;
+    int       r;
+    int       i;
+    char path[64];
+    clock_t diff;
+    clock_t stop;
+    clock_t start;
+    start = get_ms();
+
+    printf("Directory create: /mp/dir1\n");
+    r = ext4_dir_mk("/mp/dir1");
+    if(r != EOK){
+        printf("Unable to create directory: /mp/dir1\n");
+        return false;
+    }
+
+
+    printf("Add files to: /mp/dir1\n");
+    for (i = 0; i < len; ++i) {
+        sprintf(path, "/mp/dir1/f%d", i);
+        r = ext4_fopen(&f, path, "wb");
+        if(r != EOK){
+            printf("Unable to create file in directory: /mp/dir1\n");
+            return false;
+        }
+    }
+
+    stop =  get_ms();
+    diff = stop - start;
+    dir_ls("/mp/dir1");
+    printf("dir_test time: %d ms\n", (int)diff);
+    return true;
+}
+
+
+static bool file_test(void)
+{
+    int r;
+    uint32_t  size;
+    ext4_file f;
+    int i;
+    clock_t start;
+    clock_t stop;
+    clock_t diff;
+    uint32_t kbps;
+    uint64_t size_bytes;
+    /*Add hello world file.*/
+    r = ext4_fopen(&f, "/mp/hello.txt", "wb");
+    r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0);
+    r = ext4_fclose(&f);
+
+
+    printf("ext4_fopen: test1\n");
+
+    start = get_ms();
+    r = ext4_fopen(&f, "/mp/test1", "wb");
+    if(r != EOK){
+        printf("ext4_fopen ERROR = %d\n", r);
+        return false;
+    }
+
+    printf("ext4_write: %d * %d ...\n" , rw_szie, rw_count);
+    for (i = 0; i < rw_count; ++i) {
+
+        memset(wr_buff, i % 10 + '0', rw_szie);
+
+        r = ext4_fwrite(&f, wr_buff, rw_szie, &size);
+
+        if((r != EOK) || (size != rw_szie))
+            break;
+
+        if(!(i % (rw_count >> 3))){
+            printf("*");
+            fflush(stdout);
+        }
+    }
+
+    if(i != rw_count){
+        printf("ERROR: rw_count = %d\n", i);
+        return false;
+    }
+
+    printf(" OK\n");
+    stop = get_ms();
+    diff = stop - start;
+    size_bytes = rw_szie * rw_count;
+    size_bytes = (size_bytes * 1000) / 1024;
+    kbps = (size_bytes) / (diff + 1);
+    printf("file_test write time: %d ms\n", (int)diff);
+    printf("file_test write speed: %d KB/s\n", (int)kbps);
+    r = ext4_fclose(&f);
+    printf("ext4_fopen: test1\n");
+
+
+    start = get_ms();
+    r = ext4_fopen(&f, "/mp/test1", "r+");
+    if(r != EOK){
+        printf("ext4_fopen ERROR = %d\n", r);
+        return false;
+    }
+
+    printf("ext4_read: %d * %d ...\n" , rw_szie, rw_count);
+
+    for (i = 0; i < rw_count; ++i) {
+        memset(wr_buff, i % 10 + '0', rw_szie);
+        r = ext4_fread(&f, rd_buff, rw_szie, &size);
+
+        if((r != EOK) || (size != rw_szie))
+            break;
+
+        if(memcmp(rd_buff, wr_buff, rw_szie))
+            break;
+
+
+        if(!(i % (rw_count >> 3)))
+            printf("*");
+    }
+    if(i != rw_count){
+        printf("ERROR: rw_count = %d\n", i);
+        return false;
+    }
+    printf(" OK\n");
+    stop = get_ms();
+    diff = stop - start;
+    size_bytes = rw_szie * rw_count;
+    size_bytes = (size_bytes * 1000) / 1024;
+    kbps = (size_bytes) / (diff + 1);
+    printf("file_test read time: %d ms\n", (int)diff);
+    printf("file_test read speed: %d KB/s\n", kbps);
+    r = ext4_fclose(&f);
+
+    return true;
+
+}
+static void cleanup(void)
+{
+    clock_t start;
+    clock_t stop;
+    clock_t diff;
+
+    ext4_fremove("/mp/hello.txt");
+
+    printf("cleanup: remove /mp/test1\n");
+    start = get_ms();
+    ext4_fremove("/mp/test1");
+    stop = get_ms();
+    diff = stop - start;
+    printf("cleanup: time: %d ms\n", (int)diff);
+
+
+    printf("cleanup: remove /mp/dir1\n");
+    start =get_ms();
+    ext4_dir_rm("/mp/dir1");
+    stop = get_ms();
+    diff = stop - start;
+    printf("cleanup: time: %d ms\n", (int)diff);
+}
+
+static bool open_filedev(void)
+{
+
+    bd = ext4_usb_msc_get();
+    bc = ext4_usb_msc_cache_get();
+    if(!bd || !bc){
+        printf("Block device ERROR\n");
+        return false;
+    }
+    return true;
+}
+
+static bool mount(void)
+{
+    int r;
+
+    if(!open_filedev())
+        return false;
+
+    ext4_dmask_set(EXT4_DEBUG_ALL);
+
+    r = ext4_device_register(bd, cache_mode ? 0 : bc, "ext4_filesim");
+    if(r != EOK){
+        printf("ext4_device_register ERROR = %d\n", r);
+        return false;
+    }
+
+    r = ext4_mount("ext4_filesim", "/mp/");
+    if(r != EOK){
+        printf("ext4_mount ERROR = %d\n", r);
+        return false;
+    }
+
+    return true;
+}
+
+static bool umount(void)
+{
+    int r = ext4_umount("/mp/");
+    if(r != EOK){
+        printf("ext4_umount: FAIL %d", r);
+        return false;
+    }
+    return true;
+}
+
+
 int main(void)
 {
-    volatile int count;
     hw_init();
 
+    setbuf(stdout, 0);
     printf("Connect USB drive...\n");
 
     while(!hw_usb_connected())
@@ -29,16 +411,58 @@
         hw_usb_process();
     printf("USB drive connected\n");
 
+    while(!hw_usb_enum_done())
+        hw_usb_process();
+    printf("USB drive enum done\n");
+
     hw_led_red(1);
 
-    int i = 0;
+    printf("Test conditions:\n");
+    printf("Imput name: %s\n", input_name);
+    printf("RW size: %d\n",  rw_szie);
+    printf("RW count: %d\n", rw_count);
+    printf("Cache mode: %s\n", cache_mode ? "dynamic" : "static");
+
+    if(!mount())
+        return EXIT_FAILURE;
+
+
+    cleanup();
+
+    if(sbstat)
+        mp_stats();
+
+    dir_ls("/mp/");
+    if(!dir_test(dir_cnt))
+        return EXIT_FAILURE;
+
+    if(!file_test())
+        return EXIT_FAILURE;
+
+    dir_ls("/mp/");
+
+    if(sbstat)
+        mp_stats();
+
+    if(cleanup_flag)
+        cleanup();
+
+    if(bstat)
+        block_stats();
+
+    if(!umount())
+        return EXIT_FAILURE;
+
+    printf("Test finish: OK\n");
+    printf("Press RESET to restart\n");
     while (1)
     {
+        volatile int count;
         for (count = 0; count < 1000000; count++);
         hw_led_green(1);
         for (count = 0; count < 1000000; count++);
         hw_led_green(0);
-        printf("%d\n", i++);
+
     }
 }
 
--- a/demos/stm32f429_disco/stm/lcd_utils/lcd_log_conf.h
+++ b/demos/stm32f429_disco/stm/lcd_utils/lcd_log_conf.h
@@ -55,7 +55,7 @@
 #define LCD_SCROLL_ENABLED
 
 /* Define the LCD default text color */
-#define LCD_LOG_DEFAULT_COLOR    LCD_COLOR_WHITE
+#define LCD_LOG_DEFAULT_COLOR    LCD_COLOR_GREEN
 
 /* Define the display window settings */
 #define YWINDOW_MIN              3
@@ -65,7 +65,7 @@
 /* Define the cache depth */
 #define CACHE_SIZE               50
 
-#define DEFAULT_FONT            Font8x12
+#define DEFAULT_FONT             Font8x12
 
 /** @defgroup LCD_LOG_CONF_Exported_TypesDefinitions
   * @{
--- a/demos/stm32f429_disco/stm/usb_user/usbh_usr.c
+++ b/demos/stm32f429_disco/stm/usb_user/usbh_usr.c
@@ -1,29 +1,29 @@
 /**
-  ******************************************************************************
-  * @file    usbh_usr.c
-  * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    11-November-2013
-  * @brief   USB Host User Functions
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
-  *
-  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
-  * You may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at:
-  *
-  *        http://www.st.com/software_license_agreement_liberty_v2
-  *
-  * Unless required by applicable law or agreed to in writing, software 
-  * distributed under the License is distributed on an "AS IS" BASIS, 
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  *
-  ******************************************************************************
-  */
+ ******************************************************************************
+ * @file    usbh_usr.c
+ * @author  MCD Application Team
+ * @version V1.0.1
+ * @date    11-November-2013
+ * @brief   USB Host User Functions
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *        http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
 
 /* Includes ------------------------------------------------------------------*/
 #include "usbh_usr.h"
@@ -45,26 +45,26 @@
 /*  The purpose of this register is to speed up the execution */
 
 USBH_Usr_cb_TypeDef USBH_USR_cb =
-  {
-    USBH_USR_Init,
-    USBH_USR_DeInit,
-    USBH_USR_DeviceAttached,
-    USBH_USR_ResetDevice,
-    USBH_USR_DeviceDisconnected,
-    USBH_USR_OverCurrentDetected,
-    USBH_USR_DeviceSpeedDetected,
-    USBH_USR_Device_DescAvailable,
-    USBH_USR_DeviceAddressAssigned,
-    USBH_USR_Configuration_DescAvailable,
-    USBH_USR_Manufacturer_String,
-    USBH_USR_Product_String,
-    USBH_USR_SerialNum_String,
-    USBH_USR_EnumerationDone,
-    USBH_USR_UserInput,
-    USBH_USR_MSC_Application,
-    USBH_USR_DeviceNotSupported,
-    USBH_USR_UnrecoveredError
-  };
+{
+        USBH_USR_Init,
+        USBH_USR_DeInit,
+        USBH_USR_DeviceAttached,
+        USBH_USR_ResetDevice,
+        USBH_USR_DeviceDisconnected,
+        USBH_USR_OverCurrentDetected,
+        USBH_USR_DeviceSpeedDetected,
+        USBH_USR_Device_DescAvailable,
+        USBH_USR_DeviceAddressAssigned,
+        USBH_USR_Configuration_DescAvailable,
+        USBH_USR_Manufacturer_String,
+        USBH_USR_Product_String,
+        USBH_USR_SerialNum_String,
+        USBH_USR_EnumerationDone,
+        USBH_USR_UserInput,
+        USBH_USR_MSC_Application,
+        USBH_USR_DeviceNotSupported,
+        USBH_USR_UnrecoveredError
+};
 
 
 uint32_t __IO USB_Host_Application_Ready;
@@ -92,20 +92,20 @@
 /* Private functions ---------------------------------------------------------*/
 
 /**
-  * @brief  Add the host lib initialization message to the console
-  * @param  None
-  * @retval None
-  */
+ * @brief  Add the host lib initialization message to the console
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_Init(void)
 {
-  USB_Host_Application_Ready = 0;
+    USB_Host_Application_Ready = 0;
 }
 
 /**
-  * @brief  Add the device attachement message to the console
-  * @param  None
-  * @retval None
-  */
+ * @brief  Add the device attachement message to the console
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_DeviceAttached(void)
 {
 }
@@ -112,10 +112,10 @@
 
 
 /**
-  * @brief  Add the unrecovered error message to the console
-  * @param  None
-  * @retval None
-  */
+ * @brief  Add the unrecovered error message to the console
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_UnrecoveredError (void)
 {
 }
@@ -122,21 +122,21 @@
 
 
 /**
-  * @brief Add the device disconnection message to the console and free 
-  *        USB associated resources
-  * @param  None
-  * @retval None
-  */
+ * @brief Add the device disconnection message to the console and free
+ *        USB associated resources
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_DeviceDisconnected (void)
 {
-  USB_Host_Application_Ready = 0;
-//  f_mount(0, NULL);
+    USB_Host_Application_Ready = 0;
+    //  f_mount(0, NULL);
 }
 /**
-  * @brief  callback of the device reset event
-  * @param  None
-  * @retval None
-  */
+ * @brief  callback of the device reset event
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_ResetDevice(void)
 {
 }
@@ -143,37 +143,37 @@
 
 
 /**
-  * @brief  Add the device speed message to the console
-  * @param  Device speed
-  * @retval None
-  */
+ * @brief  Add the device speed message to the console
+ * @param  Device speed
+ * @retval None
+ */
 void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed)
 {
 }
 
 /**
-  * @brief  Add the USB device vendor and MFC Ids to the console
-  * @param  device descriptor
-  * @retval None
-  */
+ * @brief  Add the USB device vendor and MFC Ids to the console
+ * @param  device descriptor
+ * @retval None
+ */
 void USBH_USR_Device_DescAvailable(void *DeviceDesc)
 {
 }
 
 /**
-  * @brief  Device addressed event callbacak
-  * @param  None
-  * @retval None
-  */
+ * @brief  Device addressed event callbacak
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_DeviceAddressAssigned(void)
 {
 }
 
 /**
-  * @brief  Add the device class description to the console
-  * @param  Configuration descriptor
-  * @retval None
-  */
+ * @brief  Add the device class description to the console
+ * @param  Configuration descriptor
+ * @retval None
+ */
 void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc,
     USBH_InterfaceDesc_TypeDef *itfDesc,
     USBH_EpDesc_TypeDef *epDesc)
@@ -181,28 +181,28 @@
 }
 
 /**
-  * @brief  Add the MFC String to the console
-  * @param  Manufacturer String
-  * @retval None
-  */
+ * @brief  Add the MFC String to the console
+ * @param  Manufacturer String
+ * @retval None
+ */
 void USBH_USR_Manufacturer_String(void *ManufacturerString)
 {
 }
 
 /**
-  * @brief  Add the Product String to the console
-  * @param  Product String
-  * @retval None
-  */
+ * @brief  Add the Product String to the console
+ * @param  Product String
+ * @retval None
+ */
 void USBH_USR_Product_String(void *ProductString)
 {
 }
 
 /**
-  * @brief  Add the Srial Number String to the console
-  * @param  SerialNum_String
-  * @retval None
-  */
+ * @brief  Add the Srial Number String to the console
+ * @param  SerialNum_String
+ * @retval None
+ */
 void USBH_USR_SerialNum_String(void *SerialNumString)
 {
 }
@@ -210,38 +210,38 @@
 
 
 /**
-  * @brief  Enumeration complete event callback
-  * @param  None
-  * @retval None
-  */
+ * @brief  Enumeration complete event callback
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_EnumerationDone(void)
 {
 }
 
 /**
-  * @brief  Device is not supported callback
-  * @param  None
-  * @retval None
-  */
+ * @brief  Device is not supported callback
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_DeviceNotSupported(void)
 {
 }
 
 /**
-  * @brief  User Action for application state entry callback
-  * @param  None
-  * @retval USBH_USR_Status : User response for key button
-  */
+ * @brief  User Action for application state entry callback
+ * @param  None
+ * @retval USBH_USR_Status : User response for key button
+ */
 USBH_USR_Status USBH_USR_UserInput(void)
 {
-  return USBH_USR_RESP_OK;
+    return USBH_USR_RESP_OK;
 }
 
 /**
-  * @brief  Over Current Detected on VBUS
-  * @param  None
-  * @retval Staus
-  */
+ * @brief  Over Current Detected on VBUS
+ * @param  None
+ * @retval Staus
+ */
 void USBH_USR_OverCurrentDetected (void)
 {
 }
@@ -248,51 +248,42 @@
 
 
 /**
-  * @brief  Mass storage application main handler
-  * @param  None
-  * @retval Staus
-  */
+ * @brief  Mass storage application main handler
+ * @param  None
+ * @retval Staus
+ */
 int USBH_USR_MSC_Application(void)
 {
-  char temp[40];
-
-  if(USB_Host_Application_Ready == 0)
-  {
-    /* Initializes the File System*/
-    //if ( f_mount( 0, &USBH_fatfs ) != FR_OK )
-    if(1)
+    if(USB_Host_Application_Ready == 0)
     {
-      /* efs initialisation fails*/
-      USB_Host_Application_Ready = 1;
-      return -1;
-    }
-    sprintf (temp, "[FS] USB Disk capacity:%d MB", (int)((USBH_MSC_Param.MSCapacity * \
-      USBH_MSC_Param.MSPageLength) / 1024 / 1024));
 
-    USB_Host_Application_Ready = 1;
-  }
-  return(0);
+        uint64_t cap = (uint64_t)USBH_MSC_Param.MSCapacity * USBH_MSC_Param.MSPageLength;
+        printf ("USR_MSC size: %d MB\n", (int)(cap / (1024 * 1024)));
+
+        USB_Host_Application_Ready = 1;
+    }
+    return(0);
 }
 /**
-  * @brief  De-init User state and associated variables
-  * @param  None
-  * @retval None
-  */
+ * @brief  De-init User state and associated variables
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_DeInit(void)
 {
-  USB_Host_Application_Ready = 0;
+    USB_Host_Application_Ready = 0;
 }
 
 /**
-  * @brief  Handle Modules Background processes in the main task
-  * @param  None
-  * @retval None
-*/
+ * @brief  Handle Modules Background processes in the main task
+ * @param  None
+ * @retval None
+ */
 void USBH_USR_BackgroundProcess (void)
 {
-  if((USB_Host_Application_Ready == 0) || (HCD_IsDeviceConnected(&USB_OTG_Core) == 0))
-  {
-    USBH_Process(&USB_OTG_Core, &USB_Host);   
-  }
+    if((USB_Host_Application_Ready == 0) || (HCD_IsDeviceConnected(&USB_OTG_Core) == 0))
+    {
+        USBH_Process(&USB_OTG_Core, &USB_Host);
+    }
 }
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null
+++ b/demos/stm32f429_disco/usb_msc_lwext4.c
@@ -1,0 +1,161 @@
+
+#include <ext4_config.h>
+#include <ext4_blockdev.h>
+#include <ext4_errno.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include <hw_init.h>
+#include <usbh_msc_core.h>
+#include <usbh_usr.h>
+
+
+/**@brief   Block size.*/
+#define USB_MSC_BLOCK_SIZE          512
+
+extern USB_OTG_CORE_HANDLE          USB_OTG_Core;
+extern USBH_HOST                    USB_Host;
+
+/**@brief   MBR_block ID*/
+#define MBR_BLOCK_ID                0
+#define MBR_PART_TABLE_OFF          446
+
+struct part_tab_entry {
+    uint8_t  status;
+    uint8_t  chs1[3];
+    uint8_t  type;
+    uint8_t  chs2[3];
+    uint32_t first_lba;
+    uint32_t sectors;
+}__attribute__((packed));
+
+/**@brief   Partition block offset*/
+static uint32_t part_offset;
+
+/**********************BLOCKDEV INTERFACE**************************************/
+static int usb_msc_open(struct ext4_blockdev *bdev);
+static int usb_msc_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
+    uint32_t blk_cnt);
+static int usb_msc_bwrite(struct ext4_blockdev *bdev, const void *buf,
+    uint64_t blk_id, uint32_t blk_cnt);
+static int usb_msc_close(struct  ext4_blockdev *bdev);
+
+
+/******************************************************************************/
+EXT4_BLOCKDEV_STATIC_INSTANCE(
+    _usb_msc,
+    USB_MSC_BLOCK_SIZE,
+    0,
+    usb_msc_open,
+    usb_msc_bread,
+    usb_msc_bwrite,
+    usb_msc_close
+);
+
+/******************************************************************************/
+EXT4_BCACHE_STATIC_INSTANCE(_usb_msc_cache, CONFIG_BLOCK_DEV_CACHE_SIZE, 1024);
+
+/******************************************************************************/
+
+static int usb_msc_open(struct ext4_blockdev *bdev)
+{
+    (void)bdev;
+
+    static uint8_t mbr[512];
+    struct part_tab_entry *part0;
+    uint8_t status;
+
+    if(!hw_usb_connected())
+        return EIO;
+    do
+    {
+        status = USBH_MSC_Read10(&USB_OTG_Core, mbr, 0, USB_MSC_BLOCK_SIZE);
+        USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
+
+        if(!hw_usb_connected())
+            return EIO;
+
+    }
+    while(status == USBH_MSC_BUSY );
+
+    if(status != USBH_MSC_OK)
+        return EIO;
+
+    part0 = (struct part_tab_entry *)(mbr + MBR_PART_TABLE_OFF);
+
+    part_offset = part0->first_lba;
+    _usb_msc.ph_bcnt = USBH_MSC_Param.MSCapacity;
+
+    return hw_usb_connected() ? EOK : EIO;
+}
+
+static int usb_msc_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
+    uint32_t blk_cnt)
+{
+    uint8_t status;
+
+    if(!hw_usb_connected())
+        return EIO;
+
+    do
+    {
+        status = USBH_MSC_Read10(&USB_OTG_Core, buf, blk_id + part_offset, _usb_msc.ph_bsize * blk_cnt);
+        USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
+
+        if(!hw_usb_connected())
+            return EIO;
+    }
+    while(status == USBH_MSC_BUSY );
+
+    if(status != USBH_MSC_OK)
+        return EIO;
+
+    return EOK;
+
+}
+
+static int usb_msc_bwrite(struct ext4_blockdev *bdev, const void *buf,
+    uint64_t blk_id, uint32_t blk_cnt)
+{
+    uint8_t status;
+
+    if(!hw_usb_connected())
+        return EIO;
+
+    do
+    {
+        status = USBH_MSC_Write10(&USB_OTG_Core, (void *)buf, blk_id + part_offset, _usb_msc.ph_bsize * blk_cnt);
+        USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
+
+        if(!hw_usb_connected())
+            return EIO;
+    }
+    while(status == USBH_MSC_BUSY );
+
+    if(status != USBH_MSC_OK)
+        return EIO;
+
+    return EOK;
+}
+
+static int usb_msc_close(struct  ext4_blockdev *bdev)
+{
+    (void)bdev;
+    return EOK;
+}
+
+/******************************************************************************/
+
+struct ext4_bcache*   ext4_usb_msc_cache_get(void)
+{
+    return &_usb_msc_cache;
+}
+
+
+struct ext4_blockdev* ext4_usb_msc_get(void)
+{
+    return &_usb_msc;
+}
+
--- /dev/null
+++ b/demos/stm32f429_disco/usb_msc_lwext4.h
@@ -1,0 +1,45 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef USB_MSC_LWEXT4_H_
+#define USB_MSC_LWEXT4_H_
+
+#include <ext4_config.h>
+#include <ext4_blockdev.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/**@brief   USB MSC cache get.*/
+struct ext4_bcache*   ext4_usb_msc_cache_get(void);
+
+/**@brief   USB MSC blockdev get.*/
+struct ext4_blockdev* ext4_usb_msc_get(void);
+
+
+
+#endif /* USB_MSC_LWEXT4_H_ */