Author Topic: Help with getting the internal Flash of K64F to work as USB MSD  (Read 5801 times)

Offline SomeUser

  • Newbie
  • *
  • Posts: 4
    • View Profile
Help with getting the internal Flash of K64F to work as USB MSD
« on: December 18, 2017, 04:01:46 PM »
Hello, I would like to write an application using the internal storage of the K64F (512KiB, or even better 768KiB if possible) as USB MSD.

The intended use is for the user to move files to the MSD, which the program will then use.


Enabling USB MSD compiles okay it seems, but setting

Code: [Select]
//#define SDCARD_SUPPORT                                                 // SD-card interface
#define FLASH_FAT                                                      // FAT in internal flash
//#define SPI_FLASH_FAT                                                  // FAT in external SPI flash
#define FAT_EMULATION

Does not compile.
I get:
Code: [Select]
Building file: ../uTasker/utFAT/mass_storage.c
Invoking: Cross ARM C Compiler
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wall  -g -D_KINETIS -D_KDS -D_GNU -I"[i]removed[/i]" -std=c99 -MMD -MP -MF"uTasker/utFAT/mass_storage.d" -MT"uTasker/utFAT/mass_storage.o" -c -o "uTasker/utFAT/mass_storage.o" "../uTasker/utFAT/mass_storage.c"
../uTasker/utFAT/mass_storage.c: In function 'fnMassStorage':
../uTasker/utFAT/mass_storage.c:2061:32: error: 'DISK_EM_FAT' undeclared (first use in this function)
             if (iDiskNumber == DISK_EM_FAT) {
                                ^
../uTasker/utFAT/mass_storage.c:2061:32: note: each undeclared identifier is reported only once for each function it appears in
../uTasker/utFAT/mass_storage.c:2072:17: error: continue statement not within a loop
                 continue;
                 ^
../uTasker/utFAT/mass_storage.c: In function 'fnGetDataPointer':
../uTasker/utFAT/mass_storage.c:7380:14: error: 'DISK_EM_FAT' undeclared (first use in this function)
     iDisk -= DISK_EM_FAT;
              ^
../uTasker/utFAT/mass_storage.c: In function 'fnGenerateFAT':
../uTasker/utFAT/mass_storage.c:7403:46: error: 'DISK_EM_FAT' undeclared (first use in this function)
     int iDisk = (ptr_utDisk->ucDriveNumber - DISK_EM_FAT);
                                              ^
../uTasker/utFAT/mass_storage.c: In function 'fnReadEmulatedSector':
../uTasker/utFAT/mass_storage.c:7562:18: error: 'DISK_EM_FAT' undeclared (first use in this function)
         iDisk -= DISK_EM_FAT;
                  ^
../uTasker/utFAT/mass_storage.c: At top level:
../uTasker/utFAT/mass_storage.c:7610:12: error: redefinition of 'fnReadSector'
 extern int fnReadSector(unsigned char ucDisk, unsigned char *ptrBuffer, unsigned long ulSectorNumber)
            ^
../uTasker/utFAT/mass_storage.c:7226:12: note: previous definition of 'fnReadSector' was here
 extern int fnReadSector(unsigned char ucDisk, unsigned char *ptrBuffer, unsigned long ulSectorNumber)
            ^
../uTasker/utFAT/mass_storage.c:7618:12: error: redefinition of 'fnWriteSector'
 extern int fnWriteSector(unsigned char ucDisk, unsigned char *ptrBuffer, unsigned long ulSectorNumber)
            ^
../uTasker/utFAT/mass_storage.c:7263:12: note: previous definition of 'fnWriteSector' was here
 extern int fnWriteSector(unsigned char ucDisk, unsigned char *ptrBuffer, unsigned long ulSectorNumber)
            ^
../uTasker/utFAT/mass_storage.c: In function 'fnPrepareRootDirectory':
../uTasker/utFAT/mass_storage.c:7679:50: error: 'DISK_EM_FAT' undeclared (first use in this function)
         int iDisk = (ptr_utDisk->ucDriveNumber - DISK_EM_FAT);
                                                  ^
../uTasker/utFAT/mass_storage.c: At top level:
../uTasker/utFAT/mass_storage.c:7849:22: error: redefinition of 'fnGetDiskInfo'
 extern const UTDISK *fnGetDiskInfo(unsigned char ucDisk)
                      ^
../uTasker/utFAT/mass_storage.c:7275:22: note: previous definition of 'fnGetDiskInfo' was here
 extern const UTDISK *fnGetDiskInfo(unsigned char ucDisk)
                      ^
../uTasker/utFAT/mass_storage.c:1578:20: warning: 'fnReadPartialEmulatedSector' used but never defined [enabled by default]
         static int fnReadPartialEmulatedSector(UTDISK *ptr_utDisk, unsigned long ulSector, void *ptrBuf, unsigned short usOffset, unsigned short usLength);
                    ^
uTasker/utFAT/subdir.mk:18: recipe for target 'uTasker/utFAT/mass_storage.o' failed
make: *** [uTasker/utFAT/mass_storage.o] Error 1

Is there a specific way I can accomplish my goal easily?
And is the source code for the
USB-MSD with SD card, internal Flash disk and external SPI-Flash disk
example on the Kinetis landing page available (So I can strip out the SD-Card and SPI-Flash code)?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Help with getting the internal Flash of K64F to work as USB MSD
« Reply #1 on: December 18, 2017, 04:21:37 PM »
Hi

Disable FTP_UTFAT and HTTP_UTFAT if you have the FTP and Web servers enabled since they want to use DISK D (the SD card)

Start by using just FLASH_FAT (without FAT emulation) [I need to check whether FAT emulation works together with just USB-MSD FAT in Flash]

The single project code was used to generate all reference binaries on the Kinetis landing page so to strip out SD card it just means to not have the SDCARD_SUPPORT define enabled.

Regards

Mark

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Help with getting the internal Flash of K64F to work as USB MSD
« Reply #2 on: December 18, 2017, 06:17:13 PM »
Hi

I have an update for working with internal Flash FAT plus emulated FAT.
It needed a specific combination setup in mass_storage.h since it hasn't been used before.

    #define DISK_C                         0
    #define DISK_D                         1
    #define DISK_COUNT                     2
    #define DISK_INTERNAL_FLASH            DISK_C
    #define DISK_EM_FAT                    DISK_D


This means that disk C is the internal Flash and disk D is the emulated disk.

When using with USB-MSD the number of LUMs must also be set to match the number of disks that you want to make visible (otherwise it will only show one external disk drive - disk C)
#define NUMBER_USB_MSD 2

Finally I had to make a couple of changes to the mass storage task so that it would correctly mount the emulated drive and not try to work with disk E (which gave the build errors).

These modifications have been checked in and I also included them in the standalone utFAT package at http://www.utasker.com/forum/index.php?topic=1667.0

Beware that both FAT flash and the emulated flash (the way that the application is configuring it) will both be using internal Flash. When configuring the areas and sizes of the two operations you may need to ensure that they don't overlap  - although emulated FAT is read only and so it will not disturb. If overlapping you would in fact see the real FAT data in on the emulated Flash disk as RAW binary...

In the command line menu (Disk Interface menu) one can also check the operation of the two disks. Eg. the emulated FAT (disk D) will appear as a formatted disk with fixed files as follows:
>disk d
Disk D
>dir
Directory D:\

---A 03.08.2015  08:23             3722 Raw Data File 1.bin
---A 03.08.2015  13:09            74982 Raw Data File 2.bin
---A 03.08.2015  08:23            15816 Formatted Data File 1.csv
---A 03.08.2015  13:09           318672 Formatted Data File 2.csv
---A 26.10.2015  12:00           262144 software.bin
---A 26.10.2015  12:00              354 uTasker.html
---A 26.10.2015  12:00           262144 ram.bin
7 files with 937834 bytes
0 directories, 106496 bytes free
D:\>


If the areas overlap I expect that the raw FAT content will appear in the software.bin file!

Good luck

Regards

Mark

Offline SomeUser

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Help with getting the internal Flash of K64F to work as USB MSD
« Reply #3 on: December 21, 2017, 02:01:50 AM »
I still seem to have a Problem.

Let's for now ignore the Emulated fat.


I feel pretty stupid by now,
but I seem to be unable to figure out, as simple as it should be,
how to access the files on the MSD in my code on the microcontroller side.

So if I connect the board to the computer, the K64F shows up as a 512KiB MSD.
Now I format it (using the computer), and put a set of txt files in folders on it.

Let's assume:
Code: [Select]
H:.
????Log files
?       Log2017-12-19.txt
?       Log2017-12-20.txt
?       Log2017-12-18.txt
?       Log2017-12-21.txt
?       Log2017-12-17.txt
?
????Alternative configuration
?       Conf2.txt
?       Conf0.txt
?       Conf1.txt
?
????Default configuration
        Conf2.txt
        Conf0.txt
        Conf1.txt

How would I access those files in code on the microcontroller side?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Help with getting the internal Flash of K64F to work as USB MSD
« Reply #4 on: December 21, 2017, 03:25:59 AM »
Hi

The microcontroller sees the disk as a FAT disk and can use the utFAT interface.

Try the following:

1. Using the debug menu (usually on the UART but can also be on USB-CDC [as composite with the USB-MSD) or on Telnet] go to the "Disk Interface" - menu number 8 - and you can use a DOS like interface to list the files, print them, rename, them, delete them, or add files and directories.
Use the "info" command to get details of the disk that has been created (see whether it signifies FAT12/16 or 32)

2. Check the code in debug.c which is handling these commands - eg. to read a file (DO_PRINT_FILE) it does
utOpenFile("file name.txt", &utFile, ptr_utDirectory[ucPresentDisk], UTFAT_OPEN_FOR_READ);
utReadFile(&utFile, ucTemp, sizeof(ucTemp);

to read the first buffer content of it.

The API is described in the utFAT guide: http://www.utasker.com/docs/uTasker/uTasker_utFAT.PDF
where there is a description of the command to use and an example of each.
Since the computer host is writing the content as FAT32 (usually - it may also use FAT16 on small disks) the same FAT interface is needed by the processor.

Note that, if the disk is being formatted by the computer as FAT12 or FAT16, make sure that you have UTFAT16 and/or UTFAT12 enabled so that this is also supported.
You can also format the disk on the command line interface (or re-format it) so that it is forced to FAT32 - I expect that all PCs will do this though (Win XP may have done FAT12).

Finally, this interface is the same for the application as when working with an SD card.

Regards

Mark

P.S. Note that if you use the simulator you can format the disk via the command line interface. You can then create some test files with some content (also in the menu) and then you can test and debug your routines that are opening and reading their content. This is easier in Visual Studio than doing the same on the target and it will tend to give you exceptions/reasons in case code is not working correctly with the flash.
« Last Edit: December 21, 2017, 03:29:40 AM by mark »