1:以s5pv210芯片的开发板为例。标准输入输出设置为串口的输入输出,通过开发板串口连接PC主机,使用SecureCRT软件,来构建一个类似uboot中的shell命令行界面;
2:shell命令行界面的实质就是提供人机交互,类似GUI、xwindows等;
shell命令行界面的实现原理:
利用一个while死循环构建一个命令行终端,这个命令行终端可以读取、解析命令、并介串口来输出,把结果在SecureCRT中打印出来;
需要如下几个函数:start.S 用来做基本的初始化:如关开门狗、电源置锁、初始化时钟、初始化DDR等;
接下来初始化串口,构建一个以串口输入输出的标准化函数;
下面这段代码初始化了串口,并且构建了以串口为输入、输出的函数putc、getc
#define GPA1CON 0xE0200020 #define ULCON2 0xE2900800 #define UBRDIV2 0xE2900828 #define UDIVSLOT2 0xE290082C #define UCON2 0xE2900804 #define UFCON2 0xE2900808 #define UMCON2 0xE290080C #define UTXH2 0xE2900820 #define UTRSTAT2 0xE2900810 #define URXH2 0xE2900824 #define rGPA1CON (*(unsigned int*)0xE0200020) #define rULCON2 (*(unsigned int*)0xE2900800) #define rUBRDIV2 (*(unsigned int*)0xE2900828) #define rUDIVSLOT2 (*(unsigned int*)0xE290082C) #define rUCON2 (*(unsigned int*)0xE2900804) #define rUFCON2 (*(unsigned int*)0xE2900808) #define rUMCON2 (*(unsigned int*)0xE290080C) #define rUTXH2 (*(unsigned int*)0xE2900820) #define rUTRSTAT2 (*(unsigned int*)0xE2900810) #define rURXH2 (*(unsigned int*)0xE2900824) void uart_init(void) { //设置线接口为Rx Tx 模式 GPA1CON, R/W, Address = 0xE020_0020 rGPA1CON &= ~(0xFF); rGPA1CON |= 0x22; //设置ULCON 8字节 无奇偶校验 终止位为1位 无起始 ULCON2, R/W, Address = 0xE290_0800 rULCON2 = 0x3; //设置UCON UCON2, R/W, Address = 0xE290_0804, R/W, Address = 0xE290_0804 rUCON2 = 0x5; //设置UFCON 无FIFO UFCON2, R/W, Address = 0xE290_0808 rUFCON2 = 0x0; //设置UMCON 无流控 UMCON2, R/W, Address = 0xE290_080C rUMCON2 = 0x0; //设置波特率 UBRDIV2, R/W, Address = 0xE290_0828 UDIVSLOT2, R/W, Address = 0xE290_082C rUBRDIV2 = 0x23; rUDIVSLOT2 = 0x0808; } #if 0 #define GPA0CON 0xE0200000 #define UCON0 0xE2900004 #define ULCON0 0xE2900000 #define UMCON0 0xE290000C #define UFCON0 0xE2900008 #define UBRDIV0 0xE2900028 #define UDIVSLOT0 0xE290002C #define UTRSTAT0 0xE2900010 #define UTXH0 0xE2900020 #define URXH0 0xE2900024 #define rGPA0CON (*(volatile unsigned int *)GPA0CON) #define rUCON0 (*(volatile unsigned int *)UCON0) #define rULCON0 (*(volatile unsigned int *)ULCON0) #define rUMCON0 (*(volatile unsigned int *)UMCON0) #define rUFCON0 (*(volatile unsigned int *)UFCON0) #define rUBRDIV0 (*(volatile unsigned int *)UBRDIV0) #define rUDIVSLOT0 (*(volatile unsigned int *)UDIVSLOT0) #define rUTRSTAT0 (*(volatile unsigned int *)UTRSTAT0) #define rUTXH0 (*(volatile unsigned int *)UTXH0) #define rURXH0 (*(volatile unsigned int *)URXH0) // 串口初始化程序 void uart_init(void) { // 初始化Tx Rx对应的GPIO引脚 rGPA0CON &= ~(0xff<<0); // 把寄存器的bit0~7全部清零 rGPA0CON |= 0x00000022; // 0b0010, Rx Tx // 几个关键寄存器的设置 rULCON0 = 0x3; rUCON0 = 0x5; rUMCON0 = 0; rUFCON0 = 0; // 波特率设置 DIV_VAL = (PCLK / (bps x 16))-1 // PCLK_PSYS用66MHz算 余数0.8 //rUBRDIV0 = 34; //rUDIVSLOT0 = 0xdfdd; // PCLK_PSYS用66.7MHz算 余数0.18 // DIV_VAL = (66700000/(115200*16)-1) = 35.18 rUBRDIV0 = 35; // (rUDIVSLOT中的1的个数)/16=上一步计算的余数=0.18 // (rUDIVSLOT中的1的个数 = 16*0.18= 2.88 = 3 rUDIVSLOT0 = 0x0888; // 3个1,查官方推荐表得到这个数字 } #endif void putc(char ch) { //直接写入 UTX2就可以然后自动发送 UTXH2, W, Address = 0xE290_0820 //以轮询的方式发送检查是否已经发送完成 UTRSTAT2, R, Address = 0xE290_0810 if (ch == ‘\n‘) { while (!(rUTRSTAT2 & (0x1<<1))); rUTXH2 = (unsigned int)(‘\r‘); } while (!(rUTRSTAT2 & (0x1<<1))); rUTXH2 = (unsigned int)ch; } char getc(void) { // URXH2, R, Address = 0xE290_0824 while (!(rUTRSTAT2 & (1<<0))); return (rURXH2 & 0xFF); }
第二部构建两个函数puts打印字符串、gets读取字符串、
void puts(const char *pch) { while ((*pch)!=‘\0‘) { putc(*pch); pch++; } } char *gets(char *pbuf) { char *p = pbuf; while ((*pbuf = getc()) != ‘\r‘) { //window中用键盘输入的回撤为/r/n //所以判断是否输入回撤时要判断是否为/r if (*pbuf != ‘\b‘) { putc(*pbuf); *pbuf++; } else { if(pbuf > p) { putc(‘\b‘); //这段代码是用来实现回显 putc(‘ ‘); //如果是\b的话putc \b,然后在输入空格把原来的字符删除 putc(‘\b‘); //在输出\b会原位。 pbuf--; } } } *pbuf = ‘\0‘; putc(‘\n‘); return p; } void* memset(void *buf, int c, int n) { int i = 0; char *p = (char*)buf; while (i < n) { *p = (char)c; i++; p++; } return buf; }
#include "stdio.h" int main(void) { char buf[100]; //初始化时钟 clock_init(); //初始化uart uart_init(); puts("x210_shell:\n"); while (1) { puts("210x_bhc#"); memset(buf, 0, sizeof(buf)); gets(buf); puts("210x_bhc#what you put is "); puts(buf); puts("\n"); } return 0; }
这样就实现了一个简单的命令行回显功能,之后再加入命令。。下章继续。
原文:http://www.cnblogs.com/biaohc/p/6308938.html