Added elfloader machine dependent code for STM32W.

This commit is contained in:
salvopitru 2010-12-15 11:10:20 +00:00
parent ced88c2eff
commit 5fe80dd99d
3 changed files with 230 additions and 36 deletions

View file

@ -16,7 +16,7 @@ CONTIKI_CPU=$(CONTIKI)/cpu/stm32w108
CONTIKI_CPU_DIRS = . dev hal simplemac hal/micro/cortexm3 hal/micro/cortexm3/stm32w108
STM32W_C = leds-arch.c leds.c clock.c watchdog.c uart1.c uart1-putchar.c slip_uart1.c \
STM32W_C = leds-arch.c leds.c clock.c watchdog.c uart1.c uart1-putchar.c slip_uart1.c slip.c\
stm32w-radio.c stm32w_systick.c uip_arch.c rtimer-arch.c adc.c micro.c sleep.c \
micro-common.c micro-common-internal.c clocks.c mfg-token.c nvm.c flash.c rand.c
@ -29,6 +29,11 @@ else
STM32W_C += crt_stm32w108.c
endif
ifdef ELF_LOADER
ELFLOADER = elfloader-arch.c symtab.c
endif
# .s and .s79 not specified here because in Makefile.include only .c and .S suffixes are replaced with .o.
CONTIKI_TARGET_SOURCEFILES += $(STM32W_C) \
$(SYSAPPS) $(ELFLOADER) \
@ -55,7 +60,9 @@ AS = iasmarm
AR = iarchive
OBJCOPY = ielftool
STRIP = strip
ifndef DEBUG
OPTI = -Ohz --no_unroll
endif
CFLAGSNO = --endian=little --cpu=Cortex-M3 -e --diag_suppress Pa050 -D BOARD_HEADER=\"board.h\" \
-D BOARD_MB851 -D "PLATFORM_HEADER=\"hal/micro/cortexm3/compiler/iar.h\"" -D CORTEXM3 \
-D CORTEXM3_STM32W108 -D PHY_STM32W108XX -D DISABLE_WATCHDOG -D ENABLE_ADC_EXTENDED_RANGE_BROKEN \
@ -73,14 +80,18 @@ OBJOPTS = --bin
else
# GCC
CC = arm-none-eabi-gcc
CC = arm-none-eabi-gcc
LD = arm-none-eabi-gcc
AS = arm-none-eabi-gcc
AS = arm-none-eabi-gcc
NM = arm-none-eabi-nm
AR = arm-none-eabi-ar
OBJCOPY = arm-none-eabi-objcopy
STRIP = arm-none-eabi-strip
SIZE = arm-none-eabi-size
OPTI = -Os -ffunction-sections -fshort-enums
SIZE = arm-none-eabi-size
ifndef DEBUG
OPTI = -Os -ffunction-sections
endif
CFLAGSNO = -mthumb -mcpu=cortex-m3 -fsigned-char -D "PLATFORM_HEADER=\"hal/micro/cortexm3/compiler/gnu.h\"" \
-D BOARD_HEADER=\"board.h\" -g -Wall -Wno-strict-aliasing -mlittle-endian \
-D BOARD_MB851 -D CORTEXM3 -D CORTEXM3_STM32W108 -D PHY_STM32W108XX -D DISABLE_WATCHDOG -D ENABLE_ADC_EXTENDED_RANGE_BROKEN \
@ -94,27 +105,34 @@ LDFLAGS += -mcpu=cortex-m3 \
-Wl,-static \
-u Default_Handler \
-nostartfiles \
-Wl,-Map -Xlinker contiki-$(TARGET).map \
-Wl,--gc-sections
-Wl,-Map -Xlinker contiki-$(TARGET).map
ifndef ELF_LOADER
# Do not use garbage collection when the elfloader is used.
LDFLAGS += -Wl,--gc-sections
endif
SIZEFLAGS = -A
OBJOPTS = -O binary
endif
ifdef COFFEE_FILES #if files are defined force definition of COFFEE_ADDRESS
ifndef COFFEE_ADDRESS
COFFEE_ADDRESS=0x8010000
endif
COFFEE_ADDRESS1 = $(shell echo $$(( $(COFFEE_ADDRESS) + 1 )))
CONTIKI_TARGET_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c
CFLAGS += -DCOFFEE_FILES=$(COFFEE_FILES) -DCOFFEE_ADDRESS=$(COFFEE_ADDRESS)
ifdef IAR
LDFLAGS+= --config $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/iar-cfg-coffee.icf
else
LDFLAGS+= -Wl,--section-start=.coffeefiles=$(COFFEE_ADDRESS)
endif
ifndef IAR
ifdef COFFEE_ADDRESS
COFFEE = 1
endif
# Default values for coffee section start.
ifndef COFFEE_ADDRESS
COFFEE_ADDRESS = 0x8010c00
endif
ifeq ($(COFFEE),1)
CONTIKI_TARGET_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c
CFLAGS += -DCOFFEE_ADDRESS=$(COFFEE_ADDRESS)
#If $make invokation passed starting address use phony target to force synchronization of source to .coffeefiles section
#Warning: recompilation will not be forced if the starting address is then dropped, with dire consequences:
# -->Source that uses COFFEE_FILES and read macros for conditional compilation will be left hanging!
@ -127,11 +145,24 @@ ifdef COFFEE_FILES #if files are defined force definition of COFF
$(OBJECTDIR)/cfs-coffee-arch.o : coffee #cfs-coffee-arch uses COFFEE_FILES, COFFEE_ADDRESS
$(OBJECTDIR)/cfs-coffee.o : coffee #core routine requires recompilation
#endif
#endif
else
# Coffee starts at the end of the flash, before NVM section.
COFFEE_ADDRESS = 0x801F400
endif
LDFLAGS+= -Wl,--section-start=.coffee=$(COFFEE_ADDRESS)
else #IAR
ifeq ($(COFFEE),1)
LDFLAGS+= --config $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/iar-cfg-coffee.icf
endif
endif
FLASHER = $(CONTIKI)/tools/stm32w/stm32w_flasher/linux/stm32w_flasher
# Check if we are running under Windows
@ -172,6 +203,7 @@ else
SEDCOMMAND = sed -e '1s,\($(OBJECTDIR)\\$*\)\.o:,\1.o : ,g' -e '1!s,\($(OBJECTDIR)\\$*\)\.o:, ,g' -e 's,\\\([^ ]\),/\1,g' -e 's,$$, \\,' -e '$$s, \\$$,,' < $(@:.o=.P) > $(@:.o=.d)
endif
CUSTOM_RULE_C_TO_OBJECTDIR_O = 1
$(OBJECTDIR)/%.o: %.c
$(CC) $(CFLAGS) $< --dependencies=m $(@:.o=.P) -o $@
@ -183,9 +215,26 @@ CUSTOM_RULE_C_TO_CO = 1
$(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@
else #IAR
CUSTOM_RULE_C_TO_CE = 1
%.ce: %.c
$(CC) $(CFLAGS) -fno-merge-constants -fno-function-sections -DAUTOSTART_ENABLE -c $< -o $@
$(STRIP) --strip-unneeded -g -x $@
CUSTOM_RULE_LINK = 1
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a
.PHONY: symbols.c symbols.h
ifdef CORE
ifeq ($(wildcard $(CORE)),)
${error $(CORE) doesn't exist}
endif
symbols.c:
$(NM) $(CORE) | awk -f $(CONTIKI)/tools/mknmlist > symbols.c
else
symbols.c symbols.h:
@$(CONTIKI)/tools/make-empty-symbols
endif
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(OBJECTDIR)/symbols.o
$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} -Wl,-\( ${filter %.a,$^} $(TARGET_LIBFILES) -Wl,-\) -o $@
@echo >> contiki-$(TARGET).map
@$(SIZE) $(SIZEFLAGS) $@ >> contiki-$(TARGET).map

View file

@ -0,0 +1,141 @@
#include "contiki.h"
#include "elfloader-arch.h"
#include "cfs-coffee-arch.h"
#if 1
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) do {} while (0)
#endif
#define ELF32_R_TYPE(info) ((unsigned char)(info))
/* Supported relocations */
#define R_ARM_ABS32 2
#define R_ARM_THM_CALL 10
/* Adapted from elfloader-arm.c */
static uint32_t datamemory_aligned[(ELFLOADER_DATAMEMORY_SIZE+3)/4]; //word aligned
static uint8_t* datamemory = (uint8_t *)datamemory_aligned;
VAR_AT_SEGMENT (static const uint16_t textmemory[ELFLOADER_TEXTMEMORY_SIZE/2],".elf_text") = {0}; //halfword aligned
/*---------------------------------------------------------------------------*/
void *
elfloader_arch_allocate_ram(int size)
{
if(size > sizeof(datamemory_aligned)){
PRINTF("RESERVED RAM TOO SMALL\n");
}
return datamemory;
}
/*---------------------------------------------------------------------------*/
void *
elfloader_arch_allocate_rom(int size)
{
if(size > sizeof(textmemory)){
PRINTF("RESERVED FLASH TOO SMALL\n");
}
return (void *)textmemory;
}
/*---------------------------------------------------------------------------*/
#define READSIZE sizeof(datamemory_aligned)
void elfloader_arch_write_rom(int fd, unsigned short textoff, unsigned int size, char *mem)
{
int32u ptr;
int nbytes;
cfs_seek(fd, textoff, CFS_SEEK_SET);
cfs_seek(fd, textoff, CFS_SEEK_SET);
for(ptr = 0; ptr < size; ptr += READSIZE) {
/* Read data from file into RAM. */
nbytes = cfs_read(fd, (unsigned char *)datamemory, READSIZE);
/* Write data to flash. */
stm32w_flash_write((int32u)mem, datamemory, nbytes);
}
}
/*---------------------------------------------------------------------------*/
void elfloader_arch_relocate(int fd,
unsigned int sectionoffset,
char *sectionaddr,
struct elf32_rela *rela, char *addr)
{
unsigned int type;
type = ELF32_R_TYPE(rela->r_info);
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
/* PRINTF("elfloader_arch_relocate: type %d\n", type); */
/* PRINTF("Addr: %p, Addend: %ld\n", addr, rela->r_addend); */
switch(type) {
case R_ARM_ABS32:
{
int32_t addend;
cfs_read(fd, (char*)&addend, 4);
addr += addend;
cfs_seek(fd, -4, CFS_SEEK_CUR);
cfs_write(fd,&addr,4);
//elfloader_output_write_segment(output,(char*) &addr, 4);
PRINTF("%p: addr: %p\n", sectionaddr +rela->r_offset,
addr);
}
break;
case R_ARM_THM_CALL:
{
uint16_t instr[2];
int32_t offset;
char *base;
cfs_read(fd, (char*)instr, 4);
cfs_seek(fd, -4, CFS_SEEK_CUR);
/* Ignore the addend since it will be zero for calls to symbols,
and I can't think of a case when doing a relative call to
a non-symbol position */
base = sectionaddr + (rela->r_offset + 4);
if (((instr[1]) & 0xe800) == 0xe800) {
/* BL or BLX */
if (((uint32_t)addr) & 0x1) {
/* BL */
instr[1] |= 0x1800;
} else {
#if defined(__ARM_ARCH_4T__)
return ELFLOADER_UNHANDLED_RELOC;
#else
/* BLX */
instr[1] &= ~0x1800;
instr[1] |= 0x0800;
#endif
}
}
/* Adjust address for BLX */
if ((instr[1] & 0x1800) == 0x0800) {
addr = (char*)((((uint32_t)addr) & 0xfffffffd)
| (((uint32_t)base) & 0x00000002));
}
offset = addr - (sectionaddr + (rela->r_offset + 4));
PRINTF("elfloader-arm.c: offset %d\n", (int)offset);
if (offset < -(1<<22) || offset >= (1<<22)) {
PRINTF("elfloader-arm.c: offset %d too large for relative call\n",
(int)offset);
}
/* PRINTF("%p: %04x %04x offset: %d addr: %p\n", sectionaddr +rela->r_offset, instr[0], instr[1], (int)offset, addr); */
instr[0] = (instr[0] & 0xf800) | ((offset>>12)&0x07ff);
instr[1] = (instr[1] & 0xf800) | ((offset>>1)&0x07ff);
cfs_write(fd,&instr,4);
//elfloader_output_write_segment(output, (char*)instr, 4);
/* PRINTF("cfs_write: %04x %04x\n",instr[0], instr[1]); */
}
break;
default:
PRINTF("elfloader-arm.c: unsupported relocation type %d\n", type);
}
}

View file

@ -13,7 +13,7 @@ GROUP(
These are used by the startup in order to allocate stacks for the different modes.
*/
__Stack_Size = 0x400 ;
__Stack_Size = 0x500 ;
PROVIDE ( _Stack_Size = __Stack_Size ) ;
@ -28,7 +28,6 @@ There will be a link error if there is not this amount of RAM free at the end.
_Minimum_Stack_Size = 0x500 ;
/*
this sends all unreferenced IRQHandlers to reset
*/
@ -114,13 +113,24 @@ SECTIONS
*(.rodata*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
. = ALIGN(1024);
*(.elf_text)
. = ALIGN(1024);
/*. = ALIGN(4);*/
_etext = .;
/* This is used by the startup in order to initialize the .data secion */
/* This is used by the startup in order to initialize the .data section */
_sidata = _etext;
} >ROM_region
.coffee 0x08010000 :
{
_coffee_start = ABSOLUTE(.);
. = ALIGN(1024);
*(.coffeefiles)
. = ORIGIN(NVM_region) - _coffee_start;
} > ROM_region = 0x00
NVM (NOLOAD):
{
. = ALIGN(1024);
@ -136,12 +146,6 @@ SECTIONS
. = ALIGN(4);
} > FIB_region
/*
.FAT (NOLOAD):
{
KEEP(*(.FAT))
} > FIB_region
*/
/* after that it's only debugging information. */
@ -152,7 +156,7 @@ SECTIONS
.data : AT ( _sidata )
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
/* This is used by the startup in order to initialize the .data section */
_sdata = . ;
*(.data)
@ -161,9 +165,9 @@ SECTIONS
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
ASSERT(_sidata + SIZEOF(.data) < LOADADDR(.coffee), ".data section overflow in ROM");
} >RAM_region
/* This is the uninitialized data section */
.bss :