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

13 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

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 )

Connecting to %s