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.
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.
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:
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:
Date and Time commands are provided automatically through the FSShell:
Use status command to view the Date/Time and other information:
It shows all RTOS tasks with their status, along with performance information about each task.