USB MSD Host for the Freedom Board

Sometimes things take longer than anticipated. And this is definitely the case for my USB MSD Host project where I wanted to use a USB memory stick with the Freedom FRDM-KL25Z board.

Memory Stick attached to the Freedom Board

Memory Stick attached to the Freedom Board

But finally, I have things working. At least most of the time ….

USB MSD Host

The USB MSD (Mass Storage Device) class is designed to be used for things like diskette drives, hard drives or memory sticks. To attach a memory stick to the USB bus, the memory stick is usally a USB device, and the other side needs to be the host. The first barrier to overcome is the FRDM-KL25Z board does *not* give the needed 5V to the USB bus which is required for the host mode. To overcome this, I’m using a patched USB cable as outlined in this post.

File System

While it is possible to use the MSD device as a ‘raw’ device (doing raw block read/write operation), the usual way is to use the device with a file system on it. I’m using the open source FatFS with SD cards successfully already in many projects, so I decided to use FatFS in this project too.

Operating System

While it is possible to add USB MSD Host support in bare metal (without RTOS), using an RTOS makes it much more convenient and less complicated. I have ported the Freescale USB stack for this project. While the stack itself does not assume an RTOS, many aspects of the stack like memory management or periodic polling of the USB device block are handled in such a complicated way, that I think using it without the help of an RTOS makes things really difficult. Especially the dynamic memory management in the USB stack had many inconsistencies, and to track potential memory leaks the help of FreeRTOS was critical. So this is what I ended up using: FreeRTOS.

Processor Expert Components

The example project (link at the end of this article) has several Processor Expert components. Beside of the RTOS, it has components for LED’s, a command line shell implementation, the FatFS file system and the USB Host components:

Processor Expert MSD Host Example Project

Processor Expert MSD Host Example Project

FatFs Memory

The FatFsMem_USB_MSD component implements the ‘memory’ device for FatFs: it allows to read and write to the device. The FatFs low-level routines are not exposed for the user application, as used internally by FatFs. What are exposed is are initialization and utility routines:

FatFsMem_USB_MSD

FatFsMem_USB_MSD

Freescale USB Stack Component

My custom USB stack component is using the Init component to initialize the low-level USB peripheral of the Kinetis device. Additionally it includes the FSL_USB_MSD_Host component which is a wrapper to the Freescale USB stack:

FSL USB Stack with MSD Host

FSL USB Stack with MSD Host

Host Task

The USB stack needs to be polled periodically to do the USB transactions. I have implemented this like this as a FreeRTOS task:

/*
 * host.c
 *      Author: Erich Styger
 */

#include "host.h"
#include "msd_commands.h"
#include "CLS1.h"
#include "FRTOS1.h"
#include "FsMSD1.h"

static void print(unsigned char *str) {
  CLS1_SendStr(str, CLS1_GetStdio()->stdOut);
}

static void CheckStatus(void) {
  switch (FsMSD1_GetDeviceStatus()) {
     case USB_DEVICE_IDLE:
       break;
     case USB_DEVICE_ATTACHED:
       print((unsigned char*)"Mass Storage Device Attached\n" );
       break;
     case USB_DEVICE_SET_INTERFACE_STARTED:
       break;
     case USB_DEVICE_INTERFACED:
       break;
     case USB_DEVICE_DETACHED:
       print((unsigned char*)"\nMass Storage Device Detached\n" );
       break;
     case USB_DEVICE_OTHER:
       break;
     default:
       print((unsigned char*)"Unknown Mass Storage Device State\n");
       break;
  } /* switch */
}

static portTASK_FUNCTION(HostTask, pvParameters) {
  (void)pvParameters; /* not used */
  FsMSD1_HostInit();
  for(;;) {
    FsMSD1_AppTask();
    CheckStatus();
    FRTOS1_vTaskDelay(10/portTICK_RATE_MS);
  }
}

void HOST_Init(void) {
  if (FRTOS1_xTaskCreate(HostTask, (signed portCHAR *)"Host", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+2, NULL) != pdPASS) {
    for(;;){} /* error */
  }
}

After initialization using FsMSD1_HostInit(), it periodically calls the polling routine FsMSD1_AppTask(). CheckStatus() is used to print a message if a device is attached or removed. The “Host” task is running with a higher priority to make sure the USB bus is served often enough.

Shell Support

I have recently added command line support to the FatFs Processor Expert component. That way it is really easy to add a command line interface to the application where I can inspect the file system, copy files, dump files, etc. The user application part of the shell is implemented in a task, and the command line handlers are listed in a table:

/*
 * Shell.c
 *      Author: Erich Styger
 */

#include "Application.h"
#include "FRTOS1.h"
#include "Shell.h"
#include "CLS1.h"
#include "LEDR.h"
#include "LEDG.h"
#include "FAT1.h"
#include "Host.h"

static const CLS1_ParseCommandCallback CmdParserTable[] =
{
  CLS1_ParseCommand,
#if LEDR_PARSE_COMMAND_ENABLED
  LEDR_ParseCommand,
#endif
#if LEDG_PARSE_COMMAND_ENABLED
  LEDG_ParseCommand,
#endif
#if LEDB_PARSE_COMMAND_ENABLED
  LEDB_ParseCommand,
#endif
#if FRTOS1_PARSE_COMMAND_ENABLED
  FRTOS1_ParseCommand,
#endif
#if RTC1_PARSE_COMMAND_ENABLED
  RTC1_ParseCommand,
#endif
#if FAT1_PARSE_COMMAND_ENABLED
  FAT1_ParseCommand,
#endif
  NULL /* sentinel */
};

static portTASK_FUNCTION(ShellTask, pvParameters) {
  bool cardMounted = FALSE;
  static FAT1_FATFS fileSystemObject;
  unsigned char buf[48];

  (void)pvParameters; /* not used */
  buf[0] = '\0';
  (void)CLS1_ParseWithCommandTable((unsigned char*)CLS1_CMD_HELP, CLS1_GetStdio(), CmdParserTable);
  for(;;) {
    (void)FAT1_CheckCardPresence(&cardMounted,
        0 /* volume */, &fileSystemObject, CLS1_GetStdio());
    (void)CLS1_ReadAndParseWithCommandTable(buf, sizeof(buf), CLS1_GetStdio(), CmdParserTable);
    FRTOS1_vTaskDelay(10/portTICK_RATE_MS);
    LEDG_Neg();
  }
}

void SHELL_Init(void) {
  if (FRTOS1_xTaskCreate(ShellTask, (signed portCHAR *)"Shell", configMINIMAL_STACK_SIZE+300, NULL, tskIDLE_PRIORITY+1, NULL) != pdPASS) {
    for(;;){} /* error */
  }
}

Because some of the FatFS shell operations like to copy a file are using a local buffer on the stack, the task stack size is higher than for the other tasks in the system.

Command Line Interface

The following shows the command line interface:

Command Line Shell

Command Line Shell

With the commands it is possible copy/delete/rename/etc files, or to print the current directory:

Print Directory

Print Directory

Dynamic Memory Usage

The Freescale USB stack is using malloc() and free() to allocate memory. I have replaced them with the FreeRTOS counterparts so I can track the memory usage. The screenshot below shows the free memory (heap) without a memory stick attached, and afterwards:

USB Host Stack Memory Consumption

USB Host Stack Memory Consumption

That means that the USB stack has allocated an extra amount of 3160-2528=632 bytes. Removing the memory stick will free up memory again up to 3072 bytes free bytes, and will go back to 2528 bytes with the memory stick attached. I’m still not sure why it does not free up all the memory, but at least there is no memory leak. I still will need some time to understand where and why the USB stack needs the dynamic memory allocation.

Summary

Finally I have my USB MSD application with FatFs and FreeRTOS running :-). It was much harder than I thought, mainly because of the Freescale USB stack implementation. The GNU gcc compiler warned me about many things, and I have cleaned up the code as much as I could, but I think I still will need time to find and fix bugs in it. I still see occasional problems where the code is stuck in a loop. I need to replace that code with some timeout functionality. The other thing I faced: with the USB stack, my application ROM size exceeded the 64 KByte limit of the free CodeWarrior version. Using the -O1 compiler optimization brought it back it 48 KByte of code. Still, using a USB Host stack sounds like a lot of overhead compared to a SD card interface. I’m still dreaming of having a USB MSD bootloader which only needs a few KBytes of my Flash memory…

Source Code and Example Project

The full source code and Processor Expert components are available on GitHub. The example project shown here is as well available in this GitHub repository here.

Happy Hosting 🙂

Advertisements

96 thoughts on “USB MSD Host for the Freedom Board

  1. You are using the freescale usb stack with freertos. Is there no standard usb stack for freertos ?? From what I can tell most of the freertos demos use a ported usb stack for the micro architecture (e.g. LPC, Freescale, etc). It would be good if there was a more standardised usb stack for freertos which driver support for the various micros supported by freertos.

    The freescale usb stack is for no OS. I think this is used in MQX and/or MQX Lite, so I imagine it should be ported in a similar fashion for FreeRTOS. i.e. similar use of tasks, rtos services, etc.

    Like

    • Hi Simon, I would *love* the fact if there would be a standard (open source) USB stack. That way this would be used as stanard with FreeRTOS. But I’m not aware of any which has been ported. There are bits and pieces, but not something working? As for the stack itself: there is not much you need to have it working with an RTOS, so no dedicated support needed. And if, I can easily add the FreeRTOS functionality (as I did).

      Like

  2. Hi Erich. I am grateful very much for your work. it’s very useful for me.

    I am new enough working with Freescale. I have tried to adapt your program to my MCU, K60, but it gives me some mistakes. It does not recognize me the FSL_USB_MSD_host in USB’s stack. The error is ” No inherited component assigned” in the MSDHost module.

    Other examples and programs I could have adapted to the K60, but this one gives me always mistake. Thank you!!

    Like

    • Hello,
      thanks for that feedback, appreciated 🙂
      As for the MSD Host mode: I have tried it on KL25Z only so far. I’m sure that probably I have missed to include something to properly support the K60N512 (the one I have). Let me see what I can do for you over the next couple of days. But I think that I might have missed some files/settings to properly support the K60. Sorry about that, as I needed it for the KL25Z only so far. But I’ll look into it. ok?

      Like

    • Hi krlosb,
      I worked on the USB MSD Host stack most of today. The good news is: that error your report should be gone.
      I have put an example project on https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/TRW-K60N512/TWR-MK60_USB_MSD_Host
      The bad news is: it does not quite work yet. It raises an interrupt when I attach a memory stick, but it does not properly enumerate. Not sure what the problem is. I think I’m missing something in the driver.

      Like

  3. Pingback: Serial Bootloader for the Freedom Board with Processor Expert | MCU on Eclipse

  4. Hi Eric,

    Is there a method (or work around) to change the device class selector in the latest FSL_USB_Stack from a device to a host, or a host to a device?

    Regards,

    George

    Like

  5. Hi Eric,
    I tried to adapt the program to a K20 using the K60 selection on the FSL_USB_MSD_Host. There were no issues getting the components installed, and the project compiles without errors. The issue is the drive does not properly enumerate. After reading all the comments, I found a similar issue when using a K60. Do you know if anyone has found a solution for this issue?

    Regards,
    George

    Like

  6. Pingback: USB MSD Host for the FRDM-K20D50M Board | MCU on Eclipse

  7. Hi Erich,

    I’m interested in USB MSD device bootloader, to programm MCU just by drag and drop binary file from host PC. Is it possible to do so basing on your host implementation? Did you made some attempts to implement such functionality and can you give me some advice how to bit it?

    Like

  8. Hi Erich, have you read application note AN4368 from Freescale? It’s the same as your MSD host bootloader, but for K60 family. The code of AN doesn’t use RTOS.

    Have you made some comparisons between the two results? For example, is your solution more code efficient?

    Like

  9. Hello Erich,i ‘m glad that this strange winter looks over in your garden

    Thanks for the above example
    I spent days trying to implement something similar based on
    USB_MSD_HOST_MQX_Lite_MKL25Z128_PEx example,in the USB stack 4.1.1.
    In run it detects the attached key,it prints all the tests but it restarts from zero every couple of seconds,as showed by a printf just after PE_low_level_init();
    In debug it stucks in HardFault.
    Following your teachings i used the HardFault bean to analyze it,but strangely it mades everything working ok.I guess this fact deserves further attention.
    At this point i addedd the FatFs bean,but the FsMSD required to manage the underlying memory
    has references to freeRTOS.h for malloc functions etc.
    At this point i dont know ho to move.
    Can you help me about it?

    Diego

    Like

      • HI Erich
        ,the reference is in FSMSD1.c
        #include “freeRTOS.h” /* FreeRTOS malloc() */

        Please could you attach or link the project you ìre talkng about?
        So to compare them and find where i wrong

        Have a nice weekend and thanks
        Diego

        Like

  10. Hi,where is “FRTOS1.h”? I use your Freedom_USBHostMSD project in IAR,but 171 errors finded,Can you help me?

    Like

      • Thank you!
        I am a novice in freescacle arm and IAR IDE。
        I use FRDM-KL26Z+IAR+(your PE project).
        I add the components in PE from your PEupd folder,it’s ok.
        But when i make the project,more errors generated.
        such as:

        Warning[Pa050]: non-native end of line sequence detected (this diagnostic is only issued once) D:\FreeScale\user\test\Freedom_USBHostMSD\Sources\Application.c 1
        Error[Pe079]: expected a type specifier D:\FreeScale\user\test\Freedom_USBHostMSD\Generated_Code\Cpu.h 163
        Error[Pe141]: unnamed prototyped parameters not allowed when body is present D:\FreeScale\user\test\Freedom_USBHostMSD\Generated_Code\Cpu.h 163
        Error[Pe130]: expected a “{” D:\FreeScale\user\test\Freedom_USBHostMSD\Generated_Code\Cpu.h 163
        Warning[Pe012]: parsing restarts here after previous syntax error D:\FreeScale\user\test\Freedom_USBHostMSD\Generated_Code\CLS1.h 111
        Error[Pe020]: identifier “CLS1_StdIO_In_FctType” is undefined D:\FreeScale\user\test\Freedom_USBHostMSD\Generated_Code\CLS1.h 112
        Error[Pe020]: identifier “CLS1_StdIO_OutErr_FctType” is undefined D:\FreeScale\user\test\Freedom_USBHostMSD\Generated_Code\CLS1.h 113
        Error[Pe020]: identifier “CLS1_StdIO_OutErr_FctType” is undefined D:\FreeScale\user\test\Freedom_USBHostMSD\Generated_Code\CLS1.h 114
        Error[Pe020]: identifier “CLS1_StdIO_KeyPressed_FctType” is undefined D:\FreeScale\user\test\Freedom_USBHostMSD\Generated_Code\CLS1.h 115
        what can I do next step?

        Like

      • I do not have this on my side, but it looks like your IAR compiler does not find the header files/include files. It might be a bad idea to start with IAR tools if you are not familiar with it, as this IDE might not be something easy to start with as a novice, especially as IAR does not integrate in a seamless way with Processor Expert. Have you considered to use Eclipse/CodeWarrior/KDS instead? Then you would not run into these kind of issues.

        Like

  11. sorry for replying on different post But I feel replying here is more relevant to others who come later to this post

    So I asked that my code was overflowing .text by ***
    so Now i remember what the problem was
    I have set up every thing again from eclipse for that
    I have followed your DIY Free Toolchain for Kinetis: Part 9 – Express Setup in 8 Steps
    and successfully tested one demo PE_Blinky
    but I noticed when I imported your project Freedom_USBHostMSD from git
    that you used G++ lite (Orphaned configuration. No base extension cfg exists for org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.976069318)
    this means I think sourcery g++ lite for arm eabi is not installed on my machine

    So last time I made few changes those were changed toolchain to Cross ARM GCC
    when I did that and hit OK it gave internal error
    when I was able to compile it it gave compile time error
    so I renamed a variable to some another all occurances

    i think that was reason of thar error but how on earth change addition of a variable increases size by 1024 bytes

    I am not getting anything please help me understand this

    Like

  12. Now I have found a way out tried differant solution
    New PE project
    to which I have added All components
    changed linker do not generate start up
    and It compiled again this is wierd linker error I am facing
    This time I have avoided any modyfiction to code but I could not edit FSL_USB_MSD_HOST componets name Which is of redshaded modification was not posible
    So I have removed FSL_USB_STACK and added from library changed board type

    Generated code and compiled so this was linking error

    03:31:11 **** Incremental Build of configuration Debug for project New_MSD ****
    make all
    Building target: New_MSD.elf
    Invoking: Cross ARM C++ Linker
    arm-none-eabi-g++ -mcpu=cortex-m0plus -mthumb -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g3 -T “C:/Freescale/workspace1/New_MSD/Project_Settings/Linker_Files/ProcessorExpert.ld” -nostartfiles -Xlinker –gc-sections -L”C:/Freescale/workspace1/New_MSD/Project_Settings/Linker_Files” -Wl,-Map,”New_MSD.map” -o “New_MSD.elf” ./Sources/Application.o ./Sources/Events.o ./Sources/Shell.o ./Sources/host.o ./Sources/main.o ./Sources/sa_mtb.o ./Generated_Code/AS1.o ./Generated_Code/ASerialLdd1.o ./Generated_Code/BitIoLdd1.o ./Generated_Code/BitIoLdd2.o ./Generated_Code/BitIoLdd3.o ./Generated_Code/CLS1.o ./Generated_Code/CS1.o ./Generated_Code/Cpu.o ./Generated_Code/FAT1.o ./Generated_Code/FRTOS1.o ./Generated_Code/FsMSD1.o ./Generated_Code/HF1.o ./Generated_Code/LEDB.o ./Generated_Code/LEDG.o ./Generated_Code/LEDR.o ./Generated_Code/LEDpin1.o ./Generated_Code/LEDpin2.o ./Generated_Code/LEDpin3.o ./Generated_Code/MSD1.o ./Generated_Code/PE_LDD.o ./Generated_Code/TI1.o ./Generated_Code/TU1.o ./Generated_Code/TimerIntLdd1.o ./Generated_Code/TmDt1.o ./Generated_Code/USB0.o ./Generated_Code/USB1.o ./Generated_Code/UTIL1.o ./Generated_Code/Vectors.o ./Generated_Code/WAIT1.o ./Generated_Code/croutine.o ./Generated_Code/event_groups.o ./Generated_Code/ff.o ./Generated_Code/heap_1.o ./Generated_Code/heap_2.o ./Generated_Code/heap_3.o ./Generated_Code/heap_4.o ./Generated_Code/host_ch9.o ./Generated_Code/host_close.o ./Generated_Code/host_cnl.o ./Generated_Code/host_common.o ./Generated_Code/host_dev_list.o ./Generated_Code/host_driver.o ./Generated_Code/host_main.o ./Generated_Code/host_rcv.o ./Generated_Code/host_shut.o ./Generated_Code/host_snd.o ./Generated_Code/khci_kinetis.o ./Generated_Code/list.o ./Generated_Code/mem_util.o ./Generated_Code/poll.o ./Generated_Code/port.o ./Generated_Code/queue.o ./Generated_Code/tasks.o ./Generated_Code/timers.o ./Generated_Code/usb_classes.o ./Generated_Code/usb_host_hub.o ./Generated_Code/usb_host_hub_sm.o ./Generated_Code/usb_host_msd_bo.o ./Generated_Code/usb_host_msd_queue.o ./Generated_Code/usb_host_msd_ufi.o ./Generated_Code/usbevent.o ./Generated_Code/usbmsgq.o ./Generated_Code/usbsem.o
    cygwin warning:
    MS-DOS style path detected: C:\Freescale\workspace1\New_MSD\Debug
    Preferred POSIX equivalent is: /cygdrive/c/Freescale/workspace1/New_MSD/Debug
    CYGWIN environment variable option “nodosfilewarning” turns off this warning.
    Consult the user’s guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
    c:/kepler/gnu tools arm embedded/4.8 2013q4/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/bin/ld.exe: warning: cannot find entry symbol __thumb_startup; defaulting to 00000410
    ./Generated_Code/Vectors.o:(.vectortable+0x4): undefined reference to `__thumb_startup’
    collect2.exe: error: ld returned 1 exit status
    make: *** [New_MSD.elf] Error 1

    03:31:13 Build Finished (took 2s.688ms)

    Is this due to cygwin warning

    Like

    • If it finds Cygwin tools, that would be bad. I have not installed Cygwin, as it is source of all kind of strange problems. The issue is if gcc finds something with cygwin, then it will try to use it with bad side effects. So if you have Cygwin installed (e.g in C:\cygwin), rename that folder so it is not found any more. Maybe this helps.

      Like

      • I tried doing as you suggested renaming the cygwin directory but still same linking error
        I think it must not be getting something required for C++ linking error which I googled guess what the first hit is “https://mcuoneclipse.com/2012/10/04/processor-expert-gcc-c-and-kinetis-l-and-mqxlite/” which seems to have solution Thanx for reply and that post of yours I will let you know what happens

        Like

  13. Hi Erich
    I have solved “./Generated_Code/Vectors.o:(.vectortable+0×4): undefined reference to `__thumb_startup’”
    problem by adding Start Up code (startup.c )file

    I have noticed that this is different from your start up files I tried your start up files but could not compile them because of
    But I am unable to compile them compiler says “fatal error: ansi_parms.h: No such file or directory”
    which means no ansi_params.h is not included in include path so could you please give me your both include paths or your suggestion about solving this problem

    I have noticed similar file exists in codewarrior directory exact path is CODEwarrior root/MCU/ARM_EABI_Support/ewl/EWL_C/include/ansi_parms.h but there is no way of finding this file else where. So my conclusions is they are created by codewarrior and Your project was successfully linked because you have compiled the source from codewarrior mine built in eclipse DIY tool-chain so is there any other way to sort this problem or do I have to compile this using codewarrior

    OR my above stated conclusions are fully / partially wrong
    waiting for your response

    Like

    • I forgot to mention that I am getting same error as I was getting previously that is

      Building target: rtos.elf
      Invoking: Cross ARM C++ Linker
      arm-none-eabi-g++ -mcpu=cortex-m0plus -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -T “/home/dev/abc/rtos/Project_Settings/Linker_Files/ProcessorExpert.ld” -nostartfiles -Xlinker –gc-sections -L”/home/dev/abc/rtos/Project_Settings/Linker_Files” -Wl,-Map,”rtos.map” -o “rtos.elf” ./Sources/Application.o ./Sources/Events.o ./Sources/Shell.o ./Sources/host.o ./Sources/main.o ./Sources/sa_mtb.o ./Project_Settings/Startup_Code/startup.o ./Generated_Code/AS1.o ./Generated_Code/ASerialLdd1.o ./Generated_Code/BitIoLdd1.o ./Generated_Code/BitIoLdd2.o ./Generated_Code/BitIoLdd3.o ./Generated_Code/CLS1.o ./Generated_Code/CS1.o ./Generated_Code/Cpu.o ./Generated_Code/FAT1.o ./Generated_Code/FRTOS1.o ./Generated_Code/FsMSD1.o ./Generated_Code/HF1.o ./Generated_Code/LEDB.o ./Generated_Code/LEDG.o ./Generated_Code/LEDR.o ./Generated_Code/LEDpin1.o ./Generated_Code/LEDpin2.o ./Generated_Code/LEDpin3.o ./Generated_Code/MSD1.o ./Generated_Code/PE_LDD.o ./Generated_Code/TI1.o ./Generated_Code/TU1.o ./Generated_Code/TimerIntLdd1.o ./Generated_Code/TmDt1.o ./Generated_Code/USB0.o ./Generated_Code/USB1.o ./Generated_Code/UTIL1.o ./Generated_Code/Vectors.o ./Generated_Code/WAIT1.o ./Generated_Code/croutine.o ./Generated_Code/event_groups.o ./Generated_Code/ff.o ./Generated_Code/heap_1.o ./Generated_Code/heap_2.o ./Generated_Code/heap_3.o ./Generated_Code/heap_4.o ./Generated_Code/host_ch9.o ./Generated_Code/host_close.o ./Generated_Code/host_cnl.o ./Generated_Code/host_common.o ./Generated_Code/host_dev_list.o ./Generated_Code/host_driver.o ./Generated_Code/host_main.o ./Generated_Code/host_rcv.o ./Generated_Code/host_shut.o ./Generated_Code/host_snd.o ./Generated_Code/khci_kinetis.o ./Generated_Code/list.o ./Generated_Code/mem_util.o ./Generated_Code/poll.o ./Generated_Code/port.o ./Generated_Code/queue.o ./Generated_Code/tasks.o ./Generated_Code/timers.o ./Generated_Code/usb_classes.o ./Generated_Code/usb_host_hub.o ./Generated_Code/usb_host_hub_sm.o ./Generated_Code/usb_host_msd_bo.o ./Generated_Code/usb_host_msd_queue.o ./Generated_Code/usb_host_msd_ufi.o ./Generated_Code/usbevent.o ./Generated_Code/usbmsgq.o ./Generated_Code/usbsem.o
      /opt/gcc-arm-none-eabi-4_8-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/bin/ld: rtos.elf section `.bss’ will not fit in region `m_data’
      /opt/gcc-arm-none-eabi-4_8-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/bin/ld: region `m_data’ overflowed by 1076 bytes
      /opt/gcc-arm-none-eabi-4_8-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv6-m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r’:
      sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk’
      collect2: error: ld returned 1 exit status
      make: *** [rtos.elf] Error 1

      21:54:28 Build Finished (took 9s.563ms)

      so last time you have suggested this is caused by too many global variables but I think that is because I have to change “index” to “index1″ in Generated_Code/usbmsgq.c because if I dont change that I get this error

      Building file: ../Generated_Code/usbmsgq.c
      Invoking: Cross ARM C Compiler
      arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -I”/home/dev/.eclipse/org.eclipse.platform_4.3.2_1473617060_linux_gtk_x86/ProcessorExpert/lib/Kinetis/pdd/inc” -I”/home/dev/.eclipse/org.eclipse.platform_4.3.2_1473617060_linux_gtk_x86/ProcessorExpert/lib/Kinetis/iofiles” -I”/home/dev/abc/rtos/Sources” -I”/home/dev/abc/rtos/Generated_Code” -MMD -MP -MF”Generated_Code/usbmsgq.d” -MT”Generated_Code/usbmsgq.o” -c -o “Generated_Code/usbmsgq.o” “../Generated_Code/usbmsgq.c”
      ../Generated_Code/usbmsgq.c:38:16: error: ‘index’ redeclared as different kind of symbol
      static uint_32 index; /* << EST made it static */
      ^
      make: *** [Generated_Code/usbmsgq.o] Error 1

      so what is way out of this

      Like

      • Oh finally sorted out what was wrong I accidentally landed up reviewing FREERtos PE component and I found that heap memory allocated is 10000 in project which is does not match with your other article so I reduced that to 8192 and hurray I have rid-out of that linker problem now final linking issue is

        Building target: rtos.elf
        Invoking: Cross ARM C++ Linker
        arm-none-eabi-g++ -mcpu=cortex-m0plus -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -T “/home/dev/abc/rtos/Project_Settings/Linker_Files/ProcessorExpert.ld” -nostartfiles -Xlinker –gc-sections -L”/home/dev/abc/rtos/Project_Settings/Linker_Files” -Wl,-Map,”rtos.map” -o “rtos.elf” ./Sources/Application.o ./Sources/Events.o ./Sources/Shell.o ./Sources/host.o ./Sources/main.o ./Sources/sa_mtb.o ./Project_Settings/Startup_Code/startup.o ./Generated_Code/AS1.o ./Generated_Code/ASerialLdd1.o ./Generated_Code/BitIoLdd1.o ./Generated_Code/BitIoLdd2.o ./Generated_Code/BitIoLdd3.o ./Generated_Code/CLS1.o ./Generated_Code/CS1.o ./Generated_Code/Cpu.o ./Generated_Code/FAT1.o ./Generated_Code/FRTOS1.o ./Generated_Code/FsMSD1.o ./Generated_Code/HF1.o ./Generated_Code/LEDB.o ./Generated_Code/LEDG.o ./Generated_Code/LEDR.o ./Generated_Code/LEDpin1.o ./Generated_Code/LEDpin2.o ./Generated_Code/LEDpin3.o ./Generated_Code/MSD1.o ./Generated_Code/PE_LDD.o ./Generated_Code/TI1.o ./Generated_Code/TU1.o ./Generated_Code/TimerIntLdd1.o ./Generated_Code/TmDt1.o ./Generated_Code/USB0.o ./Generated_Code/USB1.o ./Generated_Code/UTIL1.o ./Generated_Code/Vectors.o ./Generated_Code/WAIT1.o ./Generated_Code/croutine.o ./Generated_Code/event_groups.o ./Generated_Code/ff.o ./Generated_Code/heap_1.o ./Generated_Code/heap_2.o ./Generated_Code/heap_3.o ./Generated_Code/heap_4.o ./Generated_Code/host_ch9.o ./Generated_Code/host_close.o ./Generated_Code/host_cnl.o ./Generated_Code/host_common.o ./Generated_Code/host_dev_list.o ./Generated_Code/host_driver.o ./Generated_Code/host_main.o ./Generated_Code/host_rcv.o ./Generated_Code/host_shut.o ./Generated_Code/host_snd.o ./Generated_Code/khci_kinetis.o ./Generated_Code/list.o ./Generated_Code/mem_util.o ./Generated_Code/poll.o ./Generated_Code/port.o ./Generated_Code/queue.o ./Generated_Code/tasks.o ./Generated_Code/timers.o ./Generated_Code/usb_classes.o ./Generated_Code/usb_host_hub.o ./Generated_Code/usb_host_hub_sm.o ./Generated_Code/usb_host_msd_bo.o ./Generated_Code/usb_host_msd_queue.o ./Generated_Code/usb_host_msd_ufi.o ./Generated_Code/usbevent.o ./Generated_Code/usbmsgq.o ./Generated_Code/usbsem.o
        /opt/gcc-arm-none-eabi-4_8-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv6-m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r’:
        sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk’
        collect2: error: ld returned 1 exit status
        make: *** [rtos.elf] Error 1

        so will you please help me out on this problem I guess that things are in library file libc.a and its not generated by me
        so there is something I am missing out over here so please help me solving this final issue

        Like

      • These problems come from different runtime libraries :-(. That’s the pain switching project between toolchains like CodeWarrior and stock GNU ARM Embedded 😦
        I had similar problems when I created a bare SDK project from scratch (see https://mcuoneclipse.com/2014/06/15/tutorial-diy-kinetis-sdk-project-with-eclipse-startup/).
        I had no time yet to port this USB project to bare Eclipse, but looks I should.
        Could you try adding -specs=nosys.specs to the linker options (as outlined in above post)?

        Like

  14. hi eric
    I have used codewarrior this time to build project
    using generate code and then build projet
    then I have copied srec file to kl25z
    now I can see green LED blinking
    even on terminal I can see help menu
    but only two commands work
    help and status
    I tried diskinfo output was
    ” CMD> *** Failed or unknown command: diskinfo
    *** Type help to get a list of available commands ”
    and dir which you showed above still same
    ” *** Failed or unknown command: dir
    *** Type help to get a list of available commands ”

    note I am using windows7 machine so no hyperterminal available so I am using teraterm
    Is that the problem

    Like

  15. Pingback: Multi-Drive Support with FatFS | MCU on Eclipse

  16. Hello Erich,

    About FAT_FS lib, there are any command to create a file, write data and close the file?

    I try to substitute the VNC for KL25Z, but I need this functionalite.

    Thanks.

    Eduardo

    Like

  17. Hi Erich,

    Here you connect a USB Stick to a FRDM-K64F but I would like to access my SD Card on my FRDM with a computer. So I want my FRDM as MSD Device using the K64 USB. I didn’t found tutorial here (or maybe I searched bad)

    Like

  18. Hi Erich

    Just wondering if the project files (tutorial steps) are up to-date with the latest processor expert version.
    I would like to try your example project on a newly acquired FRDM-KL25Z board..

    Any recommendations and pitfalls to avoid ??

    Thanks,

    David

    Like

    • Hi David,
      are you using CodeWarrior or Kinetis Design Studio? The CodeWarrior project is here: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/FRDM-KL25Z/Freedom_USBHostMSD. I don’t have it ported to KDS yet, but I have the same thing for the FRDM-K20 and KDS here: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/FRDM-K20D50M/FRDM-K20_MSD_Host
      The project and tutorial steps are still the same, or at least I cannot remember anything special. The only thing I know is that some USB memory sticks cause problems. Sticks with less than 4 GB worked very well, while somehow sometimes sticks with larger capacity cause problems (not sure why).
      The board revision should not matter (I hope), the latest FRDM-KL25Z I have is the Rev E. one. Just make sure you properly power the 5V to the USB port. And that you do not consume too much current of course. Otherwise let me know and I see if I can send you a project with all the files.

      I hope this helps,
      Erich

      Like

      • Hi Erich,
        Thanks for your quick reply…I’m using IAR development tools and I’m fairly comfortable using them. I have implemented code for the ultra small KL02 processor without using Processor Expert.
        For this project, If you do have files for the IAR tools then I will appreciate you make them available otherwise could you advise on porting your source code to IAR tools or any other tool in general. I will try to read up on Processor Expert and IAR to port your project files. Any help/recommendation will be much appreciated.

        Kind regards,

        David

        Like

      • Hi David,
        we are not much using IAR, except the code size limited (free) version, because it is too expensive. Porting to IAR should not be a big problem, I try to have my sources compiler neutral as much as possible. But you need to watch out the inline assembly code (or guard it), as IAR is using a different syntax. The other thing ot watch out is to properly allocate the USB buffers to a 512 Byte boundary.
        Good luck!

        Like

      • Looking for a similar USB bootloader solution for the K70. I see the new RomBootloader 1.2.0 is available for certain processors but maybe not yet for the K70? Will it be available anytime soon. So it seems the other solution is this MSD_USB solution embedded into your application, but all of this looks like legacy stuff compared with the new Kinetis RomBootloader. What path would you suggest here? I don’t want to waste a bunch of time implementing a non-supported legacy solution when it appears the forward path is now RomBootloader. 1.2.0

        Thanks

        Like

      • Yes, the USB stack I’m using is a legacy one. Freescale (well, now NXP) moved to the USB stack inside the Kinetis SDK. I’m still using that legacy USB stack because it worked very well for me. But in your case you probably go better with the stack in the Kinetis SDK?

        Like

  19. Hi Erich,

    I tried to make a project for k22fn1. Everything compiles fine but when I run the code, when it calls USB0_Init() it call an Interrupt and stays there. (PE_ISR(Cpu_Interrupt))
    Did you notice that ever? Do you know whats happening?

    Thanks

    Like

  20. Hi Erich,

    I have copied it to KDS and it worked well. but I have a runtime error as below when running Benchmark.

    ERROR: unlink failed: (13) There is no valid FAT volume on the physical drive

    What does this mean ?

    Thank you,
    Zohan

    Like

    • Hi Zohan,
      this means something went wrong with deleting the file. Have you formatted earlier the device properly? Otherwise this is an indication that something else inside the file operation was going wrong, but hard to tell what.

      Like

  21. Hello eric sir,
    I am using mk64f freedom board. and I want to update my firmware using pen drive or say external flash drive. currently I am able to update bin file from PC to system using usb cable using “KinetisFlashTool.exe”, but now I want to update my firmware through Pendrive. I also downloaded the “USB_MSD_Bootloader.bin” file but no results found.

    Please help.

    Like

  22. Hi Erich, thanks for providing such a useful example ; )

    I want to implement this demo to mount, open, write and read data from a memory stick, but I really don´t know how to do it without using shell commands you like the ones you have created. As I´m just a newbie with FreeRTOS, I´d like some support from you on how to create my own task, to do this job.

    P.S: While debbuging I tryed to use FAT1_open, FAT1_write, etc. at USB_DEVICE_INTERFACED case inside the static void CheckStatus(void) polling function, but without any success.

    Like

    • Hi Marcio,
      are you using that example project? Because this one should work ‘as is’. As for FreeRTOS: there are plenty of example on my GitHub how to create a task already?
      I hope this helps,
      Erich

      Like

      • Thanks for your reply Erich,

        Yes, I´m using it because I want a project with Processor Expert and USB MSD host to read/write files from/to a USB memory stick. This example is perfect for me, but I need to solve this Issue: I don´t understand is why it doesn´t work the code below at USB_DEVICE_INTERFACED case in CheckStatus function (host.c):

        case USB_DEVICE_INTERFACED:
        {
        static FIL fp;
        FAT1_FRESULT fres;
        UINT bw;
        byte buffer_USB[10]; // copy buffer
        const CLS1_StdIOType *io_test = CLS1_GetStdio();
        static FAT1_FATFS fileSystemObject;

        fres = FAT1_MountFileSystem(&fileSystemObject, 0, io_test);
        if(fres==ERR_OK)
        {
        if (io_test!=NULL)
        CLS1_SendStr((unsigned char*)”File System mounted\r\n”, io_test->stdOut);
        }
        fres = FAT1_open(&fp, “WRITE.TXT”, FA_OPEN_EXISTING);
        if (fres !=FR_OK) {
        CLS1_SendStr((const unsigned char*)”\r\nOpen source file failed\r\n”, io_test->stdErr);
        }
        else
        {
        fres = FAT1_read(&fp, &buffer_USB[0], sizeof(buffer_USB), &bw);
        if (fres!=FR_OK) {
        CLS1_SendStr((const unsigned char*)”*** Failed reading file!\r\n”, io_test->stdErr);
        (void)FAT1_close(&fp);
        }
        (void)FAT1_close(&fp);
        if (FAT1_UnMountFileSystem(0, io_test)==ERR_OK) {
        if (io_test!=NULL) {
        CLS1_SendStr((unsigned char*)”File System unmounted\r\n”, io_test->stdOut);
        }
        }
        }

        break;
        }

        Like

  23. I also tryed using the standard functions of stdio.h, but soon I got stucked in a Hard Fault when I call a fopen:

    static void CheckStatus(void) {
    switch (FsMSD1_GetDeviceStatus()) {
    case USB_DEVICE_IDLE:
    break;
    case USB_DEVICE_ATTACHED:
    LEDR_Off();
    LEDG_On();
    print((unsigned char*)”Mass Storage Device Attached\r\n” );
    break;
    case USB_DEVICE_SET_INTERFACE_STARTED:
    break;
    case USB_DEVICE_INTERFACED:
    {
    FILE *fp;
    char str[] = “This is string”;

    fp = fopen( “file.txt” , “w” );
    fwrite(str , 1 , sizeof(str) , fp );

    fclose(fp);
    break;
    }

    case USB_DEVICE_DETACHED:
    LEDR_On();
    LEDG_Off();
    print((unsigned char*)”\nMass Storage Device Detached\n” );
    break;
    case USB_DEVICE_OTHER:
    break;
    default:
    print((unsigned char*)”Unknown Mass Storage Device State\n”);
    break;
    } /* switch */
    }

    Like

    • Hi Martin,
      I started working on such a project, but never was able to finish it. I used FatFS for the file system. I still have the project somewhere (for the FRDM-K64F I believe), but I faced problems with the NXP USB stack implementation.

      Like

  24. Hi Erich,

    I followed your suggestion and created a task, called USB_task, to mount, open, read and write a file to/from USB stick. The task worked fine, but I still facing some problems:

    1) I only can open a .txt file if I call this function (I need to mount the file system first), but this is not a big deal for my purposes:
    (void)FAT1_CheckCardPresence(&cardMounted, 0 /* volume */, &fileSystemObject, CLS1_GetStdio());
    2) I wasn´t able to open a txt file called “PEx_FRDM__K22.TXT”, but I can do it if I rename it, like “TEST.TXT”. So, is there some file naming limitation, as number of characters or special characters?
    3) I´d like to use this example to read a .srec file and make my own MSD Host Bootlader project, but I only can do this changing its extention from .srec to .txt. This is the lines I was testing:

    if (FAT1_open(&fp, “./STEST.srec”, FA_READ)!=FR_OK) {
    CLS1_SendStr((const unsigned char*)”*** Failed opening benchmark file!\r\n”,
    io->stdErr);
    return ERR_FAILED;
    }
    Is there some problem to open a .srec file?

    Regards,

    Marcio.

    Like

  25. Ok, I got it Erich.
    I found this two constants that I could, apparently, turn on LFN in ffconf.h:

    #define _USE_LFN 1
    #define _MAX_LFN 255

    But, when I set _USE_LFN to 1, I got this error in ff.c:
    #error Static LFN work area cannot be used at thread-safe configuration.

    So, I think something is missing to make this happen. Can you help me on that?

    Like

      • Yes, it´s your example I´m using (FRDM-K22F_USB_MSD_Host). Wich component and what should I do to set things right (enable LFN)? The link you post here ( http://elm-chan.org/fsw/ff/00index_e.html) says almost the same thing is commented in the code (ffconf.h file):

        FF_USE_LFN

        This option switches the support for long file name (LFN). When enable the LFN, Unicode support functions ffunicode.c need to be added to the project. The working buffer for LFN occupies (FF_MAX_LFN + 1) * 2 bytes and additional ((FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT enabled. When use stack for the working buffer, take care on stack overflow. When use heap memory for the working buffer, memory management functions, ff_memalloc and ff_memfree, need to be added to the project.
        Value Description
        0 Disable LFN. Path name in only 8.3 format can be used.
        1 Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
        2 Enable LFN with dynamic working buffer on the STACK.
        3 Enable LFN with dynamic working buffer on the HEAP.

        See that it asks to add unicode.c and ff_memalloc and ff_memfree functions.

        Please, it´s the only thing missing for me to go further with this project at this moment.

        Like

      • In the component, under the LFN group, turn on ‘Use LFN’ with ‘Enable, dynamic heap buffer’.
        Configure the LFN Length to your needs (255 might be to larger for you).
        And turn on LFN Unicode if you really need it.

        Like

  26. Yes, It worked!

    Thanks Erich : )

    My next step is to flash a .srec file read from the USB stick based on your serial bootloader example (https://mcuoneclipse.com/2013/04/28/serial-bootloader-for-the-freedom-board-with-processor-expert/). I think I´m not far from this goal, because I already made this project work as well at my side.

    Can I use your s19 PEx component to do that? My first idea was to read, line by line, the s19 lines and then flash them (again, line by line) to the app region.

    Do you have any suggestions, or tips for me to do this job, or at least to start it?

    Regards,

    Marcio.

    Like

    • Hi Marcio,
      yes, you could use that S19 component for that. But I would not read and flash line by line: that will be far too slow. Instead, fill up a buffer up to the flash block size and then flash the block as a whole. I do this in the latest version of my serial bootloader.

      Like

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s