Added elfloader machine dependent code for STM32W.
This commit is contained in:
parent
ced88c2eff
commit
5fe80dd99d
3 changed files with 230 additions and 36 deletions
|
@ -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
|
||||
|
|
141
cpu/stm32w108/elfloader-arch.c
Normal file
141
cpu/stm32w108/elfloader-arch.c
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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 :
|
||||
|
|
Loading…
Reference in a new issue