基于S3C4510B的一个简单BSP的开发报告
系統環境
(一)? 硬件環境
CPU:S3C4510B
SDRAM:W981216DH 16M
FLASH:MX29LV160AB 2M
(二)? 軟件環境
tornado2.01 for arm(AKA的FTP上有tornado2.2需要的可以自己去下載:))
(三)? 調試環境
TRACE32`??? ??
?
TRACE32
(一)利用TRACE32調試vxWorks
S3C4510B在系統上電時,CPU寄存器的基地址為0X3FF0000,利用TRACE32直接對CPU進行初始化,分配內存布局,初始化SDRAM,然后再加載vxWorks.st進行系統調試。
腳本如下:
; t32initial script for s3c4510b
; initial s4510b sdram and flash
? d.s 0x03ff0000 %l 0x87ffffa0
? d.s 0x03ff3010 %l 0x00003001
? d.s 0x03ff3014 %l 0x12040060
? d.s 0x03ff3018 %l 0x60
? d.s 0x03ff301c %l 0x60
? d.s 0x03ff3020 %l 0x60
? d.s 0x03ff3024 %l 0x60
? d.s 0x03ff3028 %l 0x60
? d.s 0x03ff302c %l 0x10000398
? d.s 0x03ff3030 %l 0x00
? d.s 0x03ff3034 %l 0x00
? d.s 0x03ff3038 %l 0x00?
? d.s 0x03ff303c %l 0xce2983fd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; s3c4510b board - load coff file TRACE32 script file
? B::
? sYmbol.RESet
?
; load coff file
? d.load.coff? e:/s4510b_bsp/vxWorks.st? /spath /lpath??
? r.s pc 0x1000
?
; load symbol path
? y.spath + e:/s3c4510b_bsp/
? y.spath + d:/tor_arm/target/src/netwrs
? y.spath + d:/tor_arm/target/src/netinet
?
? ENDDO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1:初始化CPU
???
d.s 0x03ff0000 %l 0x87ffffa0 二進制為1000,0111,1111,1111,1111,1111,1010,0000
[05:04] = 10b 為8-Kbyte SRAM 0-Kbyte Cache
[15:06] = 1111111110b = 0x3FE SRAM的起始地址為0x3FE0000
[25:16] = 1111111111b = 0x3FF CPU寄存器基地址為0x3FF0000
[31]?? = 1b SDRAM
2:初始化內存布局
?
d.s 0x03ff3010 %l 0x00003001二進制為??? 0000,0000,0000,0000,0011,0000,0000,0001
[01:00] = 01b FLASH bank0數據總線為BYTE(8-BIT)
[13:12] = 11b SDRAM bank0 數據總線為 DWORD(32-BIT)
其他全部disable
?
d.s 0x03ff3014 %l 0x12040060二進制為 0001,0010,0000,0100,0000,0000,0110,0000
[01:00] = 00b NormalROM
[03:02] = 00b 5 cycles ( Page address access time (t PA ) )
[06:04] = 110b 7 cycle ( Programmable access cycle (t ACC ) )
[19:10] = 0100000000b = 0x100 FLASH bank0基地址為0x1000000
[29:20] = 0100100000b = 0x120 FLASH bank0 結束地址為 0x1200000-1
?
d.s 0x03ff302c %l 0x10000398 二進制為 0001,0000,0000,0000,0000,0011,1001,1000
[00:00] = 00b Normal SDRAM
[02:01] = 00b 1 cycle ( CAS strobe time (tCS) )
[03:03] = 01b 2 cycles(CAS pre-charge time (tCP))
[07:07] = 01b 2 cycles? (RAS to CAS delay (tRC or tRCD))
[09:08] = 11b 4 cycles (RAS pre-charge time (tRP))
[19:10] = 0000000000b = 0x00 SDRAM bank0 基地址為 0x000000
[29:20] = 0100000000b = 0x100 SDRAM bank0 結束地址為 0x1000000-1
[31:30] = 00b 8bits ( Number of column address bits in DRAM bank0 )
?
d.s 0x03ff303c %l 0xce2983fd 二進制為 1100,1110,0010,1001,1000,0011,1111,1101
[09:00] = 1111111101b = 0x3FD External I/O bank0 的基地址為 0x3FD0000
其他各位意義請對照datasheet
內存初始化完畢后系統內存布局為:
00-16M 為 SDRAM
16-18M 為 FLASH
0x3FD0000開始64K為External I/O
0x3FE0000 開始8K為SRAM
0x3FF0000 開始64K 為CPU寄存器
3:加載vxWorks.st
d.load.coff? e:/s4510b_bsp/vxWorks.st? /spath /lpath 將vxWorks.st 加載到SDRAM中去
r.s pc 0x1000 設置pc指針到RAM_LOW_ADRS(0x1000)
這時就可以使用TRACE32設置斷點進行調試了。
(二)利用TRACE32燒寫bootrom
1:FLASH的擦除
; s3c4510b - flash erase TRACE32 script file
; flash type : AM29F100
; Erase flash by TRACE32
? flash.reset
? flash.create 0x1000000--0x10fffff AM29F100 WORD
? flash.erase 0x1000000--0x1001fff
? flash.erase 0x1002000--0x1003fff
? flash.erase 0x1004000--0x1005fff
? flash.erase 0x1006000--0x1007fff
? flash.erase 0x1008000--0x1009fff
? flash.erase 0x100a000--0x100bfff
? flash.erase 0x100c000--0x100dfff
? flash.erase 0x100e000--0x100ffff
? …………………………………….
ENDDO
2:bootrom的燒寫
;s3c4510b flash write TRACE32 script file
; flash type : AM29F100
; Write flash by TRACE32
? B::
? flash.reset
? flash.create 0x1000000--0x10fffff AM29F100 word
? flash.program all
; download *.bin file
? d.load.binary E:/s4510b_bsp/bootrom.bin 0x1000000
? flash.program off
?
? ENDDO
?
BSP的開發流程
(一)? vxWorks的執行流程
在系統開發期,我們通常利用調試工具將編譯好的帶調試符號的vxWorks下載到SDRAM中進行調試,所有功能調試結束后才編譯生成bootrom.bin將其燒寫的FLASH中。所以vxWorks有從ROM中啟動和SDRAM中啟動之分。
?
1:從SDRAM中啟動vxWorks
?????? 利 用TRACE32將vxWorks.st下載到SDRAM中,這時根據TRACE32腳本設置,pc指針指向0x1000,這是sysInit ()的入口點。VxWorks在正常重啟下調用該函數,在sysALib.s中定義,它禁止緩存器,初始化系統中斷表、系統故障表,清除所有等待的中斷, 調用usrInit(bootType)。
??????? UsrInit() 是vxWorks下首先運行的C程序,它需要完成創建初始任務usrRoot()所需要的工作。它首先調用bzero (edata, end - edata);清除系統bss段,保存啟動類型,調用intVecBaseSet ((FUNCPTR *) VEC_BASE_ADRS); 設置中斷向量表,調用excVecInit ();設置異常向量,調用sysHwInit ();初始化系統硬件,調用usrKernelInit ();配置Wind內核,最后調用kernelInit ()開始系統根任務usrRoot;
??????? UsrRoot是運行在多任務環境下的第一個任務,它完成最后的初始化,并且啟動其他任務。UsrRoot()按照configAll.h和config.h中的配置來初始化I/O系統,安裝驅動程序,創建設備,設置網絡等等。
??? ??? 在 開發過程中,我們可以利用TRACE32對每一步執行進行跟蹤,觀察程序的執行行為,檢查相關寄存器的內容;也可以寫一些測試函數,對完成的相關的功能進 行簡單的測試,例如當我們完成了串口在輪詢模式下工作的驅動程序后,我們可以寫一個echo程序對串口的輸入輸出進行簡單的檢查。 ???
2:從ROM中啟動vxWorks
當我們利用TRACE32 調試好一個BSP以后,這時就需要修改rominit.s這個文件了,這個文件中的romInit()是冷啟動時的入口點,它將啟動類型入棧,禁止中斷, 初始化CPU,配置SDRAM、FLASH,并轉移到bootinti.c中的romStart(),它將(文本段和)數據段復制到SDRAM中的 RAM_HIGH_ADRS處,并最終調用usrInit(bootType)。
在開發過程中,我們需要利用燒錄工具或者調試工具將編譯生成的bootrom.bin 下載到FLASH之中,當系統上電時,CPU將FLASH鏡像到地址0x00000000處,并開始執行,當romInit()執行完必要的操作后,它將 跳轉到FLASH的真實地址0x01000000處,并執行SDRAM、FLASH的初始化,這時再將SDRAM映射到0x00000000至 0x00ffffff處(0-16M),將FLASH映射到0x01000000至0x011fffff(16-18M)處完成其他的執行。
(二)? CPU的體系結構
S3C4510B 是使用ARM7TDMI核的CPU,因此需要對ARM7TDMI有一定的了解,需要注意的是32位精簡指令集的CPU對數據的操作是按一個字長(4- BYTE)進行的,所以我們在gcc的編譯開關中需要用—pack-struct來消除結構體間的空白,在強制類型轉換時也需要特別的注意,因為一旦一個 奇數地址被解釋成一個short(16-bit)或int(32-bit)類型地址時將產生異常。
(三)? 利用調試工具輔助開發
在開發BSP時,有得心應手的調試工具將事半功倍。在這個項目中,我使用了TRACE32,它界面簡潔,十分容易上手。
在開發初期,我們需要編寫腳本文件來對CPU、 SDRAM、FLASH進行初始化,為了檢驗初始化結果是否正確,我們可以通過對SDRAM中的地址進行讀寫,看看結果與我們期望的是否一致。經過了這一 步,再將vxWorks.st下載到SDRAM中,通過單步運行檢查代碼執行是否正常,定位出錯誤的代碼位置,反復修改直到系統正常運行為止。
?
硬件初始化
(一)?? VxWorks的行為
vxWorks 在usrInit()中調用sysHwInit(),它設置所有設備進入安靜狀態,屏蔽所有可屏蔽的中斷。sysHwInit調用 sysSerialHwInit();來初始化串口設備,并且在uartDevInit()中配置串口相關寄存器,設置波特率,置串口工作模式為輪詢模 式。
在usrRoot() 中調用sysClkConnect(),sysClkConnect立即調用sysHwInit2()來完成sysHwInit()中不能完成的工作, (因為在調用sysHwInit()時還沒有初始化系統內存池,所以不能調用malloc相關的函數,例如intConnect())它調用 intLibInit()初始化中斷庫,調用irqDevIcnit()初始化中斷控制器,然后用intConnect()掛接時鐘中斷,調用 sysSerialHwInit2()將串口設置成中斷工作模式。
(二)? SC34510B的中斷描述
?????? SC34510B擁有21個中斷源,如下表所示:
??
在這個例子中我用到了[4]、[5]、[10] 這三個中斷源,分別為串口0發送中斷、串口0接收中斷、定時器0中斷。在初始化中斷控制器時我們需要設置INTMOD寄存器,將中斷源配置在我們需要的工 作模式下,這里我將他們配置成普通中斷模式(IRQ),即將[20:00]位清零。INTMOD寄存器如下圖所示:
?
INTPND中斷未決寄存器,它包含每個中斷源的未決中斷,需要在中斷服務程序中通過對相應的位置一來清除該未決的中斷。寄存器如下圖所示:
INTMSK中斷掩碼寄存器,它包含每個中斷源的中斷掩碼,當相應的位被置一時,該中斷將被屏蔽。寄存器如下圖所示:
在這個例子中,我沒有改變系統中各個中斷源的優先級順序,即從0開始到第21,0的優先級最高,依次遞減。
(三)? 中斷驅動程序
??? 在irqDevIcnit()中初始化中斷控制器,它初始化中斷驅動程序結構,初始化中斷控制器寄存器。
在irqcLvlVecChk()中檢查并返回當前優先級最高的未決中斷。在這期間它設置當前中斷優先級為這個未決中斷的優先級,來確保在中斷服務期間只允許優先級比它高的中斷產生。
在irqcLvlVecAck()中重新設置當前中斷為前一個中斷級別。
在irqcLvlChg()中設置新的當前中斷級別,所用優先級比當前中斷低的(包括當前中斷)將被屏蔽掉,所有比當前中斷優先級高的且被允許中斷的將被打開。
在irqcLvlEnable()允許指定中斷產生。
在irqcLvlDisable()屏蔽一個指定中斷。
(四)? 串口中斷
在uartDevInit()中初始化串口控制器,設置波特率,初始化串口驅動程序。在期間需要配置的寄存器如下:
ULCON0寄存器,其值設為0x03,8-bit數據位,無停止位,無奇偶位。
??????? UCON0寄存器,其值設為0x00,設置接收和發送中斷無效。
??????? UBRDIV0 寄存器,設置波特率除數因子,這里我設置的波特率為38400根據公式可以計算出該寄存器的值應該為0x270。公式為(fMCLK_MHz/(32* (_rate)) - 1)這里CPU的頻率為50MHZ,_rate為38400,所以CNT0的值為0x27,采用除一的方式,所以CNT1為0000b,所以該寄存器的結 果為0x270。
??????? uartPollInput()串口在輪詢模式下輸入處理程序。
UartPollOutput()串口在輪詢模式下輸出處理程序。
UartTxStartup()串口啟動一個中斷輸出。
UartIntRX()輸人中斷服務程序,注意要清除輸入中斷相應的中斷未決位。
UartIntTX()輸出中斷服務程序,注意要清除輸出中斷相應的中斷未決位。
在以上幾個函數中需要用到一下幾個寄存器USTAT0、URXBUF0、UTXBUF0,大家自己查資料吧:)。
(五)? 時鐘中斷
??????? sysClkInt()為時鐘中斷的服務程序,在中斷驅動程序初始化之后調用intConnect()注冊的。
??? ??? SysClkEnable()啟動一個定時器,它計算每次時鐘中斷發生的時間間隔,并根據公式((fMCLK_MHz)/(sysClkTicksPerSecond)-1)算出TDATA0的值。設置TMOD為0x03,開啟timer0,打開時鐘中斷。
??????? SysClkDisable()停止一個定時器。它設置TMOD為0x00,關閉時鐘中斷。相關寄存器如下:
sysClkRateSet()設置每秒鐘tick數,并通過連續調用SysClkDisable(),SysClkEnable()來更新設置。
SysClkRateGet()獲取每秒鐘tick數。
?
RomInit.s文件分析
當我們利用TRACE32 開發調試完一個在RAM中運行的vxWorks后,需要修改romInit.s和bootInti.c,編譯連接生成bootrom.bin,然后利用工 具燒錄到FLASH之中。以下是我針對S3C4510B這款CPU修改的romInit.s文件,代碼及注釋如下:
?
/* romInit.s - ARM PID ROM initialization module */
/* Copyright 1996-1999 Wind River Systems, Inc. */
??? .data
??? .globl? _copyright_wind_river
??? .long?? _copyright_wind_river
?
/*
modification history
--------------------
;*****************************************************************************/
?
#define _ASMLANGUAGE
#include "vxWorks.h"
#include "arch/arm/arm.h"
#include "regs.h"
#include "sysLib.h"
#include "config.h"
#include "s4510b.h"
?
/* internals */
?
??? .globl? _romInit??? ??? /* start of system code */
??? .globl? _sdata????? /* start of data */
?
/* externals */
?
??? .extern _romStart?? ??? /* system initialization routine */
?
_sdata:
??? .asciz? "start of data"
??? .balign 4
?
??? .text
??? .balign 4
?
/*******************************************************************************
*
* romInit - entry point for VxWorks in ROM
*
* romInit
*???? (
*???? int startType /@ only used by 2nd entry point @/
*???? )
* INTERNAL
* sysToMonitor examines the ROM for the first instruction and the string
* "Copy" in the third word so if this changes, sysToMonitor must be updated.
*/
_romInit:
romInit:
cold:
?? mov?? r0, #BOOT_COLD?? /* fall through to warm boot entry */
warm:
?? b?? start
?? /* copyright notice appears at beginning of ROM (in TEXT segment) */
?? .ascii?? "Copyright 2000-2001 STM / Cap Gemini."
?? .balign 4
?
start:
?? nop
?? nop
?? nop
?? nop??????????
/*Part 1*/
/****************************************************************/
/*disable interrupts in CPU and switch to SVC32 mode*/
??? mrs r0, cpsr
??? bic r0, r0, #MASK_MODE
??? orr r0, r0, #MODE_SVC32
??? orr r0, r0, #I_BIT
??? orr r0, r0, #F_BIT
??? msr cpsr, r0
?
??? ldr r2, =ARM7_INTMASK?????????? /*R2->interrupt controller*/
??? mvn r1, #0????????????????? ??? /*&FFFFFFFF*/
??? str r1, [r2]??????????????? ??????? /*disable all interrupt soucres*/
??? ldr r2, =ARM7_INTPEND?????????? /*R2->interrupt pend register.*/
??? mvn r1, #0????????????????? ??? /*&FFFFFFFF*/
??? str r1, [r2]??????????????? ??????? /*clear all interrupt flags.*/
? ?
/*Part 2*/
/*****************************************************************/
??? ldr r0, =ARM7_SYSCFG
??? ldr r1, =0x87ffffA0???????????? /*config SYSCFG*/
??? str r1, [r0] ?????????????? /*Cache & WB disabled*/????
??
/*part 3*/
/****************************************************************/
/*jump to flash addr exec @16M*/
?
?? ldr?? lr, L$_HiPosn?????? ?????????? /* load lr with the ROM address where */
??????????????????????????????????? /* to jump after remap (this is an??? */
??????????????????????????????????? /* address after 0x20000000)????????? */
?? mov?? pc, lr????????????????????? /* jump to address stored in lr */
?
/*Part 4*/
/****************************************************************/
/*Initalize the memory as followa:*/
/*? FLASH?????????? @ 16? ~ 18 M*/
/*? SDRAM?????????? @? 0? ~ 16M*/
HiPosn:
?
??? ldr r1, =rEXTDBWTH ???????????? /*EXTDBWTH????????? ??????? */
??? ldr r2, =rROMCON0? ???????????? /*ROMCON0?? @ 16M ~ 18M ??? */
??? ldr r3, =rROMCON1?????????????? ??? /*ROMCON1?? @ DISABLED? */
??? ldr r4, =rROMCON2?????????????? ??? /*ROMCON1?? @ DISABLED? */
??? ldr r5, =rROMCON3?????????????? ??? /*ROMCON1?? @ DISABLED? */
??? ldr r6, =rROMCON4?????????????? ??? /*ROMCON1?? @ DISABLED? */
??? ldr r7, =rROMCON5?????????? ??? ??? /*ROMCON1?? @ DISABLED? */
??? ldr r8, =rSDRAMCON0???????????? /*SDRAMCON0 ??? @ 0M ~ 16M? */
??? ldr r9, =rSDRAMCON1???????????? /*SDRAMCON1 ??? @ DISABLED*/
??? ldr r10,=rSDRAMCON2???????????? /*SDRAMCON2 ??? @ DISABLED*/
??? ldr r11,=rSDRAMCON3???????????? /*SDRAMCON3 ??? @ DISABLED*/
??? ldr r12,=rSREFEXTCON???????????
???
??? ldr r0, =ARM7_EXTDBWTH ????????
??? stmia?? r0, {r1-r12}
?
?? /*---------------------------------------------------------------*/
?? /*
??? * Initialize the stack pointer to just before where the
??? * uncompress code, copied from ROM to RAM, will run.
??? */
?? /*---------------------------------------------------------------*/
?
?? ldr?? sp, L$_STACK_ADDR
?? mov?? fp, #0???????? /* zero frame pointer */
?
?? /*----------------------------------------------------------------*/
?? /* jump to C entry point in ROM: routine - entry point + ROM base */
?? /*----------------------------------------------------------------*/
??
?? ldr?? pc,? L$_rStrtInRom /* use ARM mode (no Thumb) */
?
/******************************************************************************/
?
/*
? * PC-relative-addressable pointers - LDR Rn,=sym is broken
? * note "_" after "$" to stop preprocessor preforming substitution
? */
?
??? .balign 4
?
L$_HiPosn:
??? .long?? ROM_TEXT_ADRS + HiPosn - _romInit
?
L$_rStrtInRom:
??? .long?? ROM_TEXT_ADRS + _romStart - _romInit
?
L$_STACK_ADDR:
??? .long?? STACK_ADRS
?
注意:上電以后FLASH將被鏡像到0x00000000處,并開始執行。
這里ROM_TEXT_ADRS的值為0x01000000,當對CPU進行完必要的初始化以后它將跳轉到FLASH的真實地址處進行執行,它繼續完成對SDRAM的初始化,內存布局的分配等等,詳細信息請參看TRACE32那一節。
?
總結
以上是生活随笔為你收集整理的基于S3C4510B的一个简单BSP的开发报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 子夜秋歌的作者是谁啊?
- 下一篇: Ubuntu10.04安装Flash插件