ARM裸板開発——簡単な作成で「shell」機能を実現

32207 ワード

文書ディレクトリ
  • は、裸の環境で使用される「shell」機能を実現するプログラムを簡単に作成し、LED、beepなどを制御することができる.
  • mainメインプログラム設計
  • 主な関数:strcmp
  • を実現
  • LED初期化及び制御機能実現
  • UART初期化及び制御機能実現
  • Makefileを使用して
  • をコンパイル
  • 実行結果
  • 裸の環境で使用する「shell」機能を実現するプログラムを簡単に作成し、LED、beepなどを制御することができます.
    mainメインプログラム設計
    #include "uart.h"
    #include "strcmp.h"
    #include "led.h"
    
    //             
    static char buf[32];
    
    void main(void)
    {
        //1.   UART
        uart_init();
        //2.   LED
        led_init();
    
        //3.          
        while(1) {
            uart_puts("
    Shell#"
    ); uart_gets(buf, 32); if(!my_strcmp(buf, "led on")) led_on(); else if(!my_strcmp(buf, "led off")) led_off(); else uart_puts("
    Your command is invalid
    "
    ); } }

    主な関数:strcmp実装
    strcmp文字列比較関数を実現し、ユーザーコマンドの入力を比較します.
  • strcmp.h
  • #ifndef __STRCMP_H
    #define __STRCMP_H
    
    /*  :         
     *   :
        str1=str2:  0
        str1>str2:    0
        str1
    extern int my_strcmp(const char *str1,
                         const char *str2);
    #endif
    
    
  • strcmp.c
  • #include “strcmp.h”
    /*str1 = "hello", str2 = "hfllo"*/
    int my_strcmp(const char *str1, 
                    const char *str2)
    {
        while(*str1) {
            if(*str1 != *str2)
                return *str1 - *str2;
            str1++;
            str2++;
        }
        return *str1 - *str2;
    }
    
    

    LED初期化及び制御機能実現
  • led.h
  • #ifndef __LED_H
    #define __LED_H
    
    /*           */
    #define GPIOCOUT (*(volatile unsigned long *)0xC001C000)
    #define GPIOCOUTENB (*(volatile unsigned long *)0xC001C004)
    #define GPIOCALTFN0 (*(volatile unsigned long *)0xC001C020)
    
    /*      */
    extern void led_init(void);
    extern void led_on(void);
    extern void led_off(void);
    #endif
    
    
  • led.c
  • #include "led.h"
    
    //       
    void led_init(void)
    {
        //1.       GPIO  
        GPIOCALTFN0 &= ~(3 << 24);
        GPIOCALTFN0 |= (1 << 24);
    
        //2.         
        GPIOCOUTENB |= (1 << 12);
    }
    
    //      
    void led_on(void)
    {
        //1.        0
        GPIOCOUT &= ~(1 << 12);
    }
    
    //      
    void led_off(void)
    {
        //1.        1
        GPIOCOUT |= (1 << 12);
    }
    

    UART初期化及び制御機能実現
  • uart.h
  • #ifndef __UART_H
    #define __UART_H
    
    /*UART       */
    #define ULCON0 (*(volatile unsigned long *)0xC00A1000)
    #define UCON0 (*(volatile unsigned long *)0xC00A1004)
    #define UTRSTAT0 (*(volatile unsigned long *)0xC00A1010)
    #define UTXH0 (*(volatile unsigned long *)0xC00A1020)
    #define URXH0 (*(volatile unsigned long *)0xC00A1024)
    #define UBRDIV0 (*(volatile unsigned long *)0xC00A1028)
    #define UFRACVAL0 (*(volatile unsigned long *)0xC00A102C)
    #define GPIODALTFN0 (*(volatile unsigned long *)0xC001D020)
    #define GPIODALTFN1 (*(volatile unsigned long *)0xC001D024)
    #define UARTCLKENB (*(volatile unsigned long *)0xC00A9000)
    #define UARTCLKGENOL (*(volatile unsigned long *)0xC00A9004)
    
    /*UART      */
    //     
    extern void uart_init(void);
    //      
    extern void uart_putc(char c);
    //       
    extern void uart_puts(char *str);
    //      
    extern char uart_getc(void);
    //       
    extern void uart_gets(char buf[], int len);
    #endif
    
    
  • uart.c
  • #include "uart.h"
    
    //        
    void uart_init(void)
    {
        //1.  RX TX          UARTRXD0 UARTTXD0  
        //GPIOD14  UARTRXD0
        //GPIODALTFN0[29:28]=01
        GPIODALTFN0 &= ~(3 << 28);
        GPIODALTFN0 |= (1 << 28);
        //GPIOD18  UARTTXD0
        //GPIODALTFN1[5:4]=01
        GPIODALTFN1 &= ~(3 << 4);
        GPIODALTFN1 |= (1 << 4);
    
        //2.  UART    50MHZ
        //            
        //PLL[0]=800MHZ
        //n=800MHZ/50MHZ=16
        //n=CLKDIV0+1=>CLKDIV0=15
        //CLKDIV0=UARTCLKGENOL[12:5]
        UARTCLKGENOL &= ~(0xFF << 5);
        UARTCLKGENOL |= (0xF << 5);
    
        //3.  UART     115200
        //    8
        //       
        //    1 
        ULCON0 = 3;
        UCON0 = 5;
        UBRDIV0 = 26; 
        UFRACVAL0=2;
    
        //4.  UART   
        UARTCLKENB |= (1 << 2);
    }
    
    //        
    //               
    //               
    //   TX   ,    115200
    void uart_putc(char c)
    {
        //1.  CPU                          TX       ,CPU                          ,    ,   ,       
        while(!(UTRSTAT0 & 0x2));
    
        //2.          
        UTXH0 = c;
        
        //3.      
        if(c == '
    '
    ) uart_putc('\r'); } // //str = "helloworld
    "
    void uart_puts(char *str) { while(*str) { uart_putc(*str); str++; } } // char uart_getc(void) { //1. CPU UART // RX , CPU , // // // :CPU // :CPU while(!(UTRSTAT0 & 0x1)); //2. return (URXH0 & 0xFF); } // // :char buf[32];uart_gets(buf, 32) void uart_gets(char buf[], int len) { int i; for (i = 0; i < len - 1; i++) { // buf[i] = uart_getc(); // uart_putc(buf[i]); // // , if(buf[i] == '\r') break; } buf[i] = 0; // }

    Makefileでコンパイル
  • Makefile
  • #    
    NAME=shell
    BIN=$(NAME).bin
    ELF=$(NAME).elf 
    OBJ=main.o uart.o led.o strcmp.o
    
    CROSS_COMPILE=arm-cortex_a9-linux-gnueabi-
    CC=$(CROSS_COMPILE)gcc
    LD=$(CROSS_COMPILE)ld
    OBJCOPY=$(CROSS_COMPILE)objcopy
    CP=cp
    RM=rm
    INSTALLPATH=/tftpboot
      
      #    
    LDFLAGS=-nostdlib -nostartfiles -Ttext=0x48000000 -emain
      #    
    CFLAGS=-nostdlib
    
    #      
    shell.bin:shell.elf
    	arm-cortex_a9-linux-gnueabi-objcopy -O binary shell.elf shell.bin
    
    $(BIN):$(ELF)
    	$(OBJCOPY) -O binary $(ELF) $(BIN)
    	$(CP) $(BIN) $(INSTALLPATH)
    #
    #   		#shell.elf:main.o uart.o led.o strcmp.o
    #     arm...ld -nostartfiles -nostdlib -... -o shell.elf main.o ...
    $(ELF):$(OBJ)
    	$(LD) $(LDFLAGS) -o $(ELF) $(OBJ)
    #  .o:  .c
    #      
    %.o:%.c
    	$(CC) $(CFLAGS) -c -o $@ $<
    #  	 
    #  	 #   
    #   make clean ,    clean        
    clean:
    		$(RM) $(BIN) $(ELF) $(OBJ)   
    
    

    実行結果
    ボード上のubootインタフェースで実行します.
    tftp 48000000 shell.bin
    go 48000000