RTEMS 4.9.5 在 MINI2440 QEMU的移植


在看本文之前,大家还是要先补习一下看看什么是RTEMS。

对RTEMS感兴趣,源于我对ecos的microwindows的移植,看到里面有这个字符串,

等我从网络搜索到的时候,才发现是一个评分比vxwork还高的嵌入式系统,对于RTEMS的学习本人还在继续。

本文只是入门级别的移植文章,走运的是基本移植成功。

我只是通过patch的方式罗列了一下移植过程,很多技术细节还需要和网友们一起推敲,欢迎大家质疑,我会及时回复。

1. 移植怎么开始

既然是移植,就是把其他地方生长好的枝叶剪裁并且嫁接到新的地方。

有了ecos的经验,就知道smdk2410到mini2440比较容易。

我依旧很走运,在RTEMS的bsp中找到了smdk2410的影子。

于是,剪切复制为mini2440,本人不喜欢在原smdk2410的上面去改代码,

索性直接把创建的mini2440的目录里面的所有smdk2410的信息全部更新为mini2440。

然后,我开始安装,

cd /rtems/rtems-4.9.5/rtems-4.9

./bootstrap -c

./bootstrap

cd ~/rtems/rtems-4.9.5/rtems-build

~/rtems/rtems-4.9.5/rtems-4.9/configure --target=arm-rtems4.9 --disable-posix --disable-itron --disable-cxx --enable-networking --enable-rtemsbsp="mini2440" --enable-tests=samples --prefix=/opt/rtems-4.9

结果当然是失败的,因为config的过程就提示我的mini2440 不是有效的bsp,于是淡定了下来。

阅读New BSP porting的文档。

2.MINI2440 BSP的框架搭建

首先创建 mini2440 cfg文件

--------------------------- make/custom/mini2440.cfg ---------------------------

new file mode 100644

index 0000000..390cdab

@@ -0,0 +1,20 @@

+#

+#  Config file for ARM smdk2410

+#

+#  $Id: smdk2410.cfg,v 1.1 2008/05/06 20:59:23 joel Exp $

+#

+

+include $(RTEMS_ROOT)/make/custom/default.cfg

+

+RTEMS_CPU=arm

+RTEMS_CPU_MODEL=s3c2410

+

+# This is the actual bsp directory used during the build process.

+RTEMS_BSP_FAMILY=mini2440

+

+#  This contains the compiler options necessary to select the CPU model

+#  and (hopefully) optimize for it.

+CPU_CFLAGS = -mcpu=arm920t -DCPU_S3C2410 -mstructure-size-boundary=32

+

+# optimize flag: typically -O2

+CFLAGS_OPTIMIZE_V = -O2 -g

在Make file中添加

------------------------------- make/Makefile.am -------------------------------

index 1649992..8e863f6 100644

@@ -34,6 +34,6 @@ EXTRA_DIST += custom/Cygwin-posix.cfg custom/FreeBSD-posix.cfg \

     custom/ods68302.cfg custom/pc386.cfg custom/posix.cfg \

     custom/psim.cfg custom/rtl22xx.cfg custom/score603e.cfg \

     custom/shsim.cfg custom/ts_386ex.cfg custom/nds.cfg \

-    custom/smdk2410.cfg

+    custom/smdk2410.cfg custom/mini2440.cfg

BSP中的添加

---------------------- c/src/lib/libbsp/arm/acinclude.m4 ----------------------

index 435840f..d8e1d51 100644

@@ -12,6 +12,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR],

     AC_CONFIG_SUBDIRS([gba]);;

   gp32 )

     AC_CONFIG_SUBDIRS([gp32]);;

+  mini2440 )

+    AC_CONFIG_SUBDIRS([mini2440]);;

   nds )

     AC_CONFIG_SUBDIRS([nds]);;

   rtl22xx )

好了,现在可以用configure命令看到可以用的mini2440的bsp了,稍微有点欣慰, 直接用qemu run下,:-),失败咯不停的复位。 3. 针对MINI2440的修改 需要对bss清零 修改makefile.am, 需要用自己的start.S ----------------- c/src/lib/libbsp/arm/mini2440/start/start.S ----------------- + /* zero the bss */ +        ldr     r1, =_axf_bss_end +        ldr     r0, =_axf_bss_start + +_bss_init: +        mov     r2, #0 +        cmp     r0, r1 +        strlot  r2, [r0], #4 +        blo     _bss_init        /* loop while r0 < r1 */ + 修改makefile.am, 需要用自己的bsp.h 对pll的修改 ----------------- c/src/lib/libbsp/arm/mini2440/include/bsp.h ----------------- + +/* What is the input clock freq in hertz? */ +#define BSP_OSC_FREQ  12000000    /* 12 MHz oscillator */ +#define M_MDIV 92 /* FCLK=133Mhz */ +#define M_PDIV 1 +#define M_SDIV 1 +#define M_CLKDIVN 5 /* HCLK=FCLK/2, PCLK=FCLK/2 */ + +#define REFEN 0x1 /* enable refresh */ +#define TREFMD 0x0 /* CBR(CAS before RAS)/auto refresh */ +#define Trp 0x0 /* 2 clk */ +#define Trc 0x3 /* 7 clk */ +#define Tchr 0x2 /* 3 clk */ + 修改makefile.am, 需要用自己的bspstart.c 对分频和uart资源的修改 --------------- c/src/lib/libbsp/arm/mini2440/startup/bspstart.c --------------- +    /* setup clocks */ +    rCLKDIVN=M_CLKDIVN; +    rMPLLCON=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV); +    /* setup rREFRESH */ +    REFCNT=1113;/*2048+1-(15.6*get_HCLK()/1000000);*/ /* period=15.6 us, HCLK=66Mhz, (2048+1-15.6*66) */ +    rREFRESH=((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT); 修改makefile.am, 需要用自己的uart.c ----------------- c/src/lib/libbsp/arm/mini2440/console/uart.c ----------------- +/* Set up the UART. */ +static void uart_init(int minor) +{ + int i; + unsigned int reg = 0; + bsp_start(); + + /* enable UART0 */ + rCLKCON|=0x0100; + + /* value is calculated so : (int)(PCLK/16./baudrate) -1 */ + reg = get_PCLK() / (16 * 38400) - 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 = 0x245; + rUBRDIV0 = reg; + + for (i = 0; i < 100; i++); + +} 到这里应该可以用qemu配合arm-rtems4.9-gdb 来加载和运行RTEMS的应用程序了。 4. 为了配合测试程序,加入reset的提示 --------------- c/src/lib/libbsp/arm/mini2440/startup/bspclean.c --------------- + + +#include <stdio.h> +#include <bsp.h> +#include <rtems/bspIo.h> +#include <rtems/libio.h> + +int uart_poll_read(int); + +void rtemsReboot (void) +{ +  asm volatile ("b _start"); +} + +void bsp_cleanup(void) +{ +  static   char line[]="\nEXECUTIVE SHUTDOWN! Any key to reboot..."; +  /* +   * AT this point, the console driver is disconnected => we must +   * use polled output/input. This is exactly what printk +   * does. +   */ +  printk("\n"); +  printk(line); +  while (uart_poll_read(0) < 0) continue; + +  rtemsReboot(); +}

相关内容