从u-boot移植出来的shell命令界面
以前搞过u-boot,,有很多命令,,用超级终端操作,,比如help、tftp、erase、fatload,其实就是下面这段代码接受超级终端命令的。
因为最近打算给产品做一个shell,用超级终端输入命令,,所以从u-boot找到这段代码并移植出来了,就只有 delete_char 和 readline_into_buffer 两个函数,非常简单。 使用方法是: main() {
char buffer[16];//缓冲区长度根据命令长度可调整 while(1){
_delay_ms(100);
//其中\就是显示在超级终端的输入命令前端的,叫什么? readline_into_buffer (\
//这里为你的命令解析函数,然后调用对应的处理函数,如我的void shell(void)函数 Your_Cmd_Parse_and_Process(); } }
使用截图:
/*
**********************************************************************************
* 实现一个简单的Shell命令交互界面,命令行接收部分移植自u-boot-1.3.4
**********************************************************************************
*/
#define tab_seq (\ \#define erase_seq (\//删除一个字符
static char * delete_char(char *buffer, char *p, int *colp, int *np, int plen) {
char *s;
if (*np == 0) { return (p); }
if (*(--p) == '\\t') { /* will retype the whole line */ while (*colp > plen) {
USART_PutStr(COMMUNICATE_USART, erase_seq); (*colp)--; }
for (s=buffer; s
USART_PutStr(COMMUNICATE_USART, tab_seq+((*colp) & 07)); *colp += 8 - ((*colp) & 07); } else { ++(*colp);
USART_PutChar(COMMUNICATE_USART, *s); } } } else {
USART_PutStr(COMMUNICATE_USART, erase_seq); (*colp)--; }
(*np)--;
return (p); }
//从串口读取命令行
int readline_into_buffer (const char *const prompt, char * buffer) {
char *p = buffer; char * p_buf = p; /* buffer index */ int n = 0;
/* prompt length */ int plen = 0;
/* output column cnt */ int col; char c;
/* print prompt */ if (prompt) {
plen = strlen (prompt);
USART_PutStr(COMMUNICATE_USART, prompt); }
col = plen; for (;;) {
//从at91sam9260串口读取一个字符
while( 0 == (AT91C_BASE_US1->US_CSR & AT91C_US_RXRDY) ); c = AT91C_BASE_US1->US_RHR; /*
* Special character handling */
switch (c) {
case '\\r': /* Enter */ case '\\n':
//回车表示命令输入结束 *p = '\\0';
USART_PutStr(COMMUNICATE_USART, \ return (p - p_buf); case '\\0': /* nul */ continue;
case 0x03: /* ^C - break */ //CTRL+C表示取消命令输入 p_buf[0] = '\\0'; /* discard input */
USART_PutStr(COMMUNICATE_USART, \ return (-1);
case 0x15: /* ^U - erase line */ //CTRL+U表示擦除一行命令输入 while (col > plen) {
USART_PutStr(COMMUNICATE_USART, erase_seq); --col; }
p = p_buf; n = 0; continue;
case 0x17: /* ^W - erase word */ //CTRL+W表示删除一个词
p=delete_char(p_buf, p, &col, &n, plen); while ((n > 0) && (*p != ' ')) {
p=delete_char(p_buf, p, &col, &n, plen); } continue;
case 0x08: /* ^H - backspace */ case 0x7F: /* DEL - backspace */ //表示删除一个字符
p=delete_char(p_buf, p, &col, &n, plen); continue; default: /*
* Must be a normal character then */
if (n < 16-2) {//luodefu-命令行缓冲区大小16 if (c == '\\t') { /* expand TABs */
USART_PutStr(COMMUNICATE_USART, tab_seq+(col&07)); col += 8 - (col&07); } else {
++col; /* echo input */
USART_PutChar(COMMUNICATE_USART, c); }
*p++ = c; ++n;
} else { /* Buffer full */
USART_PutChar(COMMUNICATE_USART, '\\a'); } }//switch }//for }
//============下面是自己参照u-boot实现的命令结构体,以及处理函数============ //***************************如何使用:我的使用实例******************************** 这几天在进行shell编码和测试,参照u-boot的命令,我也实现了以下命令,功能方面相比u-boot做了简化:
h - help命令,用来输出所有支持的命令以及功能; f - find命令,用来在yaffs文件系统中查找文件夹或文件; o - open命令,用来打开目录;
g - get命令, 用来上传文件,通过串口和超级终端实现的zmodem协议,从yaffs中上传指定文件到PC中;