RTEMS 移植到 sbc2440 的笔记

上次到简要笔记,是在虚拟机上面实现到。由于最近在PC上安装来 centOS 6.3 于是将移植重新做了一次,搞来一个晚上,这次将详细一点到移植过程。

我的开发板是 sbc2440,仿真器用jlink v8 配合openocd,系统是 CentOS 6.3 X64,项目编辑使用 eclipse,串口软件使用 minicom


注意,以下到文章移植对 2440 都是通用的。但是,如果是仿真的话,就需要修改了,因为我使用到 sbc2440 的SDRAM和 mini2440 的不同。所以 gdb 初始化

脚本你必须修改为你的板子适配的数据,否则装载不进去SDRAM的话,就什么都没用了。


阅读的前提是你有C语言基础。有makefile基础,至少稍微折腾过linux,否则的话,最好不要搞RTEMS,这不是一般人能搞的,因为资料太少了,

必须靠悟性,自己从代码中学习,从仅有到英文文档中学习。good luck


解压缩
删除libbsp 和 libcpu 下面多余的,除了 share 和 no cpu 目录

libbsp/arm/acinclude.m4 文件中添加表示增加bsp我是只剩下以下的分支
  sbc2440 )
    AC_CONFIG_SUBDIRS([sbc2440]);;

复制 smdk2410 目录为 sbc2440

将 gp32 目录下的 console smc start 目录复制过来, include 目录下的文件也复制过来覆盖掉原来的。
startup/bspstart.c 也复制过来。

sbc2440 目录下的 makefile.am
凡是有 gp32 的都修改过来
include_HEADERS = ../gp32/include/bsp.h
include_HEADERS += ../gp32/smc/smc.h
libbspstart_a_SOURCES = ../gp32/start/start.S
 ../gp32/startup/bspstart.c
libbsp_a_SOURCES += ../gp32/console/uart.c
libbsp_a_SOURCES += ../gp32/smc/smc.c ../gp32/smc/smc.h

/make/custom/目录下的文件修改为 sbc2440.cfg

需要网络和posix,itron和c++都不需要。

$ cd rtems-4.10.2
$ ./bootstrap -c
$ ./bootstrap
$ ./bootstrap -p

$ ../rtems-4.10.2/configure --target=arm-rtems4.10 --enable-posix --disable-cxx --disable-itron --enable-networking --enable-rtemsbsp=sbc2440

应该能编译通过,不通过的话则检查前面哪部份搞错了。

建立 eclipse 项目加入rtems


五,修改源代码让代码跑起来。
由于2410的寄存器基本吻合,所以头文件不改也没问题

我主要是修改了时钟(PLL设置)和串口

libcpu\arm\s3c24xx\clock\support.c
修改get_FCLK
由于2440 的PLL计算公式不同,在原来的基础上乘以2 就行了。修改为
 return((BSP_OSC_FREQ * m * 2) / (p << s));

libbsp\arm\sbc2440\start\start.S

删除 GamePark magic sequence
修改启动代码,我是用GDB的话,则会根据ELF文件自动下载的,RTEMS 的运行地址是 0x30000100 添加初始化
1,关闭看门狗,关闭所有中断,SVC模式
2,设置PLL,将 FCLK : HCLK : PCLK 设置为 200 : 100 : 50 MHZ
3,清除 .bss 段的内容。
4,接着做RTEMS 原来的初始化

添加到内容如下
        /*
         * Etual add
         */
#define WTCON        0x53000000
#define INTMSK         0x4A000008
#define INTSUBMSK     0x4A00001C

        /*
         * watching dog off
         */
        ldr     r0, =WTCON
        mov     r1, # 0x0
        str     r1, [r0]

        /*
         * mask all IRQs by setting all bits in the INTMR - default
         */
        mov     r1, # 0xffffffff
        ldr     r0, =INTMSK
        str     r1, [r0]

        ldr     r1, =0x7ff
        ldr     r0, =INTSUBMSK
        str     r1, [r0]

        /*
         * FCLK:HCLK:PCLK = 1:2:4
         * default OSC = 12MHZ
         * FCLK : HCLK : PCLK = 200 : 100 : 50 MHZ
         */
        mov     r1, # 0x4C000000
        adr     r2, pll_cfg_val
        add     r3, r1, # 7*4
1:
        ldr     r4, [r2], #4
        str     r4, [r1], #4
        cmp     r1, r3
        bne     1b

        mrc     p15, 0, r1, c1, c0, 0
        orr     r1, r1, #0xc0000000
        mcr     p15, 0, r1, c1, c0, 0

        b       clear_bss

pll_cfg_val:
        .long   0xFFFFFFFF              @LOCKTIME 0x4C000000
        .long   0x0005C012              @MPLLCON
        .long   0x00038021              @UPLLCON
        .long   0x001FFFF0              @CLKCON
        .long   0x00000004              @CLKSLOW
        .long   0x00000003              @CLKDIVN
        .long   0x00000000              @CAMDIVN

        /*
         * clear .bss
         */
clear_bss:
        ldr     r0, =_axf_bss_start
        ldr     r1, =_axf_bss_end
        mov     r2, #0x00000000
        b       clbss_2
clbss_l:
        str     r2, [r0]
        add     r0, r0, #4
clbss_2:
        cmp     r0, r1
        bne     clbss_l



\c\src\lib\libbsp\arm\sbc2440\console\uart.c

static ssize_t uart_write(int minor, const char *buf, size_t len)
函数下修改这里:
            while(!(rUTRSTAT0 & 0x4)) {

初始化函数不使用FIFO直接使用死循环模式。
static void uart_init(int minor)
{
    int i;
    unsigned int reg = 0;

    rGPHCON  |= 0xa0;
    rGPHUP   = 0x0c;

    /* enable UART0 */
    rCLKCON|= (1<<10);

    /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
    reg = get_PCLK() / (16 * 115200) - 1;

    /* FIFO enable, Tx/Rx FIFO clear */
    rUFCON0 = 0x0;
    rUMCON0 = 0x0;
    /* Normal,No parity,1 stop,8 bit */
    rULCON0 = 0x3;
    /*
     * tx=level,rx=edge,disable timeout int.,enable rx error int.,
     * normal,interrupt or polling
     */
    rUCON0 = 0x05;
    rUBRDIV0 = reg;

    for (i = 0; i < 100; i++);
}

主要修改 UART0 口的初始化就行了,不用FIFO,主要发送的时候判断

sbc2440/startup/bspstart.c 屏蔽掉设置时钟频率,设置SDRAM控制器到代码,因为时钟已经在 start。S 中做了。
而内存控制器在gdb的启动脚本中做,在debug开发不许要设置。
bsp_start_default 函数中
  /* setup clocks */
//  rCLKDIVN = M_CLKDIVN;
//  rMPLLCON = ((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV);
  /* setup rREFRESH
   * period = 15.6 us, HCLK=66Mhz, (2048+1-15.6*66)
   */
//  REFCNT   = 2048+1-(15.6*get_HCLK()/1000000);
//  rREFRESH = ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT);


完成之后 make install 安装


然后用 eclipse 建立 demo 项目,将hello world的代码copy过来。

gdbinit 到内容如下
target remote localhost:3333
monitor reset
monitor halt
 
#MEMCTRL
#bank3 cs8900
#REFRESH 2^11 + 1 - HCLK* 7.8 = 1269 = 4F5
monitor mww 0x48000000  0x2201D110
monitor mww 0x48000004  0x00000700
monitor mww 0x48000008  0x00000700        
monitor mww 0x4800000c  0x00000700
monitor mww 0x48000010  0x00001F4C       
monitor mww 0x48000014  0x00000700
monitor mww 0x48000018  0x00000700
monitor mww 0x4800001C  0x00018005
monitor mww 0x48000020  0x00018005
monitor mww 0x48000024  0x008C04F5       
monitor mww 0x48000028  0x000000B1
monitor mww 0x4800002C  0x00000030
monitor mww 0x48000030  0x00000030
 
#break main
load
#continue


openocd 的配置脚本如下 s3c2440.cfg
openocd -f s3c2440.cfg 调用

# Target configuration for the Samsung 2440 system on chip
# Tested on a S3C2440 Evaluation board by keesj
# Processor       : ARM920Tid(wb) rev 0 (v4l)
# Info:   JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)

interface jlink

set _CHIPNAME s3c2440

set _ENDIAN little

set _CPUTAPID 0x0032409d

#jtag scan chain
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm920t

$_TARGETNAME configure -work-area-phys 0x200000 -work-area-size 0x4000 -work-area-backup 1

#reset configuration
reset_config trst_and_srst

adapter_khz 6000

第一阶段移植完毕 hello world 已经正常显示了。
接着就要做到是添加 2440,而不用原来到 2410

/libcpu/arm/s3c24xx/
复制 s3c2410.h 修改为 s3c2440.h
修改名字,例如 rWTCON 修改为 WTCON
将后面没用的那些定义去除。

s3c24xx.h 中添加
#elif defined CPU_S3C2440
#include<s3c2440.h>

/libbsp/arm/sbc2440/make/custom/sbc2440.cfg
RTEMS_CPU=arm
RTEMS_CPU_MODEL=s3c2440

CPU_CFLAGS = -mstructure-size-boundary=32 -mcpu=arm920t -mfpu=vfp -mfloat-abi=soft -DCPU_S3C2440

/libcpu/arm/s3c34xx/irq/irq.h
添加 2440 到分支

/libbsp/arm/sbc2440/smc/smc.c 中
#ifdef CPU_S3C2440
#define rPBDAT GPBDAT
#define rPBCON GPBCON
#define rPDDAT GPDDAT
#define rPEDAT GPEDAT
#endif


/libcpu/arm/configure.ac
添加 2440 分支

Makefile.am 添加 2440分支
if s3c24xx
include_HEADERS = s3c24xx/include/s3c24xx.h s3c24xx/include/s3c2400.h s3c24xx/include/s3c2410.h s3c24xx/include/s3c2440.h


/libcpu/arm/Makefile.in
增加所有 2440分支

编译到过程中有很多错误,只需要根据提示,修改 libbsp  libcpu 目录下面所有文件里面的寄存器定义。还有 S3C2440.H 的内容。


Etual

2012-12-23

你可能感兴趣的:(RTEMS 移植到 sbc2440 的笔记)