"); //-->
作者:下家山(转载,请注明)
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标号,程序往下执行,主要完成以下工作:
By 下家山 Q群 75303301 上海松江文汇路928号258室 松江大学城
上海索漫科技 http://www.xiajiashan.com 专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训
5:RTEMS 内核是怎么初始化BSP,CPU及各部件的
RTEMS内核的引入主要是根据两个表(结构体):
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
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驱动的函数调用关系,其主要流程如下:
By 下家山 Q群 75303301 上海松江文汇路928号258室 松江大学城
上海索漫科技 http://www.xiajiashan.com 专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训
转载:请注明,作者,下家山 请尊重原创!
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。
eleaction01 阅读:4512