ARM裸板開発——簡単な作成で「shell」機能を実現
32207 ワード
文書ディレクトリは、裸の環境で使用される「shell」機能を実現するプログラムを簡単に作成し、LED、beepなどを制御することができる. mainメインプログラム設計 主な関数:strcmp を実現 LED初期化及び制御機能実現 UART初期化及び制御機能実現 Makefileを使用して をコンパイル実行結果 裸の環境で使用する「shell」機能を実現するプログラムを簡単に作成し、LED、beepなどを制御することができます.
mainメインプログラム設計
主な関数:strcmp実装
strcmp文字列比較関数を実現し、ユーザーコマンドの入力を比較します. strcmp.h strcmp.c
LED初期化及び制御機能実現 led.h led.c
UART初期化及び制御機能実現 uart.h uart.c
Makefileでコンパイル Makefile
実行結果
ボード上のubootインタフェースで実行します.
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文字列比較関数を実現し、ユーザーコマンドの入力を比較します.
#ifndef __STRCMP_H
#define __STRCMP_H
/* :
* :
str1=str2: 0
str1>str2: 0
str1
extern int my_strcmp(const char *str1,
const char *str2);
#endif
#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初期化及び制御機能実現
#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
#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初期化及び制御機能実現
#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
#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でコンパイル
#
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