Add KBOOT.
This commit is contained in:
364
src/blsh/blsh.c
Normal file
364
src/blsh/blsh.c
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "blsh.h"
|
||||
#include "bllibc.h"
|
||||
#include "host_hardware.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief input buffer size */
|
||||
#define k_cmdBufferSize 256
|
||||
|
||||
/*! @brief input History depth */
|
||||
#define k_cmdHistoryDepth 16
|
||||
|
||||
/*! @brief max input command args */
|
||||
#define k_cmdMaxArgs 16
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief help command definition */
|
||||
static void help_func(uint8_t argc, uint8_t **argv);
|
||||
static blsh_cmd_t help_cmd = { "help", "Display commands list and usage", "help", help_func, 0, 0 };
|
||||
static blsh_cmd_t *root_cmd = &help_cmd;
|
||||
|
||||
/*! @brief exit command definition */
|
||||
static void exit_func(uint8_t argc, uint8_t **argv);
|
||||
static blsh_cmd_t exit_cmd = { "exit", "Exit the blsh", "exit", exit_func, 0, 0 };
|
||||
|
||||
/*! @brief blsh input buffer and index
|
||||
*/
|
||||
static uint8_t s_inputBuffer[k_cmdHistoryDepth][k_cmdBufferSize + 1] = { 0 };
|
||||
static uint32_t s_curCmdIndex = 0;
|
||||
static uint32_t s_curBufIndex = 0;
|
||||
|
||||
/*! @brief blsh exit flag */
|
||||
static uint8_t s_blsh_exit = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
static void blsh_handle(uint8_t c);
|
||||
static void line_execute(uint8_t *line);
|
||||
static uint32_t command_parse(blsh_cmd_t **_cmd, uint8_t **_str);
|
||||
static void command_execute(blsh_cmd_t *cmd, uint8_t *str);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void blsh_init(void)
|
||||
{
|
||||
command_add(&exit_cmd);
|
||||
|
||||
blsh_printf("\r\n **************************************** ");
|
||||
blsh_printf("\r\n *** Welcome to blsh *** ");
|
||||
blsh_printf("\r\n **************************************** ");
|
||||
blsh_printf("\r\n > "); /* Start a new line */
|
||||
}
|
||||
|
||||
void blsh_run(void)
|
||||
{
|
||||
uint8_t c;
|
||||
if (blsh_getchar(&c))
|
||||
{
|
||||
blsh_handle(c);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t blsh_exit(void)
|
||||
{
|
||||
return s_blsh_exit;
|
||||
}
|
||||
|
||||
void command_add(blsh_cmd_t *cmd)
|
||||
{
|
||||
blsh_cmd_t *index;
|
||||
|
||||
if (!root_cmd)
|
||||
{
|
||||
root_cmd = cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = root_cmd;
|
||||
while (index->next)
|
||||
index = index->next;
|
||||
index->next = cmd;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief handle input char
|
||||
*
|
||||
* @param c input char.
|
||||
*/
|
||||
static void blsh_handle(uint8_t c)
|
||||
{
|
||||
uint8_t *line = s_inputBuffer[s_curBufIndex];
|
||||
|
||||
if ((c == '\n') || (c == '\r')) /* Confirm the command */
|
||||
{
|
||||
/* Echo */
|
||||
blsh_putchar(c);
|
||||
|
||||
while (*line && (*line == ' '))
|
||||
line++;
|
||||
if (*line)
|
||||
{
|
||||
microseconds_init();
|
||||
line_execute(line);
|
||||
microseconds_shutdown();
|
||||
|
||||
s_curBufIndex = (s_curBufIndex + 1) % k_cmdHistoryDepth;
|
||||
s_curCmdIndex = 0;
|
||||
s_inputBuffer[s_curBufIndex][0] = 0;
|
||||
}
|
||||
/* Start a new line */
|
||||
if (!s_blsh_exit)
|
||||
blsh_printf("\r\n > ");
|
||||
}
|
||||
else if ((c == 0x08) || (c == 0x7f)) /* Backspace and delete */
|
||||
{
|
||||
if (s_curCmdIndex > 0)
|
||||
{
|
||||
line[--s_curCmdIndex] = 0;
|
||||
blsh_printf("\b \b");
|
||||
}
|
||||
}
|
||||
else if (c == 0x1b) /* Command turning */
|
||||
{
|
||||
uint8_t key_value[3] = { 0 };
|
||||
key_value[0] = c;
|
||||
key_value[1] = wait_uart_char_blocking();
|
||||
key_value[2] = wait_uart_char_blocking();
|
||||
|
||||
if (key_value[2] == 0x41) /* Up */
|
||||
{
|
||||
uint8_t prevLine = (s_curBufIndex + k_cmdHistoryDepth - 1) % k_cmdHistoryDepth;
|
||||
|
||||
if (s_inputBuffer[prevLine][0])
|
||||
{
|
||||
while (s_curCmdIndex-- > 0)
|
||||
blsh_printf("\b \b");
|
||||
line = s_inputBuffer[prevLine];
|
||||
s_curCmdIndex = strlen((char *)line);
|
||||
s_curBufIndex = prevLine;
|
||||
blsh_printf("\r > %s", line);
|
||||
}
|
||||
}
|
||||
else if (key_value[2] == 0x42) /* Down */
|
||||
{
|
||||
uint8_t nextLine = (s_curBufIndex + 1) % k_cmdHistoryDepth;
|
||||
|
||||
if (s_inputBuffer[nextLine][0])
|
||||
{
|
||||
while (s_curCmdIndex-- > 0)
|
||||
blsh_printf("\b \b");
|
||||
line = s_inputBuffer[nextLine];
|
||||
s_curCmdIndex = strlen((char *)line);
|
||||
s_curBufIndex = nextLine;
|
||||
blsh_printf("\r > %s", line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
blsh_printf("%s", key_value);
|
||||
}
|
||||
}
|
||||
else /* Input command */
|
||||
{
|
||||
if (s_curCmdIndex < k_cmdBufferSize)
|
||||
{
|
||||
/* Echo */
|
||||
blsh_putchar(c);
|
||||
line[s_curCmdIndex++] = c;
|
||||
line[s_curCmdIndex] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief process input line
|
||||
*
|
||||
* @param line input line.
|
||||
*/
|
||||
static void line_execute(uint8_t *line)
|
||||
{
|
||||
uint8_t *str = line;
|
||||
blsh_cmd_t *cmd = root_cmd;
|
||||
uint32_t ret = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
ret = command_parse(&cmd, &str);
|
||||
|
||||
if (ret == k_match)
|
||||
{
|
||||
if (cmd)
|
||||
{
|
||||
command_execute(cmd, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ret == k_ambig)
|
||||
{
|
||||
blsh_printf("\r\n Error: Ambiguity command: %s", str);
|
||||
break;
|
||||
}
|
||||
else if (ret == k_unmatch)
|
||||
{
|
||||
blsh_printf("\r\n Error: Invalid command: %s", str);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief parse the command line
|
||||
*
|
||||
* @param _cmd command root.
|
||||
* @param _str input command.
|
||||
*/
|
||||
static uint32_t command_parse(blsh_cmd_t **_cmd, uint8_t **_str)
|
||||
{
|
||||
uint8_t *str = *_str;
|
||||
/* uint32_t matched_len = 0; */
|
||||
blsh_cmd_t *cmd;
|
||||
/* blsh_cmd_t *matched_cmd = 0; */
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* Eliminate start blanks */
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
if (!*str)
|
||||
{
|
||||
*_str = str;
|
||||
return k_nullMatch;
|
||||
}
|
||||
|
||||
for (cmd = *_cmd; cmd; cmd = cmd->next)
|
||||
{
|
||||
ret = bl_strstart(cmd->name, str);
|
||||
|
||||
if (ret == k_fullMatch)
|
||||
{
|
||||
while (*str && (*str != ' '))
|
||||
str++;
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
*_str = str;
|
||||
*_cmd = cmd;
|
||||
return k_match;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return k_unmatch;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief execute the command
|
||||
*
|
||||
* @param cmd input command.
|
||||
* @param str input string.
|
||||
*/
|
||||
static void command_execute(blsh_cmd_t *cmd, uint8_t *str)
|
||||
{
|
||||
uint8_t temp[k_cmdBufferSize] = { 0 };
|
||||
uint8_t *string = temp;
|
||||
uint8_t *argv[k_cmdMaxArgs];
|
||||
uint8_t argc = 0;
|
||||
|
||||
memcpy(temp, str, strlen((char *)str));
|
||||
argv[argc++] = cmd->name;
|
||||
while (*string && (argc < k_cmdMaxArgs))
|
||||
{
|
||||
while (*string == ' ')
|
||||
string++;
|
||||
if (*string == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
argv[argc++] = string;
|
||||
while (*string && (*string != ' '))
|
||||
string++;
|
||||
if (!*string)
|
||||
{
|
||||
break;
|
||||
}
|
||||
*string++ = 0;
|
||||
}
|
||||
|
||||
if (cmd->function)
|
||||
{
|
||||
cmd->function(argc, argv);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief process help command
|
||||
*
|
||||
* @param argc the count of arguments inputed to shell.
|
||||
* @param argv the value of arguments inputed to shell.
|
||||
*/
|
||||
static void help_func(uint8_t argc, uint8_t **argv)
|
||||
{
|
||||
blsh_cmd_t *cmd = 0;
|
||||
|
||||
blsh_printf("\r\n Command List: \r\n ");
|
||||
for (cmd = root_cmd; cmd; cmd = cmd->next)
|
||||
{
|
||||
blsh_printf("%s\r\n \t\t\t %s\r\n ", cmd->usage, cmd->help);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief process exit command
|
||||
*
|
||||
* @param argc the count of arguments inputed to shell.
|
||||
* @param argv the value of arguments inputed to shell.
|
||||
*/
|
||||
static void exit_func(uint8_t argc, uint8_t **argv)
|
||||
{
|
||||
s_blsh_exit = 1;
|
||||
blsh_printf("\r\n Bye \r\n");
|
||||
}
|
||||
Reference in New Issue
Block a user