Przeglądaj źródła

STM32F4 family support.

Konstantin Oblaukhov 12 lat temu
rodzic
commit
8d3fffe4a6

+ 9 - 7
README.mediawiki

@@ -5,10 +5,11 @@ Requirements:
 * cmake >= 2.8
 * GCC toolchain with newlib.
 * STM32F10x Standard Peripherals Library for STM32F1 family
+* STM32F4 DSP and Standard Peripherals Library for STM32F4 family
 Project contains:
 * CMake common toolchain file, that configures cmake to use arm toolchain.
 * CMake family-specific toolchain file, that configures family-specific parameters.
-* CMake projects that builds CMSIS and STM32F10x Standard Peripherals Library into static libraries.
+* CMake projects that builds CMSIS and Standard Peripherals Library into static libraries.
 * CMake modules to find and configure CMSIS ans StdPeriphLib libraries.
 * CMake project template.
 * Example projects
@@ -20,11 +21,12 @@ First of all you need to configure toolchain and libraries, you can do this by e
 Variables for toolchain:
 * TOOLCHAIN_PREFIX - where toolchain is located, '''default''': /usr
 * TARGET_TRIPLET - toolchain target triplet, '''default''': arm-none-eabi
-* STM32_FAMILY - STM32 family (F0, F1, F4, etc.) currently only F1 family supported.
+* STM32_FAMILY - STM32 family (F0, F1, F4, etc.) currently, F1 and F4 family are supported.
 '''Note:''' If STM32_CHIP variable is set, STM32_FAMILY is optional.
 
 Variables for CMSIS and StdPeriphLib:
-* STM32_StdPeriphLib_DIR - path to STM32F10x Standard Peripherals Library '''default''': /opt/STM32F10x_StdPeriph_Lib_V3.5.0
+* STM32F1_StdPeriphLib_DIR - path to STM32F10x Standard Peripherals Library '''default''': /opt/STM32F10x_StdPeriph_Lib_V3.5.0
+* STM32F4_StdPeriphLib_DIR - path to STM32F4 DSP and Standard Peripherals Library '''default''': /opt/STM32F4xx_DSP_StdPeriph_Lib_V1.3.0
 * USE_ASSERT - Use internal asserts in Standard Peripherals Library.
 
 === Build CMSIS and Standard Peripherals Library ===
@@ -34,9 +36,11 @@ In cmsis folder:
 In stdperiph folder
  cmake -DCMAKE_TOOLCHAIN_FILE=../gcc_stm32.cmake -DCMAKE_MODULE_PATH=<path_to_cmake_folder_of_this_project>/Modules -DSTM32_FAMILY=F1 -DCMAKE_INSTALL_PREFIX=<path_to_toolchain>/arm-none-eabi/ -DCMAKE_BUILD_TYPE=Release
  make && make install
+'''Note:''' For building for STM32F4 family, change -DSTM32_FAMILY=F1 to -DSTM32_FAMILY=F4
+
 '''Note:''' You can use different CMAKE_INSTALL_PREFIX, but than you'll have to configure cmake search paths when using cmake modules.
 
-'''Note:''' To prevent header collision file "misc.h" from Standard Peripherals Library will be installed as stm32f10x_misc.h
+'''Note:''' To prevent header collision file "misc.h" from Standard Peripherals Library will be installed as stm32f10x_misc.h / stm32f4xx_misc.h
 
 == Usage ==
 After building you need to copy cmake modules in cmake's modules path, or just set CMAKE_MODULE_PATH in project. 
@@ -45,7 +49,7 @@ Template project can be found in stm32-template folder.
 === Configure === 
 Common usage:
  cmake -DSTM32_CHIP=<chip> -DCMAKE_TOOLCHAIN_FILE=<path_to_gcc_stm32.cmake> -DCMAKE_BUILD_TYPE=Debug <path_to_source_dir>
-Where <nowiki><chip></nowiki> - stm32 chip name (e.g. STM32F100C8). 
+Where <nowiki><chip></nowiki> - stm32 chip name (e.g. STM32F100C8, STM32F407IG). 
 This command will generate Makefile for project.
 Scripts will try to detected chip parameters (type, flash/ram size) from chip name. 
 You can set this parameters directly using following cmake variables:
@@ -69,11 +73,9 @@ or .bin:
 Next cmake variables are useful for linker tuning:
 * STM32_FLASH_ORIGIN - Start address of flash (default: 0x08000000)
 * STM32_RAM_ORIGIN - Start address of RAM (default: 0x20000000)
-* STM32_EXT_RAM_ORIGIN - Start address of external RAM (default: 0x60000000)
 * STM32_STACK_ADDRESS - Address of stack bottom (default: RAM_ORIGIN + RAM_SIZE)
 * STM32_FLASH_SIZE - Flash size (default: from chip name)
 * STM32_RAM_SIZE - RAM size (default: from chip name)
-* STM32_EXT_RAM_SIZE - External RAM size (default: 0 bytes)
 * STM32_MIN_STACK_SIZE - Minimum stack size for error detection at link-time (default: 512 bytes)
 * STM32_MIN_HEAP_SIZE - Minimum heap size for error detection at link-time (default: 0 bytes)
 

+ 8 - 12
cmake/Modules/FindCMSIS.cmake

@@ -1,9 +1,13 @@
 STRING(TOLOWER ${STM32_FAMILY} STM32_FAMILY_LOWER)
 
 IF(STM32_FAMILY STREQUAL "F1")
-    SET(CMSIS_STARTUP_PREFIX "startup_stm32f10x_")
+    SET(CMSIS_STARTUP_PREFIX startup_stm32f10x_)
     SET(CMSIS_HEADERS system_stm32f10x.h core_cm3.h stm32f10x.h)
     SET(CMSIS_LINKER_SCRIPT_NAME stm32f1_flash.ld.in)
+ELSEIF(STM32_FAMILY STREQUAL "F4")
+    SET(CMSIS_STARTUP_PREFIX startup_stm32f)
+    SET(CMSIS_HEADERS system_stm32f4xx.h core_cm4.h stm32f4xx.h)
+    SET(CMSIS_LINKER_SCRIPT_NAME stm32f4_flash.ld.in)
 ENDIF()
 
 IF((NOT STM32_CHIP_TYPE) AND (NOT STM32_CHIP))
@@ -62,7 +66,7 @@ MACRO(STM32_KB_TO_BYTES KB BYTES)
     ENDIF()
 ENDMACRO()
 
-FUNCTION(STM32_SET_FLASH_PARAMS TARGET STM32_FLASH_SIZE STM32_RAM_SIZE STM32_STACK_ADDRESS STM32_MIN_STACK_SIZE STM32_MIN_HEAP_SIZE STM32_EXT_RAM_SIZE STM32_FLASH_ORIGIN STM32_RAM_ORIGIN STM32_EXT_RAM_ORIGIN)
+FUNCTION(STM32_SET_FLASH_PARAMS TARGET STM32_FLASH_SIZE STM32_RAM_SIZE STM32_STACK_ADDRESS STM32_MIN_STACK_SIZE STM32_MIN_HEAP_SIZE STM32_FLASH_ORIGIN STM32_RAM_ORIGIN)
     CONFIGURE_FILE(${CMSIS_LINKER_SCRIPT} ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_flash.ld)
     SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS "-T${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_flash.ld ${CMAKE_EXE_LINKER_FLAGS}")
 ENDFUNCTION()
@@ -77,11 +81,7 @@ FUNCTION(STM32_SET_FLASH_PARAMS TARGET FLASH_SIZE RAM_SIZE)
     
     IF(NOT STM32_RAM_ORIGIN)
         SET(STM32_RAM_ORIGIN "536870912")
-    ENDIF() 
-    
-    IF(NOT STM32_EXT_RAM_ORIGIN)
-        SET(STM32_EXT_RAM_ORIGIN "0x60000000")
-    ENDIF() 
+    ENDIF()
     
     IF(NOT STM32_STACK_ADDRESS)
         MATH(EXPR STM32_STACK_ADDRESS "${STM32_RAM_ORIGIN} + ${RAM_SIZE}")
@@ -97,11 +97,7 @@ FUNCTION(STM32_SET_FLASH_PARAMS TARGET FLASH_SIZE RAM_SIZE)
     IF(NOT STM32_MIN_HEAP_SIZE)
         SET(STM32_MIN_HEAP_SIZE "0")
     ENDIF()
-    
-    IF(NOT STM32_EXT_RAM_SIZE)
-        SET(STM32_EXT_RAM_SIZE "0K")
-    ENDIF()
-    
+        
     CONFIGURE_FILE(${CMSIS_LINKER_SCRIPT} ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_flash.ld)
     SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS "-T${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_flash.ld ${CMAKE_EXE_LINKER_FLAGS}")
 ENDFUNCTION()

+ 32 - 0
cmake/Modules/FindStdPeriphLib.cmake

@@ -24,6 +24,38 @@ IF(STM32_FAMILY STREQUAL "F1")
         stm32f10x_wwdg.h
         stm32f10x_misc.h
     )
+ELSEIF(STM32_FAMILY STREQUAL "F4")
+    SET(STDPERIPH_HEADERS
+        stm32f4xx_adc.h
+        stm32f4xx_can.h
+        stm32f4xx_crc.h
+        stm32f4xx_cryp.h
+        stm32f4xx_dac.h
+        stm32f4xx_dbgmcu.h
+        stm32f4xx_dcmi.h
+        stm32f4xx_dma.h
+        stm32f4xx_dma2d.h
+        stm32f4xx_exti.h
+        stm32f4xx_flash.h
+        stm32f4xx_fmc.h
+        stm32f4xx_fsmc.h
+        stm32f4xx_gpio.h
+        stm32f4xx_hash.h
+        stm32f4xx_i2c.h
+        stm32f4xx_iwdg.h
+        stm32f4xx_ltdc.h
+        stm32f4xx_pwr.h
+        stm32f4xx_rcc.h
+        stm32f4xx_rng.h
+        stm32f4xx_rtc.h
+        stm32f4xx_sai.h
+        stm32f4xx_sdio.h
+        stm32f4xx_spi.h
+        stm32f4xx_syscfg.h
+        stm32f4xx_tim.h
+        stm32f4xx_usart.h
+        stm32f4xx_wwdg.h
+    )
 ENDIF()
 
 STRING(TOLOWER ${STM32_FAMILY} STM32_FAMILY_LOWER)

+ 24 - 0
cmsis-3.0/CMakeLists.txt

@@ -32,6 +32,30 @@ IF(${STM32_FAMILY} STREQUAL "F1")
     
     SET(CMSIS_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/stm32f1_flash.ld.in)
     SET(STARTUP_PREFIX ${STM32F1_StdPeriphLib_DIR}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/gcc_ride7/startup_stm32f10x_)
+ELSEIF(${STM32_FAMILY} STREQUAL "F4")
+    IF(NOT STM32F4_StdPeriphLib_DIR)
+        SET(STM32F4_StdPeriphLib_DIR "/opt/STM32F4xx_DSP_StdPeriph_Lib_V1.3.0")
+        MESSAGE(STATUS "No STM32F4_StdPeriphLib_DIR specified, using default: " ${STM32F4_StdPeriphLib_DIR})
+    ENDIF()
+
+    INCLUDE_DIRECTORIES(
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Include/
+    )
+        
+    SET(CMSIS_HEADERS 
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h
+        ${CMSIS3_DIR}/CMSIS/Include/core_cm4.h 
+        ${CMSIS3_DIR}/CMSIS/Include/core_cmFunc.h
+        ${CMSIS3_DIR}/CMSIS/Include/core_cmInstr.h
+    )
+    
+    SET(CMSIS_SOURCES 
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c
+    )
+    
+    SET(CMSIS_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/stm32f4_flash.ld.in)
+    SET(STARTUP_PREFIX ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_stm32f)
 ENDIF()
 
 INCLUDE_DIRECTORIES(

+ 0 - 11
cmsis-3.0/stm32f1_flash.ld.in

@@ -26,7 +26,6 @@ MEMORY
 {
   FLASH (rx)      : ORIGIN = ${STM32_FLASH_ORIGIN}, LENGTH = ${STM32_FLASH_SIZE}
   RAM (xrw)       : ORIGIN = ${STM32_RAM_ORIGIN}, LENGTH = ${STM32_RAM_SIZE}
-  MEMORY_B1 (rx)  : ORIGIN = ${STM32_EXT_RAM_ORIGIN}, LENGTH = ${STM32_EXT_RAM_SIZE}
 }
 
 /* Define output sections */
@@ -132,16 +131,6 @@ SECTIONS
     . = ALIGN(4);
   } >RAM
 
-  /* MEMORY_bank1 section, code must be located here explicitly            */
-  /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
-  .memory_b1_text :
-  {
-    *(.mb1text)        /* .mb1text sections (code) */
-    *(.mb1text*)       /* .mb1text* sections (code)  */
-    *(.mb1rodata)      /* read-only data (constants) */
-    *(.mb1rodata*)
-  } >MEMORY_B1
-
   /* Remove information from the standard libraries */
   /DISCARD/ :
   {

+ 195 - 0
cmsis-3.0/stm32f4_flash.ld.in

@@ -0,0 +1,195 @@
+/*
+Default linker script for STM32F4xx_1024K_192K
+*/
+
+/* include the common STM32F4xx  sub-script */
+
+/* Common part of the linker scripts for STM32F devices*/
+
+
+/* default stack sizes. 
+
+These are used by the startup in order to allocate stacks for the different modes.
+*/
+
+__Stack_Size = 1024 ;
+
+PROVIDE ( _Stack_Size = __Stack_Size ) ;
+
+__Stack_Init = _estack  - __Stack_Size ;
+
+/*"PROVIDE" allows to easily override these values from an object file or the commmand line.*/
+PROVIDE ( _Stack_Init = __Stack_Init ) ;
+
+/*
+There will be a link error if there is not this amount of RAM free at the end.
+*/
+_Minimum_Stack_Size = ${STM32_MIN_STACK_SIZE} ;
+
+
+/* include the memory spaces definitions sub-script */
+/*
+Linker subscript for STM32F4xx definitions with 1024 Flash and 192 Onchip SRAM */
+
+/* Memory Spaces Definitions */
+
+MEMORY
+{
+  RAM (xrw) : ORIGIN = ${STM32_RAM_ORIGIN}, LENGTH = ${STM32_RAM_SIZE}
+  CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
+  FLASH (rx) : ORIGIN = ${STM32_FLASH_ORIGIN}, LENGTH = ${STM32_FLASH_SIZE}
+  MEMORY_ARRAY (xrw)  : ORIGIN = 0x20002000, LENGTH = 32
+}
+
+/* higher address of the user mode stack (end of 128K RAM on AHB bus)*/
+_estack = ${STM32_STACK_ADDRESS};
+
+
+
+/* include the sections management sub-script for FLASH mode */
+
+/* Sections Definitions */
+
+SECTIONS
+{
+    /* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */
+    .isr_vector :
+    {
+	. = ALIGN(4);
+        KEEP(*(.isr_vector))            /* Startup code */
+	. = ALIGN(4);
+    } >FLASH
+ 
+    /* for some STRx devices, the beginning of the startup code is stored in the .flashtext section, which goes to FLASH */
+    .flashtext :
+    {
+	. = ALIGN(4);
+        *(.flashtext)            /* Startup code */
+	. = ALIGN(4);
+    } >FLASH
+ 
+    
+    /* the program code is stored in the .text section, which goes to Flash */
+    .text :
+    {
+	    . = ALIGN(4);
+	    
+        *(.text)                   /* remaining code */
+        *(.text.*)                 /* remaining code */
+        *(.rodata)                 /* read-only data (constants) */
+        *(.rodata*)
+        *(.glue_7)
+        *(.glue_7t)
+
+	    . = ALIGN(4);
+   	 _etext = .;
+	    /* This is used by the startup in order to initialize the .data secion */
+   	 _sidata = _etext;
+    } >FLASH
+    
+    /* MEMORY_ARRAY */
+    .ROarraySection :
+    {
+            *(.ROarraySection)                          
+    } >MEMORY_ARRAY
+     
+
+    /* This is the initialized data section
+    The program executes knowing that the data is in the RAM
+    but the loader puts the initial values in the FLASH (inidata).
+    It is one task of the startup to copy the initial values from FLASH to RAM. */
+    .data  : AT ( _sidata )
+    {
+	    . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _sdata = . ;
+        
+        *(.data)
+        *(.data.*)
+
+	    . = ALIGN(4);
+	    /* This is used by the startup in order to initialize the .data secion */
+   	 _edata = . ;
+    } >RAM
+    
+    
+
+    /* This is the uninitialized data section */
+    .bss :
+    {
+	    . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .bss secion */
+        _sbss = .;
+        
+        *(.bss)
+        *(COMMON)
+        
+	    . = ALIGN(4);
+	    /* This is used by the startup in order to initialize the .bss secion */
+   	 _ebss = . ;
+    } >RAM
+    
+    PROVIDE ( end = _ebss );
+    PROVIDE ( _end = _ebss );
+    
+    /* This is the user stack section 
+    This is just to check that there is enough RAM left for the User mode stack
+    It should generate an error if it's full.
+     */
+    ._usrstack :
+    {
+	    . = ALIGN(4);
+        _susrstack = . ;
+        
+        . = . + _Minimum_Stack_Size ;
+        
+	    . = ALIGN(4);
+        _eusrstack = . ;
+    } >RAM
+    
+    /* after that it's only debugging information. */
+    
+    /* remove the debugging information from the standard libraries */
+    DISCARD :
+    {
+     libc.a ( * )
+     libm.a ( * )
+     libgcc.a ( * )
+     }
+  
+  
+    /* Stabs debugging sections.  */
+    .stab          0 : { *(.stab) }
+    .stabstr       0 : { *(.stabstr) }
+    .stab.excl     0 : { *(.stab.excl) }
+    .stab.exclstr  0 : { *(.stab.exclstr) }
+    .stab.index    0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment       0 : { *(.comment) }
+    /* DWARF debug sections.
+       Symbols in the DWARF debugging sections are relative to the beginning
+       of the section so we begin them at 0.  */
+    /* DWARF 1 */
+    .debug          0 : { *(.debug) }
+    .line           0 : { *(.line) }
+    /* GNU DWARF 1 extensions */
+    .debug_srcinfo  0 : { *(.debug_srcinfo) }
+    .debug_sfnames  0 : { *(.debug_sfnames) }
+    /* DWARF 1.1 and DWARF 2 */
+    .debug_aranges  0 : { *(.debug_aranges) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    /* DWARF 2 */
+    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+    .debug_abbrev   0 : { *(.debug_abbrev) }
+    .debug_line     0 : { *(.debug_line) }
+    .debug_frame    0 : { *(.debug_frame) }
+    .debug_str      0 : { *(.debug_str) }
+    .debug_loc      0 : { *(.debug_loc) }
+    .debug_macinfo  0 : { *(.debug_macinfo) }
+    /* SGI/MIPS DWARF 2 extensions */
+    .debug_weaknames 0 : { *(.debug_weaknames) }
+    .debug_funcnames 0 : { *(.debug_funcnames) }
+    .debug_typenames 0 : { *(.debug_typenames) }
+    .debug_varnames  0 : { *(.debug_varnames) }    
+    
+}

+ 24 - 0
cmsis/CMakeLists.txt

@@ -25,6 +25,30 @@ IF(${STM32_FAMILY} STREQUAL "F1")
     
     SET(CMSIS_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/stm32f1_flash.ld.in)
     SET(STARTUP_PREFIX ${STM32F1_StdPeriphLib_DIR}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/gcc_ride7/startup_stm32f10x_)
+ELSEIF(${STM32_FAMILY} STREQUAL "F4")
+    IF(NOT STM32F4_StdPeriphLib_DIR)
+        SET(STM32F4_StdPeriphLib_DIR "/opt/STM32F4xx_DSP_StdPeriph_Lib_V1.3.0")
+        MESSAGE(STATUS "No STM32F4_StdPeriphLib_DIR specified, using default: " ${STM32F4_StdPeriphLib_DIR})
+    ENDIF()
+
+    INCLUDE_DIRECTORIES(
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Include/
+    )
+    
+    SET(CMSIS_HEADERS 
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Include/core_cm4.h 
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Include/core_cmFunc.h
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Include/core_cmInstr.h
+    )
+    
+    SET(CMSIS_SOURCES 
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c
+    )
+    
+    SET(CMSIS_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/stm32f4_flash.ld.in)
+    SET(STARTUP_PREFIX ${STM32F4_StdPeriphLib_DIR}/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_stm32f)
 ENDIF()
 
 INCLUDE_DIRECTORIES(

+ 195 - 0
cmsis/stm32f4_flash.ld.in

@@ -0,0 +1,195 @@
+/*
+Default linker script for STM32F4xx_1024K_192K
+*/
+
+/* include the common STM32F4xx  sub-script */
+
+/* Common part of the linker scripts for STM32F devices*/
+
+
+/* default stack sizes. 
+
+These are used by the startup in order to allocate stacks for the different modes.
+*/
+
+__Stack_Size = 1024 ;
+
+PROVIDE ( _Stack_Size = __Stack_Size ) ;
+
+__Stack_Init = _estack  - __Stack_Size ;
+
+/*"PROVIDE" allows to easily override these values from an object file or the commmand line.*/
+PROVIDE ( _Stack_Init = __Stack_Init ) ;
+
+/*
+There will be a link error if there is not this amount of RAM free at the end.
+*/
+_Minimum_Stack_Size = ${STM32_MIN_STACK_SIZE} ;
+
+
+/* include the memory spaces definitions sub-script */
+/*
+Linker subscript for STM32F4xx definitions with 1024 Flash and 192 Onchip SRAM */
+
+/* Memory Spaces Definitions */
+
+MEMORY
+{
+  RAM (xrw) : ORIGIN = ${STM32_RAM_ORIGIN}, LENGTH = ${STM32_RAM_SIZE}
+  CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
+  FLASH (rx) : ORIGIN = ${STM32_FLASH_ORIGIN}, LENGTH = ${STM32_FLASH_SIZE}
+  MEMORY_ARRAY (xrw)  : ORIGIN = 0x20002000, LENGTH = 32
+}
+
+/* higher address of the user mode stack (end of 128K RAM on AHB bus)*/
+_estack = ${STM32_STACK_ADDRESS};
+
+
+
+/* include the sections management sub-script for FLASH mode */
+
+/* Sections Definitions */
+
+SECTIONS
+{
+    /* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */
+    .isr_vector :
+    {
+	. = ALIGN(4);
+        KEEP(*(.isr_vector))            /* Startup code */
+	. = ALIGN(4);
+    } >FLASH
+ 
+    /* for some STRx devices, the beginning of the startup code is stored in the .flashtext section, which goes to FLASH */
+    .flashtext :
+    {
+	. = ALIGN(4);
+        *(.flashtext)            /* Startup code */
+	. = ALIGN(4);
+    } >FLASH
+ 
+    
+    /* the program code is stored in the .text section, which goes to Flash */
+    .text :
+    {
+	    . = ALIGN(4);
+	    
+        *(.text)                   /* remaining code */
+        *(.text.*)                 /* remaining code */
+        *(.rodata)                 /* read-only data (constants) */
+        *(.rodata*)
+        *(.glue_7)
+        *(.glue_7t)
+
+	    . = ALIGN(4);
+   	 _etext = .;
+	    /* This is used by the startup in order to initialize the .data secion */
+   	 _sidata = _etext;
+    } >FLASH
+    
+    /* MEMORY_ARRAY */
+    .ROarraySection :
+    {
+            *(.ROarraySection)                          
+    } >MEMORY_ARRAY
+     
+
+    /* This is the initialized data section
+    The program executes knowing that the data is in the RAM
+    but the loader puts the initial values in the FLASH (inidata).
+    It is one task of the startup to copy the initial values from FLASH to RAM. */
+    .data  : AT ( _sidata )
+    {
+	    . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _sdata = . ;
+        
+        *(.data)
+        *(.data.*)
+
+	    . = ALIGN(4);
+	    /* This is used by the startup in order to initialize the .data secion */
+   	 _edata = . ;
+    } >RAM
+    
+    
+
+    /* This is the uninitialized data section */
+    .bss :
+    {
+	    . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .bss secion */
+        _sbss = .;
+        
+        *(.bss)
+        *(COMMON)
+        
+	    . = ALIGN(4);
+	    /* This is used by the startup in order to initialize the .bss secion */
+   	 _ebss = . ;
+    } >RAM
+    
+    PROVIDE ( end = _ebss );
+    PROVIDE ( _end = _ebss );
+    
+    /* This is the user stack section 
+    This is just to check that there is enough RAM left for the User mode stack
+    It should generate an error if it's full.
+     */
+    ._usrstack :
+    {
+	    . = ALIGN(4);
+        _susrstack = . ;
+        
+        . = . + _Minimum_Stack_Size ;
+        
+	    . = ALIGN(4);
+        _eusrstack = . ;
+    } >RAM
+    
+    /* after that it's only debugging information. */
+    
+    /* remove the debugging information from the standard libraries */
+    DISCARD :
+    {
+     libc.a ( * )
+     libm.a ( * )
+     libgcc.a ( * )
+     }
+  
+  
+    /* Stabs debugging sections.  */
+    .stab          0 : { *(.stab) }
+    .stabstr       0 : { *(.stabstr) }
+    .stab.excl     0 : { *(.stab.excl) }
+    .stab.exclstr  0 : { *(.stab.exclstr) }
+    .stab.index    0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment       0 : { *(.comment) }
+    /* DWARF debug sections.
+       Symbols in the DWARF debugging sections are relative to the beginning
+       of the section so we begin them at 0.  */
+    /* DWARF 1 */
+    .debug          0 : { *(.debug) }
+    .line           0 : { *(.line) }
+    /* GNU DWARF 1 extensions */
+    .debug_srcinfo  0 : { *(.debug_srcinfo) }
+    .debug_sfnames  0 : { *(.debug_sfnames) }
+    /* DWARF 1.1 and DWARF 2 */
+    .debug_aranges  0 : { *(.debug_aranges) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    /* DWARF 2 */
+    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+    .debug_abbrev   0 : { *(.debug_abbrev) }
+    .debug_line     0 : { *(.debug_line) }
+    .debug_frame    0 : { *(.debug_frame) }
+    .debug_str      0 : { *(.debug_str) }
+    .debug_loc      0 : { *(.debug_loc) }
+    .debug_macinfo  0 : { *(.debug_macinfo) }
+    /* SGI/MIPS DWARF 2 extensions */
+    .debug_weaknames 0 : { *(.debug_weaknames) }
+    .debug_funcnames 0 : { *(.debug_funcnames) }
+    .debug_typenames 0 : { *(.debug_typenames) }
+    .debug_varnames  0 : { *(.debug_varnames) }    
+    
+}

+ 2 - 2
gcc_stm32.cmake

@@ -1,6 +1,6 @@
 INCLUDE(CMakeForceCompiler)
 
-SET(STM32_SUPPORTED_FAMILIES "F1" CACHE INTERNAL "stm32 supported families")
+SET(STM32_SUPPORTED_FAMILIES F1 F4 CACHE INTERNAL "stm32 supported families")
 
 IF(NOT TOOLCHAIN_PREFIX)
      SET(TOOLCHAIN_PREFIX "/usr")
@@ -18,7 +18,7 @@ IF(NOT STM32_FAMILY)
         SET(STM32_FAMILY "F1" CACHE INTERNAL "stm32 family")
         MESSAGE(STATUS "Neither STM32_FAMILY nor STM32_CHIP specified, using default STM32_FAMILY: ${STM32_FAMILY}")
     ELSE()
-        STRING(REGEX REPLACE "^[sS][tT][mM]32(([fF][1-4])|([lL][0-1])|([tT])|([wW])).+$" "\\1" STM32_FAMILY ${STM32_CHIP})
+        STRING(REGEX REPLACE "^[sS][tT][mM]32(([fF][0-4])|([lL][0-1])|([tT])|([wW])).+$" "\\1" STM32_FAMILY ${STM32_CHIP})
         STRING(TOUPPER ${STM32_FAMILY} STM32_FAMILY)
         MESSAGE(STATUS "Selected STM32 family: ${STM32_FAMILY}")
     ENDIF()

+ 1 - 1
gcc_stm32f1.cmake

@@ -105,5 +105,5 @@ FUNCTION(STM32_SET_CHIP_DEFINITIONS TARGET CHIP_TYPE)
     IF(TYPE_INDEX EQUAL -1)
         MESSAGE(FATAL_ERROR "Invalid/unsupported STM32F1 chip type: ${CHIP_TYPE}")
     ENDIF()
-    SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_DEFINITIONS "STM32F10X_${CHIP_TYPE}")
+    SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_DEFINITIONS "STM32F1;STM32F10X_${CHIP_TYPE}")
 ENDFUNCTION()

+ 63 - 0
gcc_stm32f4.cmake

@@ -0,0 +1,63 @@
+SET(CMAKE_C_FLAGS "-mthumb -flto -fno-builtin -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wall -std=c99 -ffunction-sections -fdata-sections -fomit-frame-pointer -mabi=aapcs -fno-unroll-loops -ffast-math -ftree-vectorize" CACHE INTERNAL "c compiler flags")
+SET(CMAKE_CXX_FLAGS "-mthumb -flto -fno-builtin -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wall -std=c++11 -ffunction-sections -fdata-sections -fomit-frame-pointer -mabi=aapcs -fno-unroll-loops -ffast-math -ftree-vectorize" CACHE INTERNAL "cxx compiler flags")
+SET(CMAKE_ASM_FLAGS "-mthumb -mcpu=cortex-m4" CACHE INTERNAL "asm compiler flags")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -Wl,--gc-sections -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -flto -mabi=aapcs" CACHE INTERNAL "executable linker flags")
+SET(CMAKE_MODULE_LINKER_FLAGS "-mthumb -mcpu=cortex-m4 -flto -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs" CACHE INTERNAL "module linker flags")
+SET(CMAKE_SHARED_LINKER_FLAGS "-mthumb -mcpu=cortex-m4 -flto -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs" CACHE INTERNAL "shared linker flags")
+
+SET(STM32_CHIP_TYPES 401xx 40_41xxx 427_437xx 429_439xx CACHE INTERNAL "stm32f4 chip types")
+SET(STM32_CODES "401.[BC]" "4[01][57].[EG]" "4[23]7.[EGI]" "4[23]9.[EGI]")
+
+MACRO(STM32_GET_CHIP_TYPE CHIP CHIP_TYPE)
+    STRING(REGEX REPLACE "^[sS][tT][mM]32[fF](4[0123][1579].[BCEGI]).+$" "\\1" STM32_CODE ${CHIP})
+    SET(INDEX 0)
+    FOREACH(C_TYPE ${STM32_CHIP_TYPES})
+        LIST(GET STM32_CODES ${INDEX} CHIP_TYPE_REGEXP)
+        IF(STM32_CODE MATCHES ${CHIP_TYPE_REGEXP})
+            SET(RESULT_TYPE ${C_TYPE})
+        ENDIF()
+        MATH(EXPR INDEX "${INDEX}+1")
+    ENDFOREACH()
+    SET(${CHIP_TYPE} ${RESULT_TYPE})
+ENDMACRO()
+
+MACRO(STM32_GET_CHIP_PARAMETERS CHIP FLASH_SIZE RAM_SIZE)
+    STRING(REGEX REPLACE "^[sS][tT][mM]32[fF](4[0123][1579].[BCEGI])" "\\1" STM32_CODE ${CHIP})
+    STRING(REGEX REPLACE "^[sS][tT][mM]32[fF]4[0123][1579].([BCEGI])" "\\1" STM32_SIZE_CODE ${CHIP})
+    
+    IF(STM32_SIZE_CODE STREQUAL "B")
+        SET(FLASH "128K")
+    ELSEIF(STM32_SIZE_CODE STREQUAL "C")
+        SET(FLASH "256K")
+    ELSEIF(STM32_SIZE_CODE STREQUAL "E")
+        SET(FLASH "512K")
+    ELSEIF(STM32_SIZE_CODE STREQUAL "G")
+        SET(FLASH "1024K")
+    ELSEIF(STM32_SIZE_CODE STREQUAL "I")
+        SET(FLASH "2048K")
+    ENDIF()
+    
+    STM32_GET_CHIP_TYPE(${CHIP} TYPE)
+    
+    IF(${TYPE} STREQUAL "401xx")
+        SET(RAM "64K")
+    ELSEIF(${TYPE} STREQUAL "40_41xxx")
+        SET(RAM "128K")
+    ELSEIF(${TYPE} STREQUAL "427_437xx")
+        SET(RAM "192K")
+    ELSEIF(${TYPE} STREQUAL "429_439xx")
+        SET(RAM "192K")
+    ENDIF()
+    
+    SET(${FLASH_SIZE} ${FLASH})
+    SET(${RAM_SIZE} ${RAM})
+ENDMACRO()
+
+FUNCTION(STM32_SET_CHIP_DEFINITIONS TARGET CHIP_TYPE)
+    LIST(FIND STM32_CHIP_TYPES ${CHIP_TYPE} TYPE_INDEX)
+    IF(TYPE_INDEX EQUAL -1)
+        MESSAGE(FATAL_ERROR "Invalid/unsupported STM32F4 chip type: ${CHIP_TYPE}")
+    ENDIF()
+    SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_DEFINITIONS "STM32F4;STM32F${CHIP_TYPE};")
+ENDFUNCTION()

+ 94 - 1
stdperiph/CMakeLists.txt

@@ -70,6 +70,99 @@ IF(${STM32_FAMILY} STREQUAL "F1")
     )
     
     INSTALL(FILES ${STDPERIPH_HEADER_DIR}/misc.h RENAME stm32f10x_misc.h DESTINATION include/stm32f1)
+ELSEIF(${STM32_FAMILY} STREQUAL "F4")
+    IF(NOT STM32F4_StdPeriphLib_DIR)
+        SET(STM32F4_StdPeriphLib_DIR "/opt/STM32F4xx_DSP_StdPeriph_Lib_V1.3.0")
+        MESSAGE(STATUS "No STM32F4_StdPeriphLib_DIR specified, using default: " ${STM32F4_StdPeriphLib_DIR})
+    ENDIF()
+
+    INCLUDE_DIRECTORIES(
+        ${STM32F4_StdPeriphLib_DIR}/Libraries/STM32F4xx_StdPeriph_Driver/inc/
+    )
+    
+    SET(STDPERIPH_SOURCE_DIR ${STM32F4_StdPeriphLib_DIR}/Libraries/STM32F4xx_StdPeriph_Driver/src)
+    SET(STDPERIPH_HEADER_DIR ${STM32F4_StdPeriphLib_DIR}/Libraries/STM32F4xx_StdPeriph_Driver/inc)
+    
+    SET(STDPERIPH_HEADERS         
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_adc.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_can.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_crc.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_cryp.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_dac.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_dbgmcu.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_dcmi.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_dma.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_dma2d.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_exti.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_flash.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_fmc.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_fsmc.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_gpio.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_hash.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_i2c.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_iwdg.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_ltdc.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_pwr.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_rcc.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_rng.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_rtc.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_sai.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_sdio.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_spi.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_syscfg.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_tim.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_usart.h
+        ${STDPERIPH_HEADER_DIR}/stm32f4xx_wwdg.h
+
+    )
+    
+    SET(STDPERIPH_SOURCES
+        ${STDPERIPH_SOURCE_DIR}/misc.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_adc.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_can.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_crc.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_cryp.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_cryp_aes.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_cryp_des.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_cryp_tdes.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_dac.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_dbgmcu.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_dcmi.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_dma.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_dma2d.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_exti.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_flash.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_gpio.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_hash.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_hash_md5.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_hash_sha1.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_i2c.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_iwdg.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_ltdc.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_pwr.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_rcc.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_rng.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_rtc.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_sai.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_sdio.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_spi.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_syscfg.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_tim.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_usart.c
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_wwdg.c
+    )
+    
+    SET(STDPERIPH_SOURCES_40_41xxx
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_fsmc.c
+    )
+    SET(STDPERIPH_SOURCES_427_437xx
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_fmc.c
+    )
+    SET(STDPERIPH_SOURCES_429_439xx
+        ${STDPERIPH_SOURCE_DIR}/stm32f4xx_fmc.c
+    )
+        
+    INSTALL(FILES ${STDPERIPH_HEADER_DIR}/misc.h RENAME stm32f4xx_misc.h DESTINATION include/stm32f4)
 ENDIF()
 
 INCLUDE_DIRECTORIES(
@@ -89,7 +182,7 @@ FOREACH(CHIP_TYPE ${STM32_CHIP_TYPES})
     STRING(TOLOWER ${CHIP_TYPE} CHIP_TYPE_LOWER)
     
     LIST(APPEND STDPERIPH_LIBRARIES stdperiph_${STM32_FAMILY_LOWER}_${CHIP_TYPE_LOWER})
-    ADD_LIBRARY(stdperiph_${STM32_FAMILY_LOWER}_${CHIP_TYPE_LOWER} ${STDPERIPH_SOURCES})
+    ADD_LIBRARY(stdperiph_${STM32_FAMILY_LOWER}_${CHIP_TYPE_LOWER} ${STDPERIPH_SOURCES} ${STDPERIPH_SOURCES_${CHIP_TYPE}})
     STM32_SET_CHIP_DEFINITIONS(stdperiph_${STM32_FAMILY_LOWER}_${CHIP_TYPE_LOWER} ${CHIP_TYPE})
 ENDFOREACH()
 

+ 5 - 1
stm32-template/main.c

@@ -1,4 +1,8 @@
-#include <stm32f10x.h>
+#ifdef STM32F1
+# include <stm32f10x.h>
+#elifdef STM32F4
+# include <stm32f4xx.h>
+#endif
 
 int main(void)
 {