How do I create shell for Kinetis KL25Z freedom board?

The Kinetis KL25Z freedom board has no physical UART/RS-232 on-board, but this is not a problem anymore as you can work shell connection through the P&E OpenSDA USB CDC connection. Although the OpenSDA firmware on the board is preliminary, it works very well.

To create the shell for Kinetis KL25Z freedom board, use FSShell with RingBuffer. FSShell is file system shell with command line interface. For developing the application, refactor the FSShell component a bit: the component uses its own buffer management. Having a more universal ring buffer implementation in RingBufferUInt8, use this for the FSShell.

Figure 1. FSShell with Ringbuffer

FSShell with Ringbuffer

Add 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). Use the Tera Term to execute the application, as Eclipse Terminal view and Termite does not work well and blocks after few seconds.

Listing: FSShell Scripting

01/*
02** =================================================================

03**     Method      :  FSSH1_ReadAndParseLine (component FSShell)

04**

05**     Description :

06**         Reads characters from the default input channel and 
appends

07**         it to the buffer. Once a new line has been detected, the

08**         line will be parsed.

09**     Parameters  :

10**         NAME            - DESCRIPTION

11**       * cmdBuf          - Pointer to buffer provided by the

12**                           caller where to store the command to read

13**                           in. Characters will be appended, so make

14**                           sure string buffer is initialized with a

15**                           zero byte at the beginning.

16**         cmdBufSize      - Size of buffer

17**       * io              - Pointer to I/O channels to be used

18**         parseCallback   - callback provided by

19**                           the user application to parse user 
commands.

20**                           If not used, NULL can be passed.

21**     Returns     :

22**         ---             - Error code

23** =================================================================

24*/

25byte FSSH1_ReadAndParseLine(byte *cmdBuf, size_t cmdBufSize, 
FSSH1_ConstStdIOType *io, FSSH1_ParseCommandCallback parseCallback)

26{

27  byte res = ERR_OK;

28  size_t len;

29 

30  len = UTIL1_strlen((const char*)cmdBuf);

31  if (FSSH1_ReadLine(cmdBuf+len, cmdBufSize-len, io)) {

32    len = UTIL1_strlen((const char*)cmdBuf); /* length of buffer 
string */

33    if (len==0) { /* error case */

34      return ERR_FAILED;

35    } else if (len==1 && (cmdBuf[0]=='\r' || cmdBuf[0]=='\r')) { /* 
eat preceding newline characters */

36      cmdBuf[0] = '\0';

37    }

38    if (len>=cmdBufSize-1) {           /* buffer overflow? Parse what 
we have, will be likely return an error */

39      res = FSSH1_ParseCommand(cmdBuf, io, parseCallback);

40      cmdBuf[0] = '\0'; /* start again */

41      res = ERR_OVERFLOW;

42    } else if (cmdBuf[len-1]=='\n' || cmdBuf[len-1]=='\r') { /* line 
end: parse command */

43      cmdBuf[len-1] = '\0';            /* remove line end character 
for parser */

44      res = FSSH1_ParseCommand(cmdBuf, io, parseCallback);

45      cmdBuf[0] = '\0';                /* start again */

46    } else {

47      /* continue to append to buffer */

48    }

49  }

50  return res;

51}

Then implement a task providing the shell interface, as the following listing shows:

Listing: Implementing Task

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

03 

04  (void)pvParameters;

05  cmd_buf[0] = '\0';

06  FSSH1_Init();

07  (void)FSSH1_ParseCommand((const unsigned char*)FSSH1_CMD_HELP, 
FSSH1_GetStdio(), ParseCommand);

08  for(;;) {

09    (void)FSSH1_ReadAndParseLine(cmd_buf, sizeof(cmd_buf), 
FSSH1_GetStdio(), ParseCommand /* local cmd parser */);

10    FRTOS1_vTaskDelay(50/portTICK_RATE_MS);

11    LED2_Neg();

12  };

13}

14 

15void SHELL_Init(void) {

16  if (FRTOS1_xTaskCreate(ShellTask, (signed portCHAR *)"Shell", 
configMINIMAL_STACK_SIZE+350, NULL, tskIDLE_PRIORITY+1, NULL) != 
pdPASS) {

17    for(;;){} /* error */

18  }

19}

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

Figure 2. Freedom Board Shell

Freedom Board Shell

Date and Time commands are provided automatically through the FSShell:

Figure 3. FSShell with TimeDate

FSShell with TimeDate

Use status command to view the Date/Time and other information:

Figure 4. System Status

System Status

It shows all RTOS tasks with their status, along with performance information about each task.