在上一节中,我们介绍了如何配置ecos并编译生成静态链接库文件。在此基础上,本节主要介绍如何编译链接生成helloworld程序。
在ecos源码包中,有一个名为examples文件夹,这个文件夹下面展示了几个ecos的应用例子,其中就包括helloworld程序示例。这几个程序示例很好的展示了用户如何开发自己的应用程序。因此,刚接触ecos时,研究这几个实例是大有裨益的,也是学习ecos的一手材料。
1. 关于makefile知识
本节涉及到一点makefile的知识,如果你了解makefile,则本节所述没什么难度;如果不了解的话,也没关系,我会把我最终使用的makefile提供出来,供大家下载使用。
虽如此,从我自己的开发经验来看,如果你想进行ecos开发,仅管深入系统地学习makefile不是必须的,但了解一些makefile的基础知识还是很有必要的,至少一些基础makefile语句要看得懂。
我没有花太多时间来学习makefile,只是项目过程中需要的时候从网络中学习了一些makefile的知识。有的软件架构,如果不了解它的makefile设计的话,你也就不能从根本上了解这个软件的体系架构,这从一定程度上影响了我们自身技术的提高。因此,我说了解一些makefile基础知识是必要,至少一些基础makefile语句要看得懂。另一方面,一般情况下,我们很少要全新写makefile文件,写也只是写一些比较基础、比较简单的makefile文件,因此,在精力有限的情况下,无需要太深入去了解makefile知识。
2. 修改makefile文件
ecos应用实例带有一个makefile文件,而且有该makefile文件的使用说明(见build_Make.params和build_Makefile文件,以及makefile文件本身内部也有一个简单的使用说明)。
2.1 指定环境变量
如果你安装ecos时在环境变量中设置好了ecos的相关变量(如ECOS_REPOSITORY、交叉编译器路径等),则可直接使用该makefile。在我的开发环境中,由于懒得设置这些ecos环境变量,所以在makefile文件中直接定义了。其实,在实际的项目开发中,这种在makefile中指定或定义好相关环境变量更加常见。
2.2 指定生成相关格式的目标文件
ecos应用实例自带的makefile文件,生成的是elf格式的目标文件。在这里,除了生成elf格式目标文件外,我们还指定生成.srec和.bin两种格式的目标文件。这两种文件都是使用交叉编译器中objcopy程序(如arm-eabi-objcopy)把elf格式文件转换而来的。其中,.srec文件叫做S记录文件,该程序文件是GNU二进制文件,包含有应用程序的入口地址和使用的内存范围;.bin文件,我们都很熟悉,可烧写到内部flash中直接运行。
2.3 最终的makefile文件
# Reference to ecos.mak added by John Dallaway, eCosCentric Limited, 2003-01-20
# This file is in the public domain and may be used for any purpose
# Usage: make INSTALL_DIR=/path/to/ecos/install
#INSTALL_DIR=$$(INSTALL_DIR) # override on make command line
#
ECOS_REPOSITORY=/home/reille/02_proj_ecos_stm32/01_source/wokspace/source/ecos/packages
export ECOS_REPOSITORY
INSTALL_DIR=/home/reille/02_proj_ecos_stm32/01_source/wokspace/source/build/2013.1.23/ecos_install
include $(INSTALL_DIR)/include/pkgconf/ecos.mak
ECOS_COMMAND_PREFIX_ := /opt/ecos/gnutools/arm-eabi/bin/arm-eabi-
XCC = $(ECOS_COMMAND_PREFIX_)gcc
XCXX = $(XCC)
XLD = $(XCC)
OBJCOPY = $(ECOS_COMMAND_PREFIX_)objcopy
CFLAGS = -I$(INSTALL_DIR)/include
CXXFLAGS = $(CFLAGS)
LDFLAGS = -nostartfiles -L$(INSTALL_DIR)/lib -Ttarget.ld
# RULES
.PHONY: all clean
all: hello twothreads simple-alarm serial
clean:
-rm -f hello hello.o twothreads twothreads.o
-rm -f simple-alarm simple-alarm.o serial serial.o
-rm -f instrument-test instrument-test.o
-rm -f *.srec
-rm -f *.bin
%.o: %.c
$(XCC) -c -o $*.o $(CFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
%.o: %.cxx
$(XCXX) -c -o $*.o $(CXXFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
%.o: %.C
$(XCXX) -c -o $*.o $(CXXFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
%.o: %.cc
$(XCXX) -c -o $*.o $(CXXFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
hello: hello.o
$(XLD) $(LDFLAGS) $(ECOS_GLOBAL_LDFLAGS) -o $@ $@.o
$(OBJCOPY) -O srec $@ $@.srec
$(OBJCOPY) -O binary $@ $@.bin
twothreads: twothreads.o
$(XLD) $(LDFLAGS) $(ECOS_GLOBAL_LDFLAGS) -o $@ $@.o
$(OBJCOPY) -O srec $@ $@.srec
simple-alarm: simple-alarm.o
$(XLD) $(LDFLAGS) $(ECOS_GLOBAL_LDFLAGS) -o $@ $@.o
$(OBJCOPY) -O srec $@ $@.srec
serial: serial.o
$(XLD) $(LDFLAGS) $(ECOS_GLOBAL_LDFLAGS) -o $@ $@.o
$(OBJCOPY) -O srec $@ $@.srec
instrument-test: instrument-test.o
$(XLD) $(LDFLAGS) $(ECOS_GLOBAL_LDFLAGS) -o $@ $@.o
$(OBJCOPY) -O srec $@ $@.srec
上面的makefile中,你需要把ECOS_REPOSITORY和INSTALL_DIR修改为你的路径即可。
3. 修改hello.c程序文件
在ecos中,应用程序的入口不像我们一般编写程序时所用的main()函数,而是cyg_user_start()函数。因此,需要对ecos应用实例中helloworld程序即hello.c程序文件进行修改下才能使用。我修改后的代码如下:
#include <cyg/kernel/kapi.h> #include <stdlib.h> /* this is a simple hello world program */ #include <stdio.h> int main(void) { static int i = 0; printf("Hello, eCos world! [i = %lu] \n", i++); return 0; } void cyg_user_start(void) { printf("Start...\n"); printf("Entering Hello' cyg_user_start() function\n"); printf("-----------------------------\n\n"); while(1) { main(); printf("-----------------------------\n\n"); hal_delay_us(1 * 1000 * 1000); } }
4. 编译链接生成目标映像文件
完成上述步骤后,在examples目录下执行make编译所有示例程序,或者执行make hello单独编译helloworld示例程序。编译完成后生成最终目标映像文件,其中,helloworld除生成.srec文件包,还将生成.bin文件。你可根据需要修改makefile文件得到所需要的目标映像文件。
推荐阅读相关文章:
- stm32移植ecos #7,移植ecos并成功运行helloworld程序,配置编译生成静态链接库文件
- stm32移植ecos #11,使用自己的模板(Template)
- stm32移植ecos #10,移植ecos并成功运行helloworld程序,烧写到内部flash直接运行helloworld程序
- stm32移植ecos #9,移植ecos并成功运行helloworld程序,使用redboot引导运行内存中的helloworld程序
- stm32移植ecos #21,触摸屏tsc2046驱动移植
- stm32移植ecos系列文章归档
- stm32移植ecos #13,redboot引导启动flash中的应用程序映像文件(下)
- stm32移植ecos #12,redboot引导启动flash中的应用程序映像文件(上)
试了好多次,每次都在make的时候出错,makefile就直接用你教程上的那个,只改了路径。
错误提示:
/Workspace/ecos/redboot_stm32f4/redboot_stm32f4_install/lib/libtarget.a(redboot_main.o): In function `cyg_start’:
/home/pchom/Workspace/ecos_eclipse/ecos_code/ecos/packages/redboot/current/src/main.c:454: undefined reference to `RedBoot_version’
collect2: ld returned 1 exit status
makefile:55: recipe for target ‘hello’ failed
make: *** [hello] Error 1
不用makefile,直接用gcc编译也是这个错误。。弄了两天没弄出来。求解。。。
reboot/current/src/version.c没有被编译进去导致的问题。这里可以配置,也可以指直接修改下面的makefile文件。
郭兄弟,你好!看到你介绍ecos的文章,非常感兴趣,但有几个地方看不明白,想请教一下:
1. 下面的两条makefile语句中,是制定源代码的存放路径么?具体语法是怎样的,可否就针对这两条语句做个简单的介绍!
ECOS_REPOSITORY=/home/reille/02_proj_ecos_stm32/01_source/wokspace/source/ecos/packages
export ECOS_REPOSITORY
INSTALL_DIR=/home/reille/02_proj_ecos_stm32/01_source/wokspace/source/build/2013.1.23/ecos_install
2. 下面这个语句是作何用途呢?
OBJCOPY = $(ECOS_COMMAND_PREFIX_)objcopy