新闻  |   论坛  |   博客  |   在线研讨会
RTEMS在S3C2410上的移植(一)
xiajiashan | 2012-08-29 10:36:25    阅读:2015   发布文章

作者:下家山(转载,请注明)


1:RTEMS开发环境建立


1.1开发环境建立前的准备工作

因为RTEMS开发环境主要用的是GNU的工具链,所以需要一台装有Linux的HOST.

1.2建立GNU工具链的详细步骤可以参考个版本的doc中的start.pdf,或者参考www.rtems.net中ray的rtems连载。
1.3 Load Image

   烧写u-boot到s3c2410 norFlash中(也可以是nandFlash),详见s3c2410开发板套件资料。

烧写成功后,就可以通过FTP下载编译后的bin文件到板子上运行。(小技巧,为了使编译后直接生成bin文件,可以在gp32.cfg文件中做如下修改:

define make-exe

$(LINK.c) $(AM_CFLAGS) $(AM_LDFLAGS) -o $@ \

$(LINK_OBJS) $(LINK_LIBS)

$(OBJCOPY) -O binary $(basename $@).exe $(basename $@).bin

$(NM) -g -n $(basename $@).exe > $(basename $@).elf

$(SIZE) $(basename $@).exe

Endef)

 

By 下家山 Q群 75303301 上海松江文汇路928号258室 松江大学城

 

上海索漫科技 http://www.xiajiashan.com 专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训

2:修改s3c2400==>s3c2410

因为用的是rtems-4.6.99.3自带的bsp(gp32),它针对的cpu是s3c2400,我们要在s3c2410上调试,有很很多需要修改的地方。
2.1 register肯定不同,需要修改

   在s3c2410开发板套件资料的armsys_2410/hardware_test_pro中找到s3c2410.h,与c/src/lib/

libcpu/arm/s3c2410/include中的s3c2400.h进行比较,添加s3c2400中没有的register。

2.2然后从链接脚本入手,(编译器就是通过它来组织code和分配memery的),

所以找到/c/src/lib/libbsp/arm/gp32/startup/linkcmds,修改

sdram : ORIGIN = 0x30000000, LENGTH = 64M



_sdram_base = DEFINED(_sdram_base) ? _sdram_base : 0x30000000;

     _sdram_size = DEFINED(_sdram_size) ? _sdram_size : 64M;

     三个地方。


3:对linkcmds的理解

3.1: ENTRY(_start)这一句很重要,相当与ads中的entry point,既go 命令就从这里开始;_start是一个标号,在c/src/lib/libbsp/arm/gp32/start/start.S中定义.
3.2: section的分配

linkcmds把编译后的bin文件主要分成.base,.text,.data,.bss四个区域load到memery.即:

.base-->0x30000000~0x30000100,主要存放vector table;

.text-->紧接着0x30000100存放,主要存放code;

.data-->紧接着.text,主要存放已被初始化的全局变量;

.bss-->紧接着.data,主要存放没有被初始化的全局变量;(系统自动初始化为0)
4:对start.S的理解(位于c/src/lib/libbsp/arm/gp32/start)

首先找到_start标号,程序往下执行,主要完成以下工作:

 

1.jpg

By 下家山 Q群 75303301 上海松江文汇路928号258室 松江大学城

上海索漫科技 http://www.xiajiashan.com 专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训

 

5:RTEMS 内核是怎么初始化BSP,CPU及各部件的

RTEMS内核的引入主要是根据两个表(结构体):

 
绘图191.jpg
6:多任务怎么开始

RTEMS是通过下面两个函数启动多任务的:

rtems_initialize_executive_early 初始化RTEMS 但是不开始多任务;

rtems_initialize_executive_late 完成初始化开始多任务;

rtems_initialize_executive_early函数原形为:

rtems_interrupt_level rtems_initialize_executive_early(

rtems_configuration_table *configuration_table,

rtems_cpu_table *cpu_[x1] )

其中的两个参数就为上面提到到了两个配置表.调用rtems_initialize_executive_early时将传入BSP_Configuration,Cpu_table这两个表.

rtems_initialize_executive_late的函数原形为:

void rtems_initialize_executive_late(rtems_interrupt_level bsp_level);(见cpukit/sapi/src/Exinit.c)

其入口参数即调用rtems_initialize_executive_early函数的返回值 .


7:系统初始化及多任务开始流程(对应到函数调用顺序)

[x1]见cpukit/sapi/src/Exinit.c

 

 
 
绘图192.jpg
 

8:系统是怎么实现驱动的

rtems是通过一个初始化任务Init来来初始化bsp,cpu,OS的.用户在应用程序中定义了Init任务后,必须得有#define CONFIGURE_INIT这条语句,rtems就是通过判断用户是否定义了#define CONFIGURE_INIT来启动多任务并实现驱动的。

在cpukit/sapi/include/confdefs.h中,系统通过判断用户是否定义了CONFIGURE_INIT来初始化Configuration配置表,Configuration_RTEMS_API配置表.

如果用户应用程序中要用到控制台,通常是串口打印信息则必须在应用程序中定义#define

CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER,

在confdefs.h中,系统通过判断用户是否定义了CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER来初始化串口。

同样,如果用户应用程序中要用到时钟,则必须在应用程序中定义#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER,在confdefs.h中系统通过判断用户是否定义了CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER来初始化clock.

所有的驱动放在一个驱动表结构体中,如confdefs.h中的rtems_driver_address_table Device_drivers,而这个表地址在Configuration配置表中引入.在Device_drivers中放着各驱动的入口如:CONSOLE_DRIVER_TABLE_ENTRY,而CONSOLE_DRIVER_TABLE_ENTRY定义在cpukit/libcsupport/include/console.h中,CONSOLE_DRIVER_TABLE_ENTRY其实是对console一系列函数调用.

注意:上述一切初始化动作是通过在应用程序中预定义的,所以在预编译的时候就初始化了.所以在调用rtems_initialize_executive_early时,通过&BSP_Configuration, &Cpu_table这两个参数可以对BSP,CPU,OS, 各驱动进行初始化。


9:从hello world入手

首先,需要理清console驱动的函数调用关系,其主要流程如下:

 

 
绘图301.jpg

By 下家山 Q群 75303301 上海松江文汇路928号258室 松江大学城

上海索漫科技 http://www.xiajiashan.com 专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训

 

转载:请注明,作者,下家山 请尊重原创!

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
02年接触ARM和ucos,开发过有线和无线图像报警器,IPCamera,人脸识别系统,OCR识别系统,指纹识别系统,05年开始从事Linux及Rtems下WiFi,camera,Ethernet等驱动开发工作,专做嵌入式linux培训,致力于把我十年来的研发经验传授给每一个学员,招人的可以找我,ximenpiaoxue4016@sina.com
推荐文章
最近访客