A Shell for the Freedom KL25Z Board

I’m a big fan of physical UART/RS-232 ports on boards. So I was somewhat disappointed not to see a serial 9pin connector on the Freedom KL25Z board. But it is perfectly understood that for this price costs are critical, and a serial header or connector is pushing the budget for that board very likely out of the water. Still, I want serial connectivity for my applications.

Freedom Board with RGB LED

Freedom Board with RGB LED

When I ported FreeRTOS to the Freedom board, I noticed that the OpenSDA debug interface enumerated as well a USB CDC port. After I had explored the P&E OSBMD/OSJTAG virtual serial port, I wondered if this works as well for my Freedom board. And yes, it does!

OpenSDA CDC Serial Port in Task Manager

OpenSDA CDC Serial Port in Task Manager

So I used that opportunity as well to improve the FSShell component I’m using in other projects. The result is an application with FreeRTOS, a realtime clock, changing RGB LED and a Shell using the OpenSDA USB CDC for communication with the host.

The Application

The application is implemented with Processor Expert in Eclipse based CodeWarrior for MCU using the ARM gcc compiler:

Freedom Shell Application with Processor Expert Components

Freedom Shell Application with Processor Expert Components

Compared to the application in this post, it ads:

  1. GenericTimeDate: A generic real-time clock implementation, see There is a Time and Date for both Worlds.
  2. FSShell: A file system shell with command line interface. See FatFs with Kinetis.
  3. Serial_LDD: Logical Device Driver for a serial/UART connection.

FSShell with RingBuffer

Developing the Application for the Freedom board, I used that opportunity to refactor the FSShell component a bit: the component was using its own buffer management. Having a more universal ring buffer implementation in RingBufferUInt8, I decided to use for the FSShell as too:

FSShell with Ringbuffer

FSShell with Ringbuffer

Additionally I have added a new routine ReadAndParseLine() an ‘append’ buffer management. This is useful if the terminal is sending character by character (and not as a full string). It turned out that this was a good idea if using Tera Term.

/*
** ===================================================================
**     Method      :  FSSH1_ReadAndParseLine (component FSShell)
**
**     Description :
**         Reads characters from the default input channel and appends
**         it to the buffer. Once a new line has been detected, the
**         line will be parsed.
**     Parameters  :
**         NAME            - DESCRIPTION
**       * cmdBuf          - Pointer to buffer provided by the
**                           caller where to store the command to read
**                           in. Characters will be appended, so make
**                           sure string buffer is initialized with a
**                           zero byte at the beginning.
**         cmdBufSize      - Size of buffer
**       * io              - Pointer to I/O channels to be used
**         parseCallback   - callback provided by
**                           the user application to parse user commands.
**                           If not used, NULL can be passed.
**     Returns     :
**         ---             - Error code
** ===================================================================
*/
byte FSSH1_ReadAndParseLine(byte *cmdBuf, size_t cmdBufSize, FSSH1_ConstStdIOType *io, FSSH1_ParseCommandCallback parseCallback)
{
  byte res = ERR_OK;
  size_t len;

  len = UTIL1_strlen((const char*)cmdBuf);
  if (FSSH1_ReadLine(cmdBuf+len, cmdBufSize-len, io)) {
    len = UTIL1_strlen((const char*)cmdBuf); /* length of buffer string */
    if (len==0) { /* error case */
      return ERR_FAILED;
    } else if (len==1 && (cmdBuf[0]=='\r' || cmdBuf[0]=='\r')) { /* eat preceding newline characters */
      cmdBuf[0] = '\0';
    }
    if (len>=cmdBufSize-1) {           /* buffer overflow? Parse what we have, will be likely return an error */
      res = FSSH1_ParseCommand(cmdBuf, io, parseCallback);
      cmdBuf[0] = '\0'; /* start again */
      res = ERR_OVERFLOW;
    } else if (cmdBuf[len-1]=='\n' || cmdBuf[len-1]=='\r') { /* line end: parse command */
      cmdBuf[len-1] = '\0';            /* remove line end character for parser */
      res = FSSH1_ParseCommand(cmdBuf, io, parseCallback);
      cmdBuf[0] = '\0';                /* start again */
    } else {
      /* continue to append to buffer */
    }
  }
  return res;
}

Shell Task

The implementation of a task providing the shell interface was really straight forward:

static portTASK_FUNCTION(ShellTask, pvParameters) {
unsigned char cmd_buf[32];

  (void)pvParameters;
  cmd_buf[0] = '\0';
  FSSH1_Init();
  (void)FSSH1_ParseCommand((const unsigned char*)FSSH1_CMD_HELP, FSSH1_GetStdio(), ParseCommand);
  for(;;) {
    (void)FSSH1_ReadAndParseLine(cmd_buf, sizeof(cmd_buf), FSSH1_GetStdio(), ParseCommand /* local cmd parser */);
    FRTOS1_vTaskDelay(50/portTICK_RATE_MS);
    LED2_Neg();
  };
}

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

Tera Term: USB CDC with OpenSDA

Trying my application did work right away: both the Eclipse Terminal view and Termite had problems: the were blocking after few seconds :-(. Not sure if this a generic problem of the terminal implementation or the OpenSDA USB CDC implementation. Luckily it worked perfectly with Tera Term :-). So that’s why I’m showing Tera Term screenshots below.

After reset, the board shows the following menu. The same menu is shown if I type in ‘help‘ as command:

Freedom Board Shell

Freedom Board Shell

Date and Time commands are provided automatically through the FSShell:

FSShell with TimeDate

FSShell with TimeDate

Date/Time and other information is shown with typing the ‘status‘ command:

System Status

System Status

This shows me as well all RTOS tasks with their status, along with performance information about each task.

The Project

The project and sources can be downloaded from this link.

Update: there is a bare metal project for Kinetis Design Studio available here: “Tutorial: Bare-Metal Shell for Kinetis

Summary

The Freedom has no physical UART/RS-232 on-board, but this is not a problem for me any more as I have a working shell connection through the P&E OpenSDA USB CDC connection. Although the OpenSDA firmware on the board is preliminary, it works very well. And I was able to successfully extend my Freedom board application with a real-time clock and a shell.

Happy Shelling 🙂

48 thoughts on “A Shell for the Freedom KL25Z Board

  1. Pingback: Sports Timing System in a Lunch Box | MCU on Eclipse

  2. Pingback: Escaping the Heat Wave | MCU on Eclipse

  3. Pingback: Tutorial: Enlightning the Freedom KL25Z Board | MCU on Eclipse

  4. Pingback: Tutorial: USB CDC with the KL25Z Freedom Board | MCU on Eclipse

  5. Pingback: Tutorial: printf() and “Hello World!” with the Freedom KL25Z Board | MCU on Eclipse

  6. Pingback: USB CDC and SCI: Side-by-Side with the Freedom Board | MCU on Eclipse

  7. Pingback: Arduino Data-Logger Shield with the FRDM-KL25Z Board | MCU on Eclipse

  8. Pingback: FRDM-KL25Z with the Arduino Motor Shield | MCU on Eclipse

  9. Pingback: CSI Crime Scene Investigation with I2CSpy and Freedom Board | MCU on Eclipse

  10. Pingback: PWM and Shell for a LED | MCU on Eclipse

  11. Pingback: Freedom Track Robot with IEEE802.15.4/SMAC | MCU on Eclipse

    • The ‘FSShell’ is the old/legacy one: it started as a ‘File System Shell’ for FatFS. As such, it incorporates functions like ‘dir’ or ‘print file’. Later functions for FreeRTOS like showing the tasks/etc had been added. So it was more than just the shell core, it had functions of other components in it. Which was not good from an architecture point of view. And it created issues with recursive includes.
      So I re-factored that component as ‘Shell’, and with only the command line shell core. And the command line features of FreeRTOS has been moved to the FreeRTOS component, and the command line shell functions for the FatFS to the FatFS component, and so on. That way every component can offer a command line interface, and the Shell component just provides the services (like parsing, using command callback tables) and so on.
      I should have done it that way in the first place, but sometimes I need to implement something the wrong way to find a better way 😉

      Like

      • so for new projects we should probably use the new shell (CLS)? …the one thing about the old one which stuck out is it appeared (though I could be wrong) that you could simultaneously have a USB_CDC virtual serial port and a real UART serial port, which could be very handy sometimes.

        Like

        • Yes, you should use the Shell (CLS) which is much better. And no issue with using it in paralle with USB CDC, SCI. I’m right now using it with Bluetooth, SCI and USB CDC plus a nRF24L01+ connection. You only have to specify the default connection, but you can add any other connection to it (not in the component itself, but just with another I/O structure). I believe I have posted an example of this, otherwise I can post something.

          Like

  12. Pingback: Tutorial: Using a Terminal Input and Output; *without* printf() and scanf() | MCU on Eclipse

  13. Pingback: RNet: A Simple Open Source Radio Network Stack | MCU on Eclipse

  14. Pingback: First Steps with the Freescale TWR-K64F120M | MCU on Eclipse

  15. Pingback: Serial Terminal View with Eclipse Kepler | MCU on Eclipse

  16. Erich,

    Initially when I try your SSHell component it did not work.
    Finally after a bit of investigation as to why it was not working on my computer,
    I found that the PEupd’s beans from your GitHub were not importing the RingBufferUInt8
    instead a RingBuffer. SShell was not seeing the RingBuffer for some reason.

    So after I downloaded the RingBufferUInt8 from here: http://www.steinerberg.com/EmbeddedComponents/RingBufferUInt8/home.htm

    I was then able to get the SShell working.

    Thank you for the great work you have done.

    Like

  17. Pingback: XFormat, a Lightweight printf() and sprintf() Alternative | MCU on Eclipse

  18. Hi Erich,

    Do you have any tutorial explaining how to use the shell component in more details?
    Unfortunately, I could not understand which are the types involved in operations such as CLS1_StdIO_OutErr_FctType, and how the boots are made!

    Thanks,

    Matheus

    Like

    • Hi Matheus,
      I was hoping that the sources are self-explanatory ;-). I don’t have a dedicated turorial about what you are asking for. The CLS1_StdIO types are structs with function pointers. And the function pointers are pointing to functions to read/write characters.
      You might this post useful as it describes how to combine the serial shell with a bluetooth shell:

      Bluetooth with the Freedom Board

      I hope this helps,
      Erich

      Like

      • Seeing the sources, I could understand! Thanks!
        But, I’m having a problem in running the example from the help of the component. I am using tera term and putty and none of then show the shell! This is not a problem of heap or stack, because with halt I see that most part of execution goes to

        PE_ISR(Cpu_Interrupt)
        {
        /* This code can be changed using the CPU component property “Build Options / Unhandled int code” */
        PE_DEBUGHALT();
        }

        Any advice?

        Like

  19. Pingback: Tutorial: Playing MP3 Files with VS1053B and FRDM Board | MCU on Eclipse

  20. Pingback: Tutorial: Web Server with the ESP8266 WiFi Module | MCU on Eclipse

  21. Hi Eric,

    I really want to thank you for all the info and examples that you post, I’ve learned more reading your blog than in some of my classes at the University.

    I have a question about the stack size needed by a task on freeRTOS and the info gived by the rtos status on the shell component (CLS).

    In a proyect I’ve configured the RTOS(V8.0.1) like this:

    Total Heap Size: 10500 [D] (I think this is in bytes)
    Minimal Stack size: 100 [D] (I understand this in stack units, as I’m using the KL25Z this is x4 = 400 bytes)

    I’m running 3 tasks: mainTask, shellTask, IDLE. All using the minimal stack size.

    But the info gived by the rtos status on shell shows:

    TASK LIST:
    Name Status Prio Stack TCB#
    ————————————————————–
    Shell R 1 10 3
    Main R 1 44 1
    IDLE R 0 90 2
    ————————————————————–
    RTOS ticks : 1000 Hz, 1 ms
    Free heap : 8620 bytes

    If I sum the stack used by the 3 tasks and the free heap it makes 8764 bytes, a lot minor that the 10500 defined in Total Heap Size. So, I don’t understand why.

    So my questions are:

    1. In what units is showed the task stack in the rtos status with the shell?
    2. In what units are the stack size parameter that we put in the task create function?, Are the same units of the config RTOS parameter: Minimal Stack size?
    3. How can we guess the stack size needed by a task to ensure there wont be overflow? (May be using the linker map info?)

    Thank you so much!

    Like

    • Hi Camilo,
      many thanks for your nice words, appreciated :-).

      To answer your questions:
      >>1. In what units is showed the task stack in the rtos status with the shell?
      It is in ‘stack units’, to be more precise of type portSTACK_TYPE which is 32bit for ARM. Or ‘stack addressable aligned units’.

      >>2. In what units are the stack size parameter that we put in the task create function?, Are the same units of the config RTOS parameter: Minimal Stack size?
      Same as above, it is in portSTACK_TYPE or stack units. 32bit (4 bytes) for ARM.

      >>3. How can we guess the stack size needed by a task to ensure there wont be overflow? (May be using the linker map info?)
      There is a stack overflow check in FreeRTOS which is usually enabled by default. See http://www.freertos.org/Stacks-and-stack-overflow-checking.html
      I recommend that you allocate enough stack in the task creation call, then monitor usage of stack with the shell, and reduce if feasible. Just one thing to keep in mind: the shell reports ‘number of free stack units’, so if this number goes low (say below 50), you probably better allocate more stack space for the task. Keep in mind that interrupts run on top of each task stack.

      And yes: heap size is in bytes, default stack size is in ‘stack units’ (32bit for ARM).

      I hope this helps,
      Erich

      Like

      • Thank you for the info, it really helps.

        I understand better now, but I still don’t understand why total heap + the stack of the tasks is lower than the heap size configured in the RTOS. I mean:

        (100 stack units by task)x(4 bytes by stack unit)x(3 tasks) + (8620 bytes of free heap reported by shell) = 9820 bytes.

        But the heap size configured on the RTOS is 10500 bytes.

        Is the RTOS consuming 680 bytes of its own heap?

        And another small question: The size code info given by the compiler says that the RAM consuming is about 11KB, and the KL25Z has 16KB. But if I put more than 10500 bytes of heap for the RTOS, for example 13000 bytes, the compiler shows the error: “region m_data overflowed by 1576 bytes”. Do you have any idea why?

        Like

  22. Hi Erich!

    Could you post the total size of the code in RAM and in FLASH that this shell is consuming with and without the RTOS?

    I have generated my own Shell code (without compatibility with any RTOS) and it is consuming:
    text data bss dec
    0x1664 0x7c 0x8cc 8108

    Im using an MWK01Z128 Kinteis W series MCU

    Many thanks!!!!

    And thanks for having this blog and sharing all that info, its a huge huge huge help for the freescale kinetis users!

    Like

    • Hi Luis,
      many thanks for your appreciation of this blog 🙂
      Here is what I have for my shell implementation, with using the RTOS:
      text data bss dec hex filename
      2892 4 4 2900 b54 Generated_Code\CLS1.o

      Like

  23. Do you have an example of Shell component without FreeRTOS? Really I don’t understand how use it. I have seen all examples but are incomplete, with errors etc. I want use these component but I can’t. Thanks

    Like

  24. Pingback: Tutorial: Bare-Metal Shell for Kinetis | MCU on Eclipse

  25. Hi Erich!
    I’m trying to use the Shell component of processor expert with a k40 microcontroller and some components don’t support this.
    Do you have any suggestion about how to adapt this component or how to create a new component compatible with this microcontrollers?

    Thanks!
    Thiago

    Like

      • Sorry about my English,
        KDS says that the mk40dn512vlq microcontroller does not supports AsynchroSerial component and any _LDD devices.

        Like

        • Have you created the project for the MK40DN512 only with Processor Expert enabled (but no SDK selected)? Then you can use LDD and other components. But if you create the project with an SDK enabled, the SDK does not support this.

          Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.