Mf4.2 + gcc +stm32

@ trioflex

I tried the new version of coIDE with my ST-Discovery board with ST-Link. It programs okay but when I try to debug (in flash) I get this error ‘java.lang.NullPointerException’.

I just had a simple test program that adds two numbers (a=b+c;). However I haven’t figured out how to add the C startup code yet. Any suggestions?

no suggestions yet, I was trying out cocoox, it FLASHED almost anything I tried but on the PC I was trying there are some weirds things, like STlink not working with ST own tools
cocoox can not start GDB server on this PC, I am about to install to another one, and try there.

I am usually happy when I get CODE DOWNLOAD ok, not so much bothering about debugging…

Antti

The following resources should help you get started with an eclipse toolchain. I didn’t try coocox because it is way too shady and I wanted to learn some stuff. Also, these aren’t targeted at .netmf porting, so you may need to adapt.

Setting up an Eclipse-based IDE (updated)- ChibiOS free embedded RTOS - This topic does not exist yet
Using an Eclipse-based IDE (updated)

The makefile i use on my toolchain(based on Yagarto’s):


 #
 #       !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!!    
 #
 ##############################################################################################
 # 
 # On command line:
 #
 # make all = Create project
 #
 # make clean = Clean project files.
 #
 # To rebuild project do "make clean" and "make all".
 #

 ##############################################################################################
 # Start of default section
 #

TRGT = arm-none-eabi-
CC   = $(TRGT)gcc
CPP  = $(TRGT)g++
CP   = $(TRGT)objcopy
AS   = $(TRGT)gcc -x assembler-with-cpp
LD   = $(CC)
BIN  = $(CP) -O ihex 

MCU  = cortex-m4

 # List all default C defines here, like -D_DEBUG=1
DDEFS = 

 # List all default ASM defines here, like -D_DEBUG=1
DADEFS =  

 # List all default directories to look for include files here
DINCDIR = 	../..\Libraries\CMSIS\Include \
            ../..\Libraries\CMSIS\ST\STM32F4xx\Include \
            ../..\Libraries\STM32F4xx_StdPeriph_Driver\inc \
			../..\Libraries\STM32_USB_OTG_Driver\inc \
			../..\Libraries\STM32_USB_Device_Library\Core\inc \
			../..\Libraries\STM32_USB_Device_Library\Class\audio\inc \
			../..\Libraries\STM32_USB_Device_Library\Class\cdc\inc \
			../..\Libraries\STM32_USB_Device_Library\Class\dfu\inc \
			../..\Libraries\STM32_USB_Device_Library\Class\hid\inc \
			../..\Libraries\STM32_USB_Device_Library\Class\msc\inc \
			../..\Libraries\STM32_USB_HOST_Library\Core\inc \
			../..\Libraries\STM32_USB_HOST_Library\Class\MSC\inc \
			../..\Libraries\STM32_USB_HOST_Library\Class\HID\inc \
			../..\Utilities\STM32F4-Discovery \
			../..\Utilities\Third_Party\fat_fs\inc


 # List the default directory to look for the libraries here
DLIBDIR = 

 # List all default libraries here
DLIBS = -lc -lm -lgcc -lstdc++

 #
 # End of default section
 ##############################################################################################

 ##############################################################################################
 # Start of user section
 #

 # 
 # Define project name and Ram/Flash mode here
PROJECT        = template
 #
 # Define linker script file here(OVERRIDES DEFAULT)
 #
LDSCRIPT = 

FULL_PRJ = $(PROJECT)

 # List all user C define here, like -D_DEBUG=1
UDEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DHSE_VALUE=8000000

 # Define ASM defines here
UADEFS = 

 # List C source files here
CSRC  = ./src/stm32f4xx_it.c \
./src/system_stm32f4xx.c \
./src/main.c

 # List Cpp source files here
CPPSRC = 

 # List ASM source files here
ASRC = ./src/startup_stm32f4xx.S

 # List all user directories here
UINCDIR = ./inc
			
 # List the user directory to look for the libraries here
ULIBDIR = 

 # List all user libraries here
ULIBS = 

 #
 # End of user defines
 ##############################################################################################
ifndef LDSCRIPT
	ifdef CPPSRC
		LDSCRIPT = ./LinkerScripts/stm32f4xx_flash_cpp.ld
		DADEFS+= -DCPPMAKE
        LD   = $(CPP)
	else
		LDSCRIPT = ./LinkerScripts/stm32f4xx_flash.ld
	endif
endif

INCDIR  = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR))
LIBDIR  = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))


DEFS    = $(DDEFS) $(UDEFS)

ADEFS   = $(DADEFS) $(UADEFS)
OBJS    = $(CSRC:.c=.o) $(CPPSRC:.cpp=.o) $(ASRC:.S=.o) 
LIBS    = $(DLIBS) $(ULIBS)
MCFLAGS = -mthumb -mcpu=$(MCU) -mfpu=fpv4-sp-d16 -mfloat-abi=softfp

GFLAGS = -O0 -gdwarf-2  -Wall -ffunction-sections -fdata-sections  -fomit-frame-pointer -fverbose-asm
ASFLAGS = $(MCFLAGS)  -gdwarf-2 -Wa,-amhls=$(<:.S=.lst) $(ADEFS) 
CFLAGS = $(MCFLAGS) $(GFLAGS) -Wa,-ahlms=$(<:.c=.lst)  $(DEFS)
CPPFLAGS = $(MCFLAGS)  $(GFLAGS) -fno-rtti -fno-exceptions -Wa,-ahlms=$(<:.cpp=.lst)  $(DEFS)
LDFLAGS = $(MCFLAGS) -T$(LDSCRIPT) -Wl,-Map=$(FULL_PRJ).map,--cref,--no-warn-mismatch,--gc-sections   $(LIBDIR)

 # Generate dependency information
CFLAGS += -MD -MP -MF .dep/$(@ F).d
CPPFLAGS += -MD -MP -MF .dep/$(@ F).d

 #
 # makefile rules
 #

all: $(OBJS) $(FULL_PRJ).elf $(FULL_PRJ).hex


%.o : %.c
	$(CC) -c $(CFLAGS) -I . $(INCDIR) $< -o $@ 

%.o : %.cpp
	$(CPP) -c $(CPPFLAGS) -I . $(INCDIR) $< -o $@ 

%.o : %.S
	$(AS) -c $(ASFLAGS) $< -o $@ 

%elf: $(OBJS)
	$(LD) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ 
  
%hex: %elf
	$(BIN) $< $@ 

clean:
	-rm -f $(OBJS)
	-rm -f $(FULL_PRJ).elf
	-rm -f $(FULL_PRJ).map
	-rm -f $(FULL_PRJ).hex
	-rm -f $(CSRC:.c=.c.bak)
	-rm -f $(CSRC:.c=.lst)
	-rm -f $(CPPSRC:.cpp=.cpp.bak)
	-rm -f $(CPPSRC:.cpp=.lst)
	-rm -f $(ASRC:.S=.S.bak)
	-rm -f $(ASRC:.S=.lst)
	-rm -fR .dep

 # 
 # Include the dependency files, should be the last of the makefile
 #
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)

 # *** EOF ***

my linker scripts(based on Atollic, Yagarto, ARM, etc ;)):

stm32f4xx_flash.ld


/*
**
** Standard linking descriptor for arm-none-eabi-gcc
**
*/

/* Entry Point */
ENTRY(Reset_Handler)


/* Specify the memory areas */
MEMORY
{
	FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
	RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 112K
}


_estack = ORIGIN(RAM) + LENGTH(RAM); /*0x2001c000 end of 112K RAM */

/* Define output sections */
SECTIONS
{
	/* The startup code goes first into FLASH */
	.isr_vector :
	{
		KEEP(*(.isr_vector)) /* Startup code */
		. = ALIGN(4);
	} >FLASH

	/* The program code and other data goes into FLASH */
	.text :
	{
		. = ALIGN(4);
		*(.text)           /* .text sections (code) */
		*(.text*)          /* .text* sections (code) */
		*(.rodata)         /* .rodata sections (constants, strings, etc.) */
		*(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
		*(.eh_frame)


		_etext = ALIGN(4);
	} >FLASH


	/* used by the startup to initialize data */
	_sidata = .;

	/* Initialized data sections goes into RAM, load LMA copy after code */
	.data : AT ( _sidata )
	{
		. = ALIGN(4);
		_sdata = .;        /* create a global symbol at data start */
		*(.data)           /* .data sections */
		*(.data*)          /* .data* sections */

		. = ALIGN(4);
		_edata = .;        /* define a global symbol at data end */
	} >RAM

	/* Uninitialized data section */
	. = ALIGN(4);
	.bss :
	{
		/* This is used by the startup in order to initialize the .bss secion */
		_sbss = .;         /* define a global symbol at bss start */
		__bss_start__ = _sbss;
		*(.bss)
		*(.bss*)
		*(COMMON)

		. = ALIGN(4);
		_ebss = .;         /* define a global symbol at bss end */
		__bss_end__ = _ebss;
	} >RAM

}

stm32f4_flash_cpp.ld


/*
**
** Standard linking descriptor for arm-none-eabi-gcc
**
*/

GROUP(libgcc.a libc.a libm.a)

/* Entry Point */
ENTRY(Reset_Handler)


/* Specify the memory areas */
MEMORY
{
	FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
	RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 112K
}

HEAP_SIZE = 0;
STACK_MAX_SIZE = LENGTH(RAM);

_estack = ORIGIN(RAM) + LENGTH(RAM); /*0x2001c000 end of 112K RAM */

/* Define output sections */
SECTIONS
{
	/* The startup code goes first into FLASH */
	.isr_vector :
	{
		KEEP(*(.isr_vector)) /* Startup code */
		. = ALIGN(4);
	} >FLASH

	/* The program code and other data goes into FLASH */
	.text :
	{
		. = ALIGN(4);
		*(.text .text.* .gnu.linkonce.t.*)
		*(.plt)
		*(.gnu.warning)
		*(.vfp11_veneer)
		*(.ARM.extab* .gnu.linkonce.armextab.*)
		*(.gcc_except_table)
		. = ALIGN(4);
		KEEP (*(.eh_frame_hdr))
		. = ALIGN(4);
		KEEP(*(.eh_frame))
	} >FLASH

	__exidx_start = .;
	.ARM.exidx :
	{
		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
	} > FLASH
	__exidx_end = .;

	.rodata : ALIGN (4)
	{
		*(.rodata .rodata.* .gnu.linkonce.r.*)
		
		. = ALIGN(4);
		KEEP(*(.init))
		
		. = ALIGN(4);
		__preinit_array_start = .;
		KEEP (*(.preinit_array))
		__preinit_array_end = .;
		
		. = ALIGN(4);
		__init_array_start = .;
		KEEP (*(SORT(.init_array.*)))
		KEEP (*(.init_array))
		__init_array_end = .;
		
		. = ALIGN(4);
		KEEP(*(.fini))
		
		. = ALIGN(4);
		__fini_array_start = .;
		KEEP (*(.fini_array))
		KEEP (*(SORT(.fini_array.*)))
		__fini_array_end = .;
		
		. = ALIGN(0x4);
		KEEP (*crtbegin.o(.ctors))
		KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
		KEEP (*(SORT(.ctors.*)))
		KEEP (*crtend.o(.ctors))
		
		. = ALIGN(0x4);
		KEEP (*crtbegin.o(.dtors))
		KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
		KEEP (*(SORT(.dtors.*)))
		KEEP (*crtend.o(.dtors))
		
		. = ALIGN (8);
		*(.rom)
		*(.rom.b)
		_etext = .;

	} >FLASH



	/* used by the startup to initialize data */
	_sidata = .;

	/* Initialized data sections goes into RAM, load LMA copy after code */
	.data : AT ( _sidata )
	{
		. = ALIGN(4);
		_sdata = .;        /* create a global symbol at data start */
		
		KEEP(*(.jcr))
		*(.got.plt) *(.got)
		*(.shdata)
		*(.data .data.* .gnu.linkonce.d.*)
		
		. = ALIGN(4);
		_edata = .;        /* define a global symbol at data end */
	} >RAM

	/* Uninitialized data section */
	. = ALIGN(4);
	.bss :
	{
		/* This is used by the startup in order to initialize the .bss secion */
		_sbss = .;         /* define a global symbol at bss start */
		__bss_start__ = _sbss;
		*(.shbss)
		*(.bss .bss.* .gnu.linkonce.b.*)
		*(COMMON)

		. = ALIGN(4);
		_ebss = .;         /* define a global symbol at bss end */
		__bss_end__ = _ebss;
	} >RAM
	
	PROVIDE ( end = _ebss );
    PROVIDE ( _end = _ebss );
    PROVIDE ( __end__ = _ebss );

    .heap : {
        __heap_start__ = . ;
        . = . + HEAP_SIZE;
        . = ALIGN(4);
        __heap_end__ = . ;
    } >RAM
	
	
	/DISCARD/ :
    {
     libc.a ( * )
     libm.a ( * )
     libgcc.a ( * )
     }     
}

ASSERT((_estack - __heap_end__)<STACK_MAX_SIZE,"Heap and stack overlap.")

Thanks everyone for the replies. As I mentioned in my post I was missing the C startup code which it turns out is in the CMSIS code. Once I found and installed that everything works fine. I can compile, dowmload and debug (using ST-Link) code on my ST_Discovery board :slight_smile:

Synapsys: This is still with the CooCox IDE? Where did you gat the CMSIS code branch from? I included all the offered components in my first build attempt and it would not even compile due to missing code from this branch.

On another thought: Is there any reason we cannot use Visual Studio as an IDE for the GNU ARM toolset?

@ JohnH

Yes, it’s the CooCox IDE. I received an email from CooCox tech support overnight indicating that their web servers have been experiencing problems but are now back on line. So you can download the CMSIS code from the repository in CoIDE.

Regards,
Synapsys

Finally got FEZ Cerberus firmware to build with GCC. I’ll have to try it tomorrow to see if it actually works on my Cerb40.

Done Building Project "D:\NETMF42_ST32_CERB\solutions\FEZ_Cerberus\dotnetmf.proj" (default targets).

Build succeeded.

The ER_FLASH ended up being 393 kb. Plenty of room for piling on the features! :slight_smile:

Note: I disabled Graphics and a few other items I had no use for…

Incredible news! Are you willing to set up a codeplex or other site to host the code?

When I load my firmware onto the Cerb40 and power up, the system no longer recognizes the device. Right now, I am suspecting the scatter file is not quite right. Clearly needs more work.

Yeah, that is where I am.

My scatter file is correct, of that much i’m sure. I think… :slight_smile:

While debugging my board always ends up in a hard fault exception state…

I suspect there is something wrong with my ASM porting…

Have you taken a look at the Netduino asm files?

Have not yet had time…

There is a lot of places in the .NET MF with ARM code, Cortex-M4 core supports only Thumb/2 instruction sets, hence the exceptions. In order to fix them, you’d need to pass -mcpu=cortex-m4 and/or -march=armv7 (depending on the toolchain), make sure thumb assembly is being generated (.thumb_func directives here and there) and no branch-and-exhanges are emitted (BX to address that has bit 0 zero, because switching to ARM mode is not allowed), and correct thumb libraries are used (as suggested by gcc --print-multi-lib, based on the mcpu/march parameters, the default build settings pick up wrong ARM libraries).

Hope this helps.

Thanks for helping @ CW2 and welcome to the community. I am sure with the efforts by companies and communities we will all enjoy a nice solid port for STMF4

Hey CW2! I actually borrowed the scatterfile from your GCC STM32 port for NGO (with a change to the project path). Hope you don’t mind. I have some guesses at what I did wrong (maybe made the dfu incorrectly) and will try again tonight. Obviously, it would be great if we had a source code repository for this so we can have more people working on it. I’ve made so many changes that I will have to figure out how to do a diff between what I have and the NETMF PK.

Also, do you think it’s possible that your NGO GCC port would work on the Cerberus with the clock crystal changes similar to those needed for the ST Discovery board? I might try that too, just to make sure I am on the right path. Although, I don’t know if the processor is the same with all these devices… besides the fact that they are all STM32F4.

Yes, it should work. I haven’t tried it yet, but it was/is on my list of things to do.

Of course I don’t mind. Please make sure you get the latest version, I have made a few important bugfixes recently (one was missing section in scatterfile). I have not examined the exact differences between Netduino Go! and Cerberus, but IMHO it should work with those three little changes needed to adjust the oscillator frequency, like for STM32F4 Discovery. It should not be hard to for example clone the Netduino Go! solution into STM32F4-Discovery solution - however, there is some Netduino Go!-specific code not yet wrapped in conditional compilation blocks, so a good diff tool comes in handy :slight_smile:

@ CW2

Great to see you here!
I’ve learned few things from your posts on PK in netduino forum.

Appreciate it!

Attempting to compile, I get a whole giant list of errors that all look something like this:

Any ideas?

The way I use is to dump the output of the MSBUILD command into a text file >> 1.txt
Then you can copy individual command from that text file that has failed and re-run it. That will give you more meaningful output of the real reason of the failure.