s3c2410手冊 : http://wenku.baidu.com/view/105ddc264b35eefdc8d3338a.html
http://wenku.baidu.com/view/c5c9171a59eef8c75fbfb3b5.html
s3c2410引腳分類: http://wenku.baidu.com/view/003795f8c8d376eeaeaa3102.html
在網上苦苦尋找skyeye的使用教程,發現根本沒有搜到幾篇文章。即使有,也是說說理論部分,根本不會詳細的說明源代碼如何使用,編譯,鏈接,生成,對於我這種剛剛接觸skyeye的人來說,要使用skyeye來進行模擬真的非常難啊。故鑑於網上資料少之又少,只好自己硬着頭皮去研究例子和源代碼,至此記錄skyeye的學習。
對skyeye模擬s3c2410引腳,時鐘,串口等寄存器的詳細描述,可以看skyeye的源代碼:skyeye/soc/arm/s3c2410x下的s3c2410x.h
由此可以知道skyeye中s3c2410所支持的外設模塊有哪些。
S3C2410的UART的寄存器有11X3個(3個UART)之多,我選UART0來進行通信,用到的寄存器有8個。不過初始化就用去了5個寄存器,剩下的3個用於接收、發送數據。
第一步:串口編寫流程
1、初始化引腳: 把使用到的引腳GPH2、GPH3定義爲TXD0、RXD0
GPHCON |= 0xa0
GPHUP |= 0x0c
2、設置串口數據格式寄存器ULCON0:8個數據位,1個停止位,無校驗,正常操作模式(與之相對的是Infra-Red Mode,此模式表示0、1的方式比較特殊)
ULCON0 = 0x03
3、設置串口控制寄存器UCON0:設置發送、接收都使用“中斷或查詢方式”
UCON0 = 0x05
4、設置串口FIFO寄存器UFCON0:本次不使用FIFO,設爲默認值0
UFCON0 = 0x00
5、UMCON0 (UART channel 0 Modem control register ):本次不使用流控,設爲默認值0
UMCON0 = 0x00
6、設置波特率寄存器UBRDIV0:波特率計算公式UBRDIVn = (int)(PCLK / (bps x 16) ) –1 ,要看說明書驗算一下此波特率是否在可容忍的誤差範圍之內;如果不在,則需要更換另一個波特率,本次使用的57600是符合的
UBRDIV0 = 0x12
至此,串口初始化完畢,下面進行數據的收發:
串口狀態寄存器:UTRSTAT0 其位功能如下
位[2]:無數據發送時,自動設爲1。當我們要使用串口發送數據時,先讀此位以判斷是否有數據正在佔用發送口。
位[1]:發送FIFO是否爲空,本次未用此位
位[0]:接收緩衝區是否有數據,若有,此位設爲1。需要用到這位,需要不斷查詢此位一判斷是否有數據已經被接收。
串口發送寄存器UTXH0 :把要發送的數據寫入此寄存器。
3、接收數據:
UTRSTAT0:如同上述“發送數據”所列,我們用到位[0]
串口發送寄存器URXH0 : 當查詢到UTRSTAT0 位[0]=1時,讀此寄存器獲得串口接收到的數據。
對程序有了大概的流程後,下一步開始編碼:
我的工程的組成:
start.s 設置中斷,堆棧環境
s3c2410.h 定義寄存器宏
serial.c serial.h 串口初始化函數,收發函數
hello.c 主要函數
-----------------------------------------------------------------------------------------------------------------------------
start.s 的代碼如下
#define MODE_SVC 0x13
#define I_BIT 0x80
.text
.align 4
.global begin
.type begin, function
begin:
/*disable I-bit*/
mov r0, #I_BIT|MODE_SVC
msr cpsr_c, r0
mov r1,#0xd2
sub r2,r0,r1
ldr sp, =irq_stack @ set sp_irq = irq_stack
bl hello
b begin
.data
.align 4
irq_stack:
.space 4096
-----------------------------------------------------------------------------------------------------------------------------
s3c2410.h的代碼如下
/* WOTCH DOG register */
#define WTCON (*(volatile unsigned long *)0x53000000)
/* SDRAM regisers */
#define MEM_CTL_BASE 0x48000000
#define SDRAM_BASE 0x30000000
/* NAND Flash registers */
#define NFCONF (*(volatile unsigned int *)0x4e000000)
#define NFCMD (*(volatile unsigned char *)0x4e000004)
#define NFADDR (*(volatile unsigned char *)0x4e000008)
#define NFDATA (*(volatile unsigned char *)0x4e00000c)
#define NFSTAT (*(volatile unsigned char *)0x4e000010)
/*GPIO registers*/
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPHCON (*(volatile unsigned long *)0x56000070)
#define GPHDAT (*(volatile unsigned long *)0x56000074)
#define GPHUP (*(volatile unsigned long *)0x56000078)
/*UART registers*/
#define ULCON0 (*(volatile unsigned long *)0x50000000)
#define UCON0 (*(volatile unsigned long *)0x50000004)
#define UFCON0 (*(volatile unsigned long *)0x50000008)
#define UMCON0 (*(volatile unsigned long *)0x5000000c)
#define UTRSTAT0 (*(volatile unsigned long *)0x50000010)
#define UTXH0 (*(volatile unsigned char *)0x50000020)
#define URXH0 (*(volatile unsigned char *)0x50000024)
#define UBRDIV0 (*(volatile unsigned long *)0x50000028)
-----------------------------------------------------------------------------------------------------------------------------
serial.h的代碼如下void init_uart(void);void putc(unsigned char c);unsigned char getc(void);-----------------------------------------------------------------------------------------------------------------------------
serial.c的代碼如下#include "s3c2410.h"#include "serial.h"#defineTXD0READY(1<<2)#defineRXD0READY(1)
void init_uart( ){//初始化UART GPHCON |= 0xa0;//GPH2,GPH3 used as TXD0,RXD0 GPHUP = 0x0c;//GPH2,GPH3內部上拉
ULCON0 = 0x03;//8N1 UCON0 = 0x05;//查詢方式 UFCON0 = 0x00;//不使用FIFO UMCON0 = 0x00;//不使用流控 UBRDIV0 = 12;//波特率爲57600}
void putc(unsigned char c){ while( ! (UTRSTAT0 & TXD0READY) ); UTXH0 = c;}
unsigned char getc( ){ while( ! (UTRSTAT0 & RXD0READY) ); return URXH0;}
-----------------------------------------------------------------------------------------------------------------------------
hello.c的代碼如下
#include "s3c2410.h"
#include "serial.h"
#define BOGO_MIPS 1000000
void hello(void)
{
int i;
char * hellostr="helloworld";
int timeout ;
i = *hellostr - 'h';
init_uart();
while(1){
timeout = 0;
while(++timeout != BOGO_MIPS);
for(i=0;i<10;i++)
{
putc(hellostr[i]);
}
}
return;
}
-----------------------------------------------------------------------------------------------------------------------------接下來就是要寫鏈接文件了,它決定文件的存儲域,加載域,允許域等東西,是合併文件所需要的下面就是hello.lds的類容了,具體含義上網看看lds鏈接文件的含義吧OUTPUT_ARCH(arm)ENTRY(begin)SECTIONS{ . = 0xc0000000; .text : { *(.text) *(.rodata) }. = ALIGN(8192);
.data : {*(.data)}
.bss : {*(.bss)}
/* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_info 0 : { *(.debug_info) } .debug_line 0 : { *(.debug_line) } .debug_pubnames 0 : { *(.debug_pubnames) } .debug_aranges 0 : { *(.debug_aranges) }
}
-----------------------------------------------------------------------------------------------------------------------------
接下來就是寫個Makefile文件,最終生成我們的目標文件
下面是我寫的Makefile的內容了
#begin
CC=arm-elf-gcc
LD=arm-elf-ld
CFLAGS= -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi
LDFLAGS= -N -p -X -Thello.lds
LIB=
all: hello
hello: start.o hello.o serial.o
$(LD) $(LDFLAGS) start.o hello.o serial.o -o hello
arm-elf-objdump -xS hello > hello.s
arm-elf-readelf -a hello > hello.r
arm-elf-nm hello > hello.n
start.o:start.S
$(CC) $(CFLAGS) start.S
hello.o:hello.c
$(CC) $(CFLAGS) hello.c
serial.o:serial.c
$(CC) $(CFLAGS) serial.c
clean:
rm -rf *.o *.elf *.gdb *.r *.n *.s
test:
skyeye -e hello -c skyeye.conf
#end
---------------------------------------------------------------------------------------
Makefile的基本語法過程也應該會點吧,不會的話就應該自己補補了
最後就是skyeye的skyeye.conf的文件置配了
關於skyeye.conf裏面的內容介紹,請看skyeye的官方PDF文檔,裏面說的很清楚
在這裏需要設置內存的分佈圖,外設IO,cpu體系結構等,下面是我的skyeye.conf文件的置配內容
#skyeye config file sample
cpu: arm920t
mach: s3c2410x
#physical memory
#mem_bank: map=M, type=RW, addr=0x01000000, size=0x00400000
#mem_bank: map=M, type=RW, addr=0x20000000, size=0x01000000
mem_bank: map=M, type=RW, addr=0xc0000000, size=0x01000000
mem_bank: map=M, type=RW, addr=0xc1000000, size=0x00600000, file=./initrd.img
mem_bank: map=M, type=RW, addr=0xc1600000, size=0x00a00000
#all peripherals I/O mapping area
#mem_bank: map=I, type=RW, addr=0xfefa0000, size=0x00060000
mem_bank: map=I, type=RW, addr=0x48000000, size=0x20000000
mem_bank: map=I, type=RW, addr=0x19000300, size=0x00000020
uart:mod=term
#net: type=cs8900a, base=0x19000300, size=0x20,int=9, mac=0:4:3:2:1:f, ethmod=tuntap, hostip=10.0.0.1
#lcd:type=s3c2410x,mod=gtk
#dbct:state=on
好了,至此skyey的s3c2410的串口編寫的整個流程都搞好了
在工程目錄下終端鍵入make生成
鍵入 make test,自動進入skyeye,然後start,run就可以了
以下是測試通過的圖