nr_micro_shell是一個(gè)開源的shell工具。使用簡單,移植也容易。和它類似的有l(wèi)etter-shell和RTTHREAD的finsh shell。
下面簡單介紹下如何移植nr_micro_shell吧。
移植之前首先要搞定串口通信。
串口初始化如下,本次使用中斷加fifo緩存接收方式。
void drv_usart_gpio_init(void)
{
usart_config_t USART_InitStructure;
/* Enables clock for switch matrix.: enable */
CLOCK_EnableClock(kCLOCK_Swm);
const uint32_t DEBUG_UART_RX = (/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Enable hysteresis */
IOCON_PIO_HYS_EN |
/* Input not invert */
IOCON_PIO_INV_DI |
/* Disables Open-drain function */
IOCON_PIO_OD_DI |
/* Bypass input filter */
IOCON_PIO_SMODE_BYPASS |
/* IOCONCLKDIV0 */
IOCON_PIO_CLKDIV0);
/* PIO1 PIN16 (coords: 36) is configured as USART0, RXD. */
IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_24, DEBUG_UART_RX);
const uint32_t DEBUG_UART_TX = (/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Enable hysteresis */
IOCON_PIO_HYS_EN |
/* Input not invert */
IOCON_PIO_INV_DI |
/* Disables Open-drain function */
IOCON_PIO_OD_DI |
/* Bypass input filter */
IOCON_PIO_SMODE_BYPASS |
/* IOCONCLKDIV0 */
IOCON_PIO_CLKDIV0);
/* PIO1 PIN17 (coords: 37) is configured as USART0, TXD. */
IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_25, DEBUG_UART_TX);
/* USART0_TXD connect to P0_25 */
SWM_SetMovablePinSelect(SWM0, kSWM_USART0_TXD, kSWM_PortPin_P0_25);
/* USART0_RXD connect to P0_24 */
SWM_SetMovablePinSelect(SWM0, kSWM_USART0_RXD, kSWM_PortPin_P0_24);
/* Disable clock for switch matrix. */
CLOCK_DisableClock(kCLOCK_Swm);CLOCK_Select(kUART0_Clk_From_MainClk);
RESET_PeripheralReset(kUART0_RST_N_SHIFT_RSTn);
USART_GetDefaultConfig(&USART_InitStructure);
USART_InitStructure.baudRate_Bps = 115200;
USART_InitStructure.enableRx = 1U;
USART_InitStructure.enableTx = 1U;
USART_Init(USART0, &USART_InitStructure, CLOCK_GetMainClkFreq());
//使能UARTx RC中斷
USART_EnableInterrupts(USART0, kUSART_RxReadyInterruptEnable);
//優(yōu)先級(jí),無優(yōu)先級(jí)分組
NVIC_SetPriority(USART0_IRQn, 0);
//UARTx中斷使能
NVIC_EnableIRQ(USART0_IRQn);
}
串口發(fā)送:
int stdout_putchar (int ch)
{
while (0 == (USART_GetStatusFlags(USART0) & USART_STAT_TXRDY_MASK));
USART_WriteByte(USART0, (uint8_t)ch);
return ch;
}
int fputc(int ch,FILE *f)
{
return stdout_putchar(ch);
}
中斷fifo接收:
typedef struct fifo_buffer
{
volatile uint32_t read_i;
volatile uint32_t write_i;
uint8_t buff[128];
}fifo_buffer;
fifo_buffer shell_uart_rx=
{
.read_i = 0,
.write_i = 0,
};
void USART0_IRQHandler(void)
{
uint32_t statusFlag;
uint32_t ch;
statusFlag = USART0->STAT;
// if((statusFlag & USART_STAT_OVERRUNINT_MASK) != 0)
// {
// ch =ch;
// }
if((statusFlag & USART_STAT_RXRDY_MASK) != 0)
{
ch = USART_ReadByte(USART0);
if(((shell_uart_rx.write_i+1)&0x7f) != shell_uart_rx.read_i)
{
shell_uart_rx.buff[shell_uart_rx.write_i++] = ch & 0xff;
shell_uart_rx.write_i &= 0x7f;
}
}
USART0->STAT |= statusFlag;
}
下面就是移植nr_micro_shell代碼了。首先去nr_micro_shell倉庫下載代碼:https://gitee.com/nrush/nr_micro_shell 。
將代碼文件加入到工程中。
移植主要是在nr_micro_shell_config.h配置。配置串口字節(jié)輸出和printf格式化輸出。
/* ANSI command line buffer size. */
#define NR_ANSI_LINE_SIZE 256
/* Maximum user name length. */
#define NR_SHELL_USER_NAME_MAX_LENGTH 16
/* Maximum command name length. */
#define NR_SHELL_CMD_NAME_MAX_LENGTH 16
/* Command line buffer size. */
#define NR_SHELL_CMD_LINE_MAX_LENGTH NR_ANSI_LINE_SIZE
/* The maximum number of parameters in the command. */
#define NR_SHELL_CMD_PARAS_MAX_NUM 10
/* Command stores the most history commands (the maximum number here refers to the maximum number of commands that can be stored. When the history command line cache is full, it will automatically release the earliest command record) */
#define NR_SHELL_MAX_CMD_HISTORY_NUM 8
/* History command cache length */
#define NR_SHELL_CMD_HISTORY_BUF_LENGTH 253
/* The user's name. */
#define NR_SHELL_USER_NAME "root:"
/*
0: n
1: r
2: rn
*/
#define NR_SHELL_END_OF_LINE 1
/* Weather the terminal support all ANSI codes. */
#define NR_SHLL_FULL_ANSI 1
/* Show logo or not. */
#define NR_SHELL_SHOW_LOG
// /* Use NR_SHELL_CMD_EXPORT() or not */
#define NR_SHELL_USING_EXPORT_CMD
/* If you use RTOS, you may need to do some special processing for printf(). */
extern int stdout_putchar (int ch) ;
#define shell_printf(fmt, args...) printf(fmt, ##args);
#define ansi_show_char(x) stdout_putchar(x)
然后在main中調(diào)用初始化shell以及從串口中讀取輸入數(shù)據(jù)進(jìn)行解析。
void shell_usart_loop(void)
{
if(shell_uart_rx.read_i != shell_uart_rx.write_i)
{
shell(shell_uart_rx.buff[shell_uart_rx.read_i++]);
shell_uart_rx.read_i &= 0x7f;
}
}
編譯下載后就可以通過串口來控制了。nr_micro_shell默認(rèn)有l(wèi)s和test命令例子。