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.

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 :-)

About these ads

30 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

      • if you have a link to using multiple serial ‘ports’ in parallel with CLS I’d love to see it… didn’t find anything on that but maybe I missed it…

        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:

      http://mcuoneclipse.com/2013/02/14/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

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