zoukankan      html  css  js  c++  java
  • shell学习一:shell命令行实现

    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 == '
    ') {
            while (!(rUTRSTAT2 & (0x1<<1)));
            rUTXH2 = (unsigned int)('
    ');
        }
        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)!='') {
            putc(*pch);
            pch++;
        }
    }
    
    char *gets(char *pbuf)
    {
        char *p = pbuf;
        
        while ((*pbuf = getc()) != '
    ') {        //window中用键盘输入的回撤为/r/n
                                                //所以判断是否输入回撤时要判断是否为/r        
            if (*pbuf != '') {            
                putc(*pbuf);            
                *pbuf++;
            }
            else {
                if(pbuf > p) {
                    putc('');                        //这段代码是用来实现回显
                    putc(' ');                        //如果是的话putc ,然后在输入空格把原来的字符删除
                    putc('');                        //在输出会原位。            
                    pbuf--;    
                }
                        
            }
            
        }
        *pbuf = '';    
        putc('
    ');
        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:
    ");
        while (1) {
            puts("210x_bhc#");
            memset(buf, 0, sizeof(buf));        
            gets(buf);
            puts("210x_bhc#what you put is ");
            puts(buf);    
            puts("
    ");
            
            
        }    
        return 0;
    }

     这样就实现了一个简单的命令行回显功能,之后再加入命令。。下章继续。

  • 相关阅读:
    经典排序算法动态图
    oracle之触发器
    假如有Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小
    spring mvc将对象转换为json返回的配置
    用jackson包实现json、对象、Map之间的转换
    不加好友实现QQ在线代码状态临时会话
    QQ自动强制加好友代码html
    maven 私服搭建
    java定时任务
    ORACLE数据库表解锁record is locked by another user
  • 原文地址:https://www.cnblogs.com/biaohc/p/6308938.html
Copyright © 2011-2022 走看看