common.cmake 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. set(STM32_SUPPORTED_FAMILIES_LONG_NAME
  2. STM32F0 STM32F1 STM32F2 STM32F3 STM32F4 STM32F7
  3. STM32G0 STM32G4
  4. STM32H7_M4 STM32H7_M7
  5. STM32L0 STM32L1 STM32L4 STM32L5
  6. STM32U5
  7. STM32WB_M4 STM32WL_M4 STM32WL_M0PLUS
  8. STM32MP1_M4 )
  9. foreach(FAMILY ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
  10. # append short names (F0, F1, H7_M4, ...) to STM32_SUPPORTED_FAMILIES_SHORT_NAME
  11. string(REGEX MATCH "^STM32([FGHLMUW]P?[0-9BL])_?(M0PLUS|M4|M7)?" FAMILY ${FAMILY})
  12. list(APPEND STM32_SUPPORTED_FAMILIES_SHORT_NAME ${CMAKE_MATCH_1})
  13. endforeach()
  14. list(REMOVE_DUPLICATES STM32_SUPPORTED_FAMILIES_SHORT_NAME)
  15. if(NOT STM32_TOOLCHAIN_PATH)
  16. if(DEFINED ENV{STM32_TOOLCHAIN_PATH})
  17. message(STATUS "Detected toolchain path STM32_TOOLCHAIN_PATH in environmental variables: ")
  18. message(STATUS "$ENV{STM32_TOOLCHAIN_PATH}")
  19. set(STM32_TOOLCHAIN_PATH $ENV{STM32_TOOLCHAIN_PATH})
  20. else()
  21. if(NOT CMAKE_C_COMPILER)
  22. set(STM32_TOOLCHAIN_PATH "/usr")
  23. message(STATUS "No STM32_TOOLCHAIN_PATH specified, using default: " ${STM32_TOOLCHAIN_PATH})
  24. else()
  25. # keep only directory of compiler
  26. get_filename_component(STM32_TOOLCHAIN_PATH ${CMAKE_C_COMPILER} DIRECTORY)
  27. # remove the last /bin directory
  28. get_filename_component(STM32_TOOLCHAIN_PATH ${STM32_TOOLCHAIN_PATH} DIRECTORY)
  29. endif()
  30. endif()
  31. file(TO_CMAKE_PATH "${STM32_TOOLCHAIN_PATH}" STM32_TOOLCHAIN_PATH)
  32. endif()
  33. if(NOT STM32_TARGET_TRIPLET)
  34. set(STM32_TARGET_TRIPLET "arm-none-eabi")
  35. message(STATUS "No STM32_TARGET_TRIPLET specified, using default: " ${STM32_TARGET_TRIPLET})
  36. endif()
  37. set(CMAKE_SYSTEM_NAME Generic)
  38. set(CMAKE_SYSTEM_PROCESSOR arm)
  39. set(TOOLCHAIN_SYSROOT "${STM32_TOOLCHAIN_PATH}/${STM32_TARGET_TRIPLET}")
  40. set(TOOLCHAIN_BIN_PATH "${STM32_TOOLCHAIN_PATH}/bin")
  41. set(TOOLCHAIN_INC_PATH "${STM32_TOOLCHAIN_PATH}/${STM32_TARGET_TRIPLET}/include")
  42. set(TOOLCHAIN_LIB_PATH "${STM32_TOOLCHAIN_PATH}/${STM32_TARGET_TRIPLET}/lib")
  43. find_program(CMAKE_OBJCOPY NAMES ${STM32_TARGET_TRIPLET}-objcopy HINTS ${TOOLCHAIN_BIN_PATH})
  44. find_program(CMAKE_OBJDUMP NAMES ${STM32_TARGET_TRIPLET}-objdump HINTS ${TOOLCHAIN_BIN_PATH})
  45. find_program(CMAKE_SIZE NAMES ${STM32_TARGET_TRIPLET}-size HINTS ${TOOLCHAIN_BIN_PATH})
  46. find_program(CMAKE_DEBUGGER NAMES ${STM32_TARGET_TRIPLET}-gdb HINTS ${TOOLCHAIN_BIN_PATH})
  47. find_program(CMAKE_CPPFILT NAMES ${STM32_TARGET_TRIPLET}-c++filt HINTS ${TOOLCHAIN_BIN_PATH})
  48. function(stm32_print_size_of_target TARGET)
  49. add_custom_target(${TARGET}_always_display_size
  50. ALL COMMAND ${CMAKE_SIZE} ${TARGET}${CMAKE_EXECUTABLE_SUFFIX_C}
  51. COMMENT "Target Sizes: "
  52. DEPENDS ${TARGET}
  53. )
  54. endfunction()
  55. function(stm32_generate_binary_file TARGET)
  56. add_custom_command(
  57. TARGET ${TARGET}
  58. POST_BUILD
  59. COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET}${CMAKE_EXECUTABLE_SUFFIX_C} ${TARGET}.bin
  60. BYPRODUCTS ${TARGET}.bin
  61. COMMENT "Generating binary file ${CMAKE_PROJECT_NAME}.bin"
  62. )
  63. endfunction()
  64. function(stm32_generate_srec_file TARGET)
  65. add_custom_command(
  66. TARGET ${TARGET}
  67. POST_BUILD
  68. COMMAND ${CMAKE_OBJCOPY} -O srec ${TARGET}${CMAKE_EXECUTABLE_SUFFIX_C} ${TARGET}.srec
  69. BYPRODUCTS ${TARGET}.srec
  70. COMMENT "Generating srec file ${CMAKE_PROJECT_NAME}.srec"
  71. )
  72. endfunction()
  73. function(stm32_generate_hex_file TARGET)
  74. add_custom_command(
  75. TARGET ${TARGET}
  76. POST_BUILD
  77. COMMAND ${CMAKE_OBJCOPY} -O ihex ${TARGET}${CMAKE_EXECUTABLE_SUFFIX_C} ${TARGET}.hex
  78. BYPRODUCTS ${TARGET}.hex
  79. COMMENT "Generating hex file ${CMAKE_PROJECT_NAME}.hex"
  80. )
  81. endfunction()
  82. # This function takes FAMILY (e.g. L4) and DEVICE (e.g. L496VG) to output TYPE (e.g. L496xx)
  83. function(stm32_get_chip_type FAMILY DEVICE TYPE)
  84. set(INDEX 0)
  85. foreach(C_TYPE ${STM32_${FAMILY}_TYPES})
  86. list(GET STM32_${FAMILY}_TYPE_MATCH ${INDEX} REGEXP)
  87. if(${DEVICE} MATCHES ${REGEXP})
  88. set(RESULT_TYPE ${C_TYPE})
  89. endif()
  90. math(EXPR INDEX "${INDEX}+1")
  91. endforeach()
  92. if(NOT RESULT_TYPE)
  93. message(FATAL_ERROR "Invalid/unsupported device: ${DEVICE}")
  94. endif()
  95. set(${TYPE} ${RESULT_TYPE} PARENT_SCOPE)
  96. endfunction()
  97. function(stm32_get_chip_info CHIP)
  98. set(ARG_OPTIONS "")
  99. set(ARG_SINGLE FAMILY DEVICE TYPE)
  100. set(ARG_MULTIPLE "")
  101. cmake_parse_arguments(PARSE_ARGV 1 ARG "${ARG_OPTIONS}" "${ARG_SINGLE}" "${ARG_MULTIPLE}")
  102. string(TOUPPER ${CHIP} CHIP)
  103. string(REGEX MATCH "^STM32([FGHLMUW]P?[0-9BL])([0-9A-Z][0-9M][A-Z][0-9A-Z]).*$" CHIP ${CHIP})
  104. if((NOT CMAKE_MATCH_1) OR (NOT CMAKE_MATCH_2))
  105. message(FATAL_ERROR "Unknown chip ${CHIP}")
  106. endif()
  107. set(STM32_FAMILY ${CMAKE_MATCH_1})
  108. set(STM32_DEVICE "${CMAKE_MATCH_1}${CMAKE_MATCH_2}")
  109. if(NOT (${STM32_FAMILY} IN_LIST STM32_SUPPORTED_FAMILIES_SHORT_NAME))
  110. message(FATAL_ERROR "Unsupported family ${STM32_FAMILY} for device ${CHIP}")
  111. endif()
  112. stm32_get_chip_type(${STM32_FAMILY} ${STM32_DEVICE} STM32_TYPE)
  113. if(ARG_FAMILY)
  114. set(${ARG_FAMILY} ${STM32_FAMILY} PARENT_SCOPE)
  115. endif()
  116. if(ARG_DEVICE)
  117. set(${ARG_DEVICE} ${STM32_DEVICE} PARENT_SCOPE)
  118. endif()
  119. if(ARG_TYPE)
  120. set(${ARG_TYPE} ${STM32_TYPE} PARENT_SCOPE)
  121. endif()
  122. endfunction()
  123. function(stm32_get_cores CORES)
  124. set(ARG_OPTIONS "")
  125. set(ARG_SINGLE CHIP FAMILY DEVICE)
  126. set(ARG_MULTIPLE "")
  127. cmake_parse_arguments(PARSE_ARGV 1 ARG "${ARG_OPTIONS}" "${ARG_SINGLE}" "${ARG_MULTIPLE}")
  128. if(ARG_CHIP)
  129. # TODO: I don't get why stm32_get_chip_info is called in stm32_get_cores
  130. stm32_get_chip_info(${ARG_CHIP} FAMILY ARG_FAMILY TYPE ARG_TYPE DEVICE ARG_DEVICE)
  131. elseif(ARG_FAMILY AND ARG_DEVICE)
  132. # TODO: I don't get why stm32_get_chip_type is called in stm32_get_cores
  133. stm32_get_chip_type(${ARG_FAMILY} ${ARG_DEVICE} ARG_TYPE)
  134. elseif(ARG_FAMILY)
  135. if(${ARG_FAMILY} STREQUAL "H7")
  136. set(${CORES} M7 M4 PARENT_SCOPE)
  137. elseif(${ARG_FAMILY} STREQUAL "WB")
  138. set(${CORES} M4 PARENT_SCOPE)
  139. elseif(${ARG_FAMILY} STREQUAL "WL")
  140. set(${CORES} M4 M0PLUS PARENT_SCOPE)
  141. elseif(${ARG_FAMILY} STREQUAL "MP1")
  142. set(${CORES} M4 PARENT_SCOPE)
  143. else()
  144. set(${CORES} "" PARENT_SCOPE)
  145. endif()
  146. return()
  147. else()
  148. message(FATAL_ERROR "Either CHIP or FAMILY or FAMILY/DEVICE should be specified for stm32_get_cores()")
  149. endif()
  150. # TODO following is the only part really used by FindCMSIS. Maybe a cleanup is needed
  151. if(${ARG_FAMILY} STREQUAL "H7")
  152. stm32h7_get_device_cores(${ARG_DEVICE} ${ARG_TYPE} CORE_LIST)
  153. elseif(${ARG_FAMILY} STREQUAL "WB")
  154. # note STM32WB have an M0 core but in current state of the art it runs ST stacks and is not needed/allowed to build for customer
  155. set(CORE_LIST M4)
  156. elseif(${ARG_FAMILY} STREQUAL "MP1")
  157. set(CORE_LIST M4)
  158. elseif(${ARG_FAMILY} STREQUAL "WL")
  159. stm32wl_get_device_cores(${ARG_DEVICE} ${ARG_TYPE} CORE_LIST)
  160. endif()
  161. set(${CORES} "${CORE_LIST}" PARENT_SCOPE)
  162. endfunction()
  163. function(stm32_get_memory_info)
  164. set(ARG_OPTIONS FLASH RAM CCRAM STACK HEAP RAM_SHARE)
  165. set(ARG_SINGLE CHIP FAMILY DEVICE CORE SIZE ORIGIN)
  166. set(ARG_MULTIPLE "")
  167. cmake_parse_arguments(INFO "${ARG_OPTIONS}" "${ARG_SINGLE}" "${ARG_MULTIPLE}" ${ARGN})
  168. if((NOT INFO_CHIP) AND ((NOT INFO_FAMILY) OR (NOT INFO_DEVICE)))
  169. message(FATAL_ERROR "Either CHIP or FAMILY/DEVICE is required for stm32_get_memory_info()")
  170. endif()
  171. if(INFO_CHIP)
  172. stm32_get_chip_info(${INFO_CHIP} FAMILY INFO_FAMILY TYPE INFO_TYPE DEVICE INFO_DEVICE)
  173. else()
  174. stm32_get_chip_type(${INFO_FAMILY} ${INFO_DEVICE} INFO_TYPE)
  175. endif()
  176. string(REGEX REPLACE "^[FGHLMUW]P?[0-9BL][0-9A-Z][0-9M].([3468ABCDEFGHIYZ])$" "\\1" SIZE_CODE ${INFO_DEVICE})
  177. if(SIZE_CODE STREQUAL "3")
  178. set(FLASH "8K")
  179. elseif(SIZE_CODE STREQUAL "4")
  180. set(FLASH "16K")
  181. elseif(SIZE_CODE STREQUAL "6")
  182. set(FLASH "32K")
  183. elseif(SIZE_CODE STREQUAL "8")
  184. set(FLASH "64K")
  185. elseif(SIZE_CODE STREQUAL "B")
  186. set(FLASH "128K")
  187. elseif(SIZE_CODE STREQUAL "C")
  188. set(FLASH "256K")
  189. elseif(SIZE_CODE STREQUAL "D")
  190. set(FLASH "384K")
  191. elseif(SIZE_CODE STREQUAL "E")
  192. set(FLASH "512K")
  193. elseif(SIZE_CODE STREQUAL "F")
  194. set(FLASH "768K")
  195. elseif(SIZE_CODE STREQUAL "G")
  196. set(FLASH "1024K")
  197. elseif(SIZE_CODE STREQUAL "H")
  198. set(FLASH "1536K")
  199. elseif(SIZE_CODE STREQUAL "I")
  200. set(FLASH "2048K")
  201. elseif(SIZE_CODE STREQUAL "Y")
  202. set(FLASH "640K")
  203. elseif(SIZE_CODE STREQUAL "Z")
  204. set(FLASH "192K")
  205. else()
  206. set(FLASH "16K")
  207. message(WARNING "Unknow flash size for device ${DEVICE}. Set to ${FLASH}")
  208. endif()
  209. list(FIND STM32_${INFO_FAMILY}_TYPES ${INFO_TYPE} TYPE_INDEX)
  210. list(GET STM32_${INFO_FAMILY}_RAM_SIZES ${TYPE_INDEX} RAM)
  211. list(GET STM32_${INFO_FAMILY}_CCRAM_SIZES ${TYPE_INDEX} CCRAM)
  212. list(GET STM32_${INFO_FAMILY}_RAM_SHARE_SIZES ${TYPE_INDEX} RAM_SHARE)
  213. set(FLASH_ORIGIN 0x8000000)
  214. set(RAM_ORIGIN 0x20000000)
  215. set(CCRAM_ORIGIN 0x10000000)
  216. set(RAM_SHARE_ORIGIN 0x20030000)
  217. unset(TWO_FLASH_BANKS)
  218. if(FAMILY STREQUAL "F1")
  219. stm32f1_get_memory_info(${INFO_DEVICE} ${INFO_TYPE} FLASH RAM)
  220. elseif(FAMILY STREQUAL "L1")
  221. stm32l1_get_memory_info(${INFO_DEVICE} ${INFO_TYPE} FLASH RAM)
  222. elseif(FAMILY STREQUAL "F2")
  223. stm32f2_get_memory_info(${INFO_DEVICE} ${INFO_TYPE} FLASH RAM)
  224. elseif(FAMILY STREQUAL "F3")
  225. stm32f3_get_memory_info(${INFO_DEVICE} ${INFO_TYPE} FLASH RAM)
  226. elseif(FAMILY STREQUAL "H7")
  227. stm32h7_get_memory_info(${INFO_DEVICE} ${INFO_TYPE} "${INFO_CORE}" RAM FLASH_ORIGIN RAM_ORIGIN TWO_FLASH_BANKS)
  228. elseif(FAMILY STREQUAL "WL")
  229. stm32wl_get_memory_info(${INFO_DEVICE} ${INFO_TYPE} "${INFO_CORE}" RAM FLASH_ORIGIN RAM_ORIGIN TWO_FLASH_BANKS)
  230. elseif(FAMILY STREQUAL "WB")
  231. stm32wb_get_memory_info(${INFO_DEVICE} ${INFO_TYPE} "${INFO_CORE}" RAM RAM_ORIGIN TWO_FLASH_BANKS)
  232. elseif(FAMILY STREQUAL "MP1")
  233. stm32mp1_get_memory_info(${INFO_DEVICE} ${INFO_TYPE} FLASH)
  234. endif()
  235. # when a device is dual core, each core uses half of total flash
  236. if(TWO_FLASH_BANKS)
  237. string(REGEX MATCH "([0-9]+)K" FLASH_KB ${FLASH})
  238. math(EXPR FLASH_KB "${CMAKE_MATCH_1} / 2")
  239. set(FLASH "${FLASH_KB}K")
  240. endif()
  241. if(INFO_FLASH)
  242. set(SIZE ${FLASH})
  243. set(ORIGIN ${FLASH_ORIGIN})
  244. elseif(INFO_RAM)
  245. set(SIZE ${RAM})
  246. set(ORIGIN ${RAM_ORIGIN})
  247. elseif(INFO_CCRAM)
  248. set(SIZE ${CCRAM})
  249. set(ORIGIN ${CCRAM_ORIGIN})
  250. elseif(INFO_RAM_SHARE)
  251. set(SIZE ${RAM_SHARE})
  252. set(ORIGIN ${RAM_SHARE_ORIGIN})
  253. elseif(INFO_STACK)
  254. if (RAM STREQUAL "2K")
  255. set(SIZE 0x200)
  256. else()
  257. set(SIZE 0x400)
  258. endif()
  259. set(ORIGIN ${RAM_ORIGIN}) #TODO: Real stack pointer?
  260. elseif(INFO_HEAP)
  261. if (RAM STREQUAL "2K")
  262. set(SIZE 0x100)
  263. else()
  264. set(SIZE 0x200)
  265. endif()
  266. set(ORIGIN ${RAM_ORIGIN}) #TODO: Real heap pointer?
  267. endif()
  268. if(INFO_SIZE)
  269. set(${INFO_SIZE} ${SIZE} PARENT_SCOPE)
  270. endif()
  271. if(INFO_ORIGIN)
  272. set(${INFO_ORIGIN} ${ORIGIN} PARENT_SCOPE)
  273. endif()
  274. endfunction()
  275. function(stm32_add_linker_script TARGET VISIBILITY SCRIPT)
  276. get_filename_component(SCRIPT "${SCRIPT}" ABSOLUTE)
  277. target_link_options(${TARGET} ${VISIBILITY} -T "${SCRIPT}")
  278. get_target_property(TARGET_TYPE ${TARGET} TYPE)
  279. if(TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
  280. set(INTERFACE_PREFIX "INTERFACE_")
  281. endif()
  282. get_target_property(LINK_DEPENDS ${TARGET} ${INTERFACE_PREFIX}LINK_DEPENDS)
  283. if(LINK_DEPENDS)
  284. list(APPEND LINK_DEPENDS "${SCRIPT}")
  285. else()
  286. set(LINK_DEPENDS "${SCRIPT}")
  287. endif()
  288. set_target_properties(${TARGET} PROPERTIES ${INTERFACE_PREFIX}LINK_DEPENDS "${LINK_DEPENDS}")
  289. endfunction()
  290. if(NOT (TARGET STM32::NoSys))
  291. add_library(STM32::NoSys INTERFACE IMPORTED)
  292. target_compile_options(STM32::NoSys INTERFACE $<$<C_COMPILER_ID:GNU>:--specs=nosys.specs>)
  293. target_link_options(STM32::NoSys INTERFACE $<$<C_COMPILER_ID:GNU>:--specs=nosys.specs>)
  294. endif()
  295. if(NOT (TARGET STM32::Nano))
  296. add_library(STM32::Nano INTERFACE IMPORTED)
  297. target_compile_options(STM32::Nano INTERFACE $<$<C_COMPILER_ID:GNU>:--specs=nano.specs>)
  298. target_link_options(STM32::Nano INTERFACE $<$<C_COMPILER_ID:GNU>:--specs=nano.specs>)
  299. endif()
  300. if(NOT (TARGET STM32::Nano::FloatPrint))
  301. add_library(STM32::Nano::FloatPrint INTERFACE IMPORTED)
  302. target_link_options(STM32::Nano::FloatPrint INTERFACE
  303. $<$<C_COMPILER_ID:GNU>:-Wl,--undefined,_printf_float>
  304. )
  305. endif()
  306. if(NOT (TARGET STM32::Nano::FloatScan))
  307. add_library(STM32::Nano::FloatScan INTERFACE IMPORTED)
  308. target_link_options(STM32::Nano::FloatScan INTERFACE
  309. $<$<C_COMPILER_ID:GNU>:-Wl,--undefined,_scanf_float>
  310. )
  311. endif()
  312. include(stm32/utilities)
  313. include(stm32/f0)
  314. include(stm32/f1)
  315. include(stm32/f2)
  316. include(stm32/f3)
  317. include(stm32/f4)
  318. include(stm32/f7)
  319. include(stm32/g0)
  320. include(stm32/g4)
  321. include(stm32/h7)
  322. include(stm32/l0)
  323. include(stm32/l1)
  324. include(stm32/l4)
  325. include(stm32/l5)
  326. include(stm32/u5)
  327. include(stm32/wb)
  328. include(stm32/wl)
  329. include(stm32/mp1)