Contiki 了解(2)-HelloWorld的编译过程

基础知识:

Makefile常用函数:

http://blog.csdn.net/l0605020112/article/details/38944825

strip :去空格函数
$(strip string)
功能:去掉<string>字串中开头和结尾的空字符。
返回:返回被去掉空格的字符串值

$(findstring ,)
名称:查找字符串函数——findstring。
功能:在字串中查找字串。
返回:如果找到,那么返回,否则返回空字符串。

http://blog.csdn.net/liangkaiming/article/details/6267357

1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符

src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )


在user@instant-contiki:~/contiki/examples/hello-world$ 路径中执行make TARGET=srf06-cc26xx BOARD=srf06/cc26xx即可完成helloworld工程的编译,并且输出bin,hex,elf类型可执行文件。

user@instant-contiki:~/contiki/examples/hello-world$ make <span style="color:#ff0000;">TARGET</span>=srf06-cc26xx <span style="color:#ff0000;">BOARD</span>=srf06/cc26xx 

1. 根目录的Makefile

命令中主要是通过执行make命令完成对目标的编译的。

#Makefile:
CONTIKI_PROJECT = hello-world
all: $(CONTIKI_PROJECT)

CONTIKI = ../..
include $(CONTIKI)/Makefile.include

Makefile 中指定输出目标是hello-world,这样就会编译hello-world.c文件。但是要知道helloworld.c中包含的有contiki.h文件,那么就需要指定路径进行索引。并且helloworld文件中的宏定义展开后引申出线程相关的函数。

最后一行,引入contiki目录下的Makefile.include文件,里面包含了大量的内容,逐级展开包含内核、协议栈、处理器相关等内容。

include $(CONTIKI)/Makefile.include

2. Contiki根目录下的Makfile.include文件

2.1 make命令预处理

首先是判断是做了变量的初始化,即make的时候后面跟的TARGET等。
# -*- makefile -*-


ifndef CONTIKI
  ${error CONTIKI not defined! You must specify where Contiki resides}
endif


ifeq ($(TARGET),)
  -include Makefile.target
  ifeq ($(TARGET),)
    ${info TARGET not defined, using target 'native'}
    TARGET=native
  else
    ${info using saved target '$(TARGET)'}
  endif
endif

其中${info xxx},$(warning xxx),$(error xxxx),@echo xxx均为信息打印,其中$后的括号可以是大括号也可以是小括号。

其中feq ($(TARGET),)是说TARGET变量是否为空,即make的时候没有指定此变量。

2.2 预处理结果输出

usage:
        @echo "make MAKETARGETS... [TARGET=(TARGET)] [savetarget] [targets]"

targets:
        @ls -1 $(CONTIKI)/platform $(TARGETDIRS) | grep -v CVS

savetarget:
        -@rm -f Makefile.target
        @echo "saving Makefile.target"
        @echo >Makefile.target "TARGET = $(TARGET)"

savedefines:
        -@rm -f Makefile.$(TARGET).defines
        @echo "saving Makefile.$(TARGET).defines"
        @echo >Makefile.$(TARGET).defines "DEFINES = $(DEFINES)"

这里做一些信息打印,主要是预处理后的信息打印。

@表示后面的是个命令,如echo,ls -l等。

2.3编译所用的主要变量的定义、赋值

OBJECTDIR = obj_$(TARGET)

LOWERCASE = -abcdefghijklmnopqrstuvwxyz
UPPERCASE = _ABCDEFGHIJKLMNOPQRSTUVWXYZ
TARGET_UPPERCASE := ${strip ${shell echo $(TARGET) | sed y!$(LOWERCASE)!$(UPPERCASE)!}}
CFLAGS += -DCONTIKI=1 -DCONTIKI_TARGET_$(TARGET_UPPERCASE)=1


<span style="color:#ff0000;">MODULES </span>+= core/sys core/dev core/lib

OBJECTDIR开始指定了一些非常有用的信息,object变量赋值,Modules变量赋值。第一次定义MODULES变量,并把内核相关文件路径赋值给MODULES。

2.4协议栈的选择

协议栈的定义,根据是否声明了协议栈类型:IPV4,IPV6或Rime。默认是IPV6。
# Include IPv6, IPv4, and/or Rime

HAS_STACK = 0
ifeq ($(CONTIKI_WITH_IPV4),1)
  HAS_STACK = 1
  CFLAGS += -DNETSTACK_CONF_WITH_IPV4=1
  MODULES += core/net/ipv4 core/net/ip
endif

ifeq ($(CONTIKI_WITH_RIME),1)
  HAS_STACK = 1
  CFLAGS += -DNETSTACK_CONF_WITH_RIME=1
  MODULES += core/net/rime
endif

# Make IPv6 the default stack
ifeq ($(HAS_STACK),0)
ifneq ($(CONTIKI_WITH_IPV6),0)
CONTIKI_WITH_IPV6 = 1
endif
endif

ifeq ($(CONTIKI_WITH_IPV6),1)
  CFLAGS += -DNETSTACK_CONF_WITH_IPV6=1
  ifneq ($(CONTIKI_WITH_RPL),0)
        CONTIKI_WITH_RPL = 1
  endif
  MODULES += core/net/ipv6 core/net/ip
endif

ifeq ($(CONTIKI_WITH_RPL),1)
    CFLAGS += -DUIP_CONF_IPV6_RPL=1
    MODULES += core/net/rpl
else
    CFLAGS += -DUIP_CONF_IPV6_RPL=0
endif

2.5 contiki内核、网络协议相关的文件包含

把需要编译的内容放到CONTIKI_OBJECTFILES和PROJECT_OBJECTFILES变量中。然后创建相应的用于存放编译输输出的文件夹,为编译准备环境。这些在执行make clean的时候会被删除,不过加上TARGET BOARD 才行,不然会被默认为native。

<span style="color:#ff0000;">CONTIKI_SOURCEFILES </span>+= $(CONTIKIFILES)
<span style="color:#ff0000;">CONTIKIDIRS </span>+= ${addprefix $(CONTIKI)/core/,dev lib net net/llsec net/mac net/rime \
                 net/rpl sys cfs ctk lib/ctk loader . }

<span style="color:#ff0000;">oname </span>= ${patsubst %.c,%.o,${patsubst %.S,%.o,$(1)}}

<span style="color:#ff0000;">CONTIKI_OBJECTFILES </span>= ${addprefix $(OBJECTDIR)/,${call oname, $(CONTIKI_SOURCEFILES)}}

<span style="color:#ff0000;">PROJECT_OBJECTFILES </span>= ${addprefix $(OBJECTDIR)/,${call oname, $(PROJECT_SOURCEFILES)}}
# Provide way to create $(OBJECTDIR) if it has been removed by make clean
$(OBJECTDIR):        
            mkdir $@
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))

这里不清楚CONTIKIFILES变量在哪里定义的。第一次定义CONTIKI_SOURCEFILES变量CONTIKI_OBJECTFILES变量, PROJECT_OBJECTFILES变量和CONTIKIDIRS变量。定义oname,uniq。

这里addprefix加前缀函数,把contiki所在路径增加到后面的dev lib等前面。

2.6  获取目标平台的makefile文件

target_makefile := $(wildcard $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET) ${foreach TDIR, $(TARGETDIRS), $(TDIR)/$(TARGET)/Makefile.$(TARGET)})

:=为覆盖赋值。$(wildcard)是通配符函数,该句展开所有的Makefile.srf06-cc26xx,并将这些文件赋值为target_makefile变量。


此处应该先了解3~5小节内容。之后再看2.7


2.7  Nothing

懒没有写

3. Makefile.srf06-cc26xx

# srf06-cc26xx platform makefile

ifndef CONTIKI
  $(error CONTIKI not defined! You must specify where CONTIKI resides!)
endif

### Board and BSP selection
ifeq ($(BOARD),)
  BOARD=srf06/cc26xx
endif

CONTIKI_TARGET_DIRS += .

### Include the board-specific makefile
PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET)
-include $(PLATFORM_ROOT_DIR)/$(BOARD)/Makefile.$(notdir $(BOARD))

CONTIKI_TARGET_SOURCEFILES += contiki-main.c
CONTIKI_TARGET_SOURCEFILES += sensors.c leds.c
CONTIKI_TARGET_SOURCEFILES += $(BOARD_SOURCEFILES)

CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES)

CLEAN += *.srf06-cc26xx

### Unless the example dictates otherwise, build with code size optimisations
ifndef SMALL
  SMALL = 0
endif

### Define the CPU directory and pull in the correct CPU makefile. This will
### be defined by one of the makefiles included above and it can be either
### Makefile.cc26xx or Makefile.cc13xx
CONTIKI_CPU=$(CONTIKI)/cpu/cc26xx-cc13xx
include $(CONTIKI_CPU)/Makefile.$(CPU_FAMILY)

MODULES += core/net core/net/mac core/net/mac/contikimac core/net/llsec

这里把Platform路径添加到CONTIKI_TARGET_DIRS,定义了PLATFORM_ROOT_DIR,platform路径下的.c,.h文件增加到CONTIKI_TARGET_SOURCEFILES和CONTIKI_SOURCEFILES。定义CONTIKI_CPU,并将cpu/cc26xx-cc13xx下的makefile文件包含进来。网络协议相关的mac层文件增加到MODULES变量中。

下一步就是看cpu/cc26xx-cc13xx下的makefile的了,可是这里的CPU_FAMILY不知道在哪里定义的,根据注释应该是Makefile.cc26xx。

4. Makefile.cc26xx

这个文件比较简单只有两行
TI_XXWARE_PATH = lib/cc26xxware

include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx
定义变量TI_XXWARE_PATH,并赋值固件路径。包含了Makefile.cc26xx-cc13xx文件。

5. Makefile.cc26xx-cc13xx

因为这个文件与CPU相关,也就是与处理器相关,所以编译相关的很多东西会在这里制定,gcc、编译规则,硬件相关的RAM,Flash配置、堆栈

5.1 gcc设定

CC      = arm-none-eabi-gcc
CPP     = arm-none-eabi-cpp
LD      = arm-none-eabi-gcc
AR      = arm-none-eabi-ar
OBJCOPY = arm-none-eabi-objcopy
OBJDUMP = arm-none-eabi-objdump
NM      = arm-none-eabi-nm
SIZE    = arm-none-eabi-size
SREC_CAT = srec_cat

5.2 固件相关变量定义

CPU_ABS_PATH       = cpu/cc26xx-cc13xx
TI_XXWARE = $(CONTIKI_CPU)/$(TI_XXWARE_PATH)

### cc26xxware sources under driverlib will be added to the MODULES list
TI_XXWARE_SRC = $(CPU_ABS_PATH)/$(TI_XXWARE_PATH)/driverlib

### The directory with startup sources will be added to the CONTIKI_CPU_DIRS
### and the sources therein are added to the sources list explicitly. They are
### also listed explicitly in the linker command (through TARGET_STARTFILES),
### to make sure they always get linked in the image
TI_XXWARE_STARTUP_DIR = $(TI_XXWARE_PATH)/startup_files
TI_XXWARE_STARTUP_SRCS = ccfg.c startup_gcc.c

5.3 指定CPU依赖关系

### CPU-dependent cleanup files
CLEAN += symbols.c symbols.h *.d *.elf *.hex

### CPU-dependent directories
CONTIKI_CPU_DIRS = . dev rf-core rf-core/api $(TI_XXWARE_STARTUP_DIR)

### Use the existing debug I/O in cpu/arm/common
CONTIKI_CPU_DIRS += ../arm/common/dbg-io

### CPU-dependent source files
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c soc-rtc.c uart.c
CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c aux-ctrl.c
CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c adc-sensor.c
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c
CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c
CONTIKI_CPU_SOURCEFILES += rf-core.c rf-ble.c ieee-mode.c
CONTIKI_CPU_SOURCEFILES += random.c soc-trng.c

DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c

CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES)
并将所有依赖文件添加到CONTIKI_SOURCEFILES变量中。

5.4设定编译规则

### Compilation rules
CUSTOM_RULE_LINK=1

%.elf: $(TARGET_STARTFILES) %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(LDSCRIPT)
        $(TRACE_LD)
        $(Q)$(LD) $(LDFLAGS) ${filter-out $(LDSCRIPT) %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -lm -o $@

%.i16hex: %.elf
        $(OBJCOPY) -O ihex $< $@

%.hex: %.i16hex
        $(SREC_CAT) $< -intel -o $@ -intel

%.bin: %.elf
        $(OBJCOPY) $(OBJCOPY_FLAGS) $< $@

%.lst: %.elf
        $(OBJDUMP) $(OBJDUMP_FLAGS) $< > $@

### We don't really need the .hex and .bin for the .$(TARGET) but let's make
### sure they get built
%.$(TARGET): %.elf %.hex %.bin
        cp $< $@

5.5 硬件相关配置

# a target that gives a user-friendly memory profile, taking into account the RAM
# that is statically occupied by the stack as defined in the linker script
# see $(LDSCRIPT)
RAM_SIZE = 0x00003E00
FLASH_SIZE = 0x0001E000
STACK_SIZE = 0
%.size: %.$(TARGET)
        @$(SIZE) -A $< | egrep "data|bss" | awk '{s+=$$2} END {s=s+$(STACK_SIZE); f=$(RAM_SIZE)-s; printf "[RAM]   used %6d, free %6d\n",s,f;}'
        @$(SIZE) -A $< | egrep "text|isr_vector" | awk '{s+=$$2} END {f=$(FLASH_SIZE)-s; printf "[Flash] used %6d, free %6d\n",s,f;}'

ifeq ($(BOARD_SUPPORTS_BSL),1)
%.upload: %.bin
ifeq ($(wildcard $(BSL)), )
        @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?"
else
        $(PYTHON) $(BSL) $(BSL_FLAGS) $<
endif
else
%.upload:
        @echo "This board cannot be programmed through the ROM bootloader and therefore does not support the .upload target."
endif

# Check if we are running under Windows
ifeq ($(HOST_OS),Windows)
  SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-windows
else
ifeq ($(HOST_OS),Darwin)
  SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-macos
else
  # Else assume Linux
  SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-linux
endif
endif

UART_BAUDRATE = 115200

login:
        $(SERIALDUMP) -b$(UART_BAUDRATE) $(PORT)
配置RAM,配置FLash、Stack,串口波特率等与硬件相关内容。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值