FindCMSIS.cmake 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. # For information about why and how of this file: https://cmake.org/cmake/help/latest/command/find_package.html
  2. set(CMSIS_RTOS RTOS RTOS_V2)
  3. if(NOT CMSIS_FIND_COMPONENTS)
  4. set(CMSIS_FIND_COMPONENTS ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
  5. endif()
  6. if(STM32H7 IN_LIST CMSIS_FIND_COMPONENTS)
  7. list(REMOVE_ITEM CMSIS_FIND_COMPONENTS STM32H7)
  8. list(APPEND CMSIS_FIND_COMPONENTS STM32H7_M7 STM32H7_M4)
  9. endif()
  10. if(STM32WB IN_LIST CMSIS_FIND_COMPONENTS)
  11. list(REMOVE_ITEM CMSIS_FIND_COMPONENTS STM32WB)
  12. list(APPEND CMSIS_FIND_COMPONENTS STM32WB_M4)
  13. endif()
  14. if(STM32WL IN_LIST CMSIS_FIND_COMPONENTS)
  15. list(REMOVE_ITEM CMSIS_FIND_COMPONENTS STM32WL)
  16. list(APPEND CMSIS_FIND_COMPONENTS STM32WL_M4 STM32WL_M0PLUS)
  17. endif()
  18. if(STM32MP1 IN_LIST CMSIS_FIND_COMPONENTS)
  19. list(REMOVE_ITEM CMSIS_FIND_COMPONENTS STM32MP1)
  20. list(APPEND CMSIS_FIND_COMPONENTS STM32MP1_M4)
  21. endif()
  22. list(REMOVE_DUPLICATES CMSIS_FIND_COMPONENTS)
  23. # This section fills the RTOS or family components list
  24. foreach(COMP ${CMSIS_FIND_COMPONENTS})
  25. string(TOLOWER ${COMP} COMP_L)
  26. string(TOUPPER ${COMP} COMP)
  27. # Component is RTOS component
  28. if(${COMP} IN_LIST CMSIS_RTOS)
  29. list(APPEND CMSIS_FIND_COMPONENTS_RTOS ${COMP})
  30. continue()
  31. endif()
  32. # Component is not RTOS component, so check whether it is a family component
  33. string(REGEX MATCH "^STM32([CFGHLMUW]P?[0-9BL])([0-9A-Z][0-9M][A-Z][0-9A-Z])?_?(M0PLUS|M4|M7)?.*$" COMP ${COMP})
  34. if(CMAKE_MATCH_1)
  35. list(APPEND CMSIS_FIND_COMPONENTS_FAMILIES ${COMP})
  36. endif()
  37. endforeach()
  38. if(NOT CMSIS_FIND_COMPONENTS_FAMILIES)
  39. set(CMSIS_FIND_COMPONENTS_FAMILIES ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
  40. endif()
  41. if(NOT CMSIS_FIND_COMPONENTS_RTOS)
  42. set(CMSIS_FIND_COMPONENTS_RTOS ${CMSIS_RTOS})
  43. endif()
  44. message(STATUS "Search for CMSIS families: ${CMSIS_FIND_COMPONENTS_FAMILIES}")
  45. message(STATUS "Search for CMSIS RTOS: ${CMSIS_FIND_COMPONENTS_RTOS}")
  46. include(stm32/devices)
  47. function(cmsis_generate_default_linker_script FAMILY DEVICE CORE)
  48. if(CORE)
  49. set(CORE_C "::${CORE}")
  50. set(CORE_U "_${CORE}")
  51. endif()
  52. set(OUTPUT_LD_FILE "${CMAKE_CURRENT_BINARY_DIR}/${DEVICE}${CORE_U}.ld")
  53. if(${FAMILY} STREQUAL MP1)
  54. string(TOLOWER ${FAMILY} FAMILY_L)
  55. find_file(CMSIS_${FAMILY}${CORE_U}_LD_SCRIPT
  56. NAMES stm32mp15xx_m4.ld
  57. PATHS "${CMSIS_${FAMILY}${CORE_U}_PATH}/Source/Templates/gcc/linker"
  58. NO_DEFAULT_PATH
  59. )
  60. add_custom_command(OUTPUT "${OUTPUT_LD_FILE}"
  61. COMMAND ${CMAKE_COMMAND}
  62. -E copy ${CMSIS_${FAMILY}${CORE_U}_LD_SCRIPT} ${OUTPUT_LD_FILE})
  63. else()
  64. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} FLASH SIZE FLASH_SIZE ORIGIN FLASH_ORIGIN)
  65. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} RAM SIZE RAM_SIZE ORIGIN RAM_ORIGIN)
  66. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} CCRAM SIZE CCRAM_SIZE ORIGIN CCRAM_ORIGIN)
  67. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} RAM_SHARE SIZE RAM_SHARE_SIZE ORIGIN RAM_SHARE_ORIGIN)
  68. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} HEAP SIZE HEAP_SIZE)
  69. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} STACK SIZE STACK_SIZE)
  70. add_custom_command(OUTPUT "${OUTPUT_LD_FILE}"
  71. COMMAND ${CMAKE_COMMAND}
  72. -DFLASH_ORIGIN="${FLASH_ORIGIN}"
  73. -DRAM_ORIGIN="${RAM_ORIGIN}"
  74. -DCCRAM_ORIGIN="${CCRAM_ORIGIN}"
  75. -DRAM_SHARE_ORIGIN="${RAM_SHARE_ORIGIN}"
  76. -DFLASH_SIZE="${FLASH_SIZE}"
  77. -DRAM_SIZE="${RAM_SIZE}"
  78. -DCCRAM_SIZE="${CCRAM_SIZE}"
  79. -DRAM_SHARE_SIZE="${RAM_SHARE_SIZE}"
  80. -DSTACK_SIZE="${STACK_SIZE}"
  81. -DHEAP_SIZE="${HEAP_SIZE}"
  82. -DLINKER_SCRIPT="${OUTPUT_LD_FILE}"
  83. -P "${STM32_CMAKE_DIR}/stm32/linker_ld.cmake"
  84. )
  85. endif()
  86. add_custom_target(CMSIS_LD_${DEVICE}${CORE_U} DEPENDS "${OUTPUT_LD_FILE}")
  87. add_dependencies(CMSIS::STM32::${DEVICE}${CORE_C} CMSIS_LD_${DEVICE}${CORE_U})
  88. stm32_add_linker_script(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE "${OUTPUT_LD_FILE}")
  89. endfunction()
  90. foreach(COMP ${CMSIS_FIND_COMPONENTS_FAMILIES})
  91. string(TOLOWER ${COMP} COMP_L)
  92. string(TOUPPER ${COMP} COMP)
  93. string(REGEX MATCH "^STM32([CFGHLMUW]P?[0-9BL])([0-9A-Z][0-9M][A-Z][0-9A-Z])?_?(M0PLUS|M4|M7)?.*$" COMP ${COMP})
  94. # CMAKE_MATCH_<n> contains n'th subexpression
  95. # CMAKE_MATCH_0 contains full match
  96. if((NOT CMAKE_MATCH_1) AND (NOT CMAKE_MATCH_2))
  97. message(FATAL_ERROR "Unknown CMSIS component: ${COMP}")
  98. endif()
  99. if(CMAKE_MATCH_2)
  100. set(FAMILY ${CMAKE_MATCH_1})
  101. set(STM_DEVICES "${CMAKE_MATCH_1}${CMAKE_MATCH_2}")
  102. message(TRACE "FindCMSIS: full device name match for COMP ${COMP}, STM_DEVICES is ${STM_DEVICES}")
  103. else()
  104. set(FAMILY ${CMAKE_MATCH_1})
  105. stm32_get_devices_by_family(STM_DEVICES FAMILY ${FAMILY})
  106. message(TRACE "FindCMSIS: family only match for COMP ${COMP}, STM_DEVICES is ${STM_DEVICES}")
  107. endif()
  108. if(CMAKE_MATCH_3)
  109. set(CORE ${CMAKE_MATCH_3})
  110. set(CORE_C "::${CORE}")
  111. set(CORE_U "_${CORE}")
  112. set(CORE_Ucm "_c${CORE}")
  113. string(TOLOWER ${CORE_Ucm} CORE_Ucm)
  114. message(TRACE "FindCMSIS: core match in component name for COMP ${COMP}. CORE is ${CORE}")
  115. else()
  116. unset(CORE)
  117. unset(CORE_C)
  118. unset(CORE_U)
  119. unset(CORE_Ucm)
  120. endif()
  121. string(TOLOWER ${FAMILY} FAMILY_L)
  122. if((NOT STM32_CMSIS_${FAMILY}_PATH) AND (NOT STM32_CUBE_${FAMILY}_PATH) AND (DEFINED ENV{STM32_CUBE_${FAMILY}_PATH}))
  123. # try to set path from environment variable. Note it could be ...-NOT-FOUND and it's fine
  124. set(STM32_CUBE_${FAMILY}_PATH $ENV{STM32_CUBE_${FAMILY}_PATH} CACHE PATH "Path to STM32Cube${FAMILY}")
  125. message(STATUS "ENV STM32_CUBE_${FAMILY}_PATH specified, using STM32_CUBE_${FAMILY}_PATH: ${STM32_CUBE_${FAMILY}_PATH}")
  126. endif()
  127. if((NOT STM32_CMSIS_${FAMILY}_PATH) AND (NOT STM32_CUBE_${FAMILY}_PATH))
  128. set(STM32_CUBE_${FAMILY}_PATH /opt/STM32Cube${FAMILY} CACHE PATH "Path to STM32Cube${FAMILY}")
  129. message(STATUS "Neither STM32_CUBE_${FAMILY}_PATH nor STM32_CMSIS_${FAMILY}_PATH specified using default STM32_CUBE_${FAMILY}_PATH: ${STM32_CUBE_${FAMILY}_PATH}")
  130. endif()
  131. # search for Include/cmsis_gcc.h
  132. find_path(CMSIS_${FAMILY}${CORE_U}_CORE_PATH
  133. NAMES Include/cmsis_gcc.h
  134. PATHS "${STM32_CMSIS_PATH}" "${STM32_CUBE_${FAMILY}_PATH}/Drivers/CMSIS"
  135. NO_DEFAULT_PATH
  136. )
  137. if (NOT CMSIS_${FAMILY}${CORE_U}_CORE_PATH)
  138. message(VERBOSE "FindCMSIS: cmsis_gcc.h for ${FAMILY}${CORE_U} has not been found")
  139. continue()
  140. endif()
  141. # search for Include/stm32[XX]xx.h
  142. find_path(CMSIS_${FAMILY}${CORE_U}_PATH
  143. NAMES Include/stm32${FAMILY_L}xx.h
  144. PATHS "${STM32_CMSIS_${FAMILY}_PATH}" "${STM32_CUBE_${FAMILY}_PATH}/Drivers/CMSIS/Device/ST/STM32${FAMILY}xx"
  145. NO_DEFAULT_PATH
  146. )
  147. if (NOT CMSIS_${FAMILY}${CORE_U}_PATH)
  148. message(VERBOSE "FindCMSIS: stm32${FAMILY_L}xx.h for ${FAMILY}${CORE_U} has not been found")
  149. continue()
  150. endif()
  151. list(APPEND CMSIS_INCLUDE_DIRS "${CMSIS_${FAMILY}${CORE_U}_CORE_PATH}/Include" "${CMSIS_${FAMILY}${CORE_U}_PATH}/Include")
  152. if(NOT CMSIS_${FAMILY}${CORE_U}_VERSION)
  153. find_file(CMSIS_${FAMILY}${CORE_U}_PDSC
  154. NAMES ARM.CMSIS.pdsc
  155. PATHS "${CMSIS_${FAMILY}${CORE_U}_CORE_PATH}"
  156. NO_DEFAULT_PATH
  157. )
  158. if (NOT CMSIS_${FAMILY}${CORE_U}_PDSC)
  159. set(CMSIS_${FAMILY}${CORE_U}_VERSION "0.0.0")
  160. else()
  161. file(STRINGS "${CMSIS_${FAMILY}${CORE_U}_PDSC}" VERSION_STRINGS REGEX "<release version=\"([0-9]*\\.[0-9]*\\.[0-9]*)\" date=\"[0-9]+\\-[0-9]+\\-[0-9]+\">")
  162. list(GET VERSION_STRINGS 0 STR)
  163. string(REGEX MATCH "<release version=\"([0-9]*)\\.([0-9]*)\\.([0-9]*)\" date=\"[0-9]+\\-[0-9]+\\-[0-9]+\">" MATCHED ${STR})
  164. set(CMSIS_${FAMILY}${CORE_U}_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" CACHE INTERNAL "CMSIS STM32${FAMILY}${CORE_U} version")
  165. endif()
  166. endif()
  167. set(CMSIS_${COMP}_VERSION ${CMSIS_${FAMILY}${CORE_U}_VERSION})
  168. set(CMSIS_VERSION ${CMSIS_${COMP}_VERSION})
  169. if(NOT (TARGET CMSIS::STM32::${FAMILY}${CORE_C}))
  170. message(TRACE "FindCMSIS: creating library CMSIS::STM32::${FAMILY}${CORE_C}")
  171. add_library(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE IMPORTED)
  172. #STM32::${FAMILY}${CORE_C} contains compile options and is define in <family>.cmake
  173. target_link_libraries(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE STM32::${FAMILY}${CORE_C})
  174. target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_CORE_PATH}/Include")
  175. target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_PATH}/Include")
  176. endif()
  177. # search for system_stm32[XX]xx.c
  178. find_file(CMSIS_${FAMILY}${CORE_U}_SYSTEM
  179. NAMES system_stm32${FAMILY_L}xx.c
  180. PATHS "${CMSIS_${FAMILY}${CORE_U}_PATH}/Source/Templates"
  181. NO_DEFAULT_PATH
  182. )
  183. list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_SYSTEM}")
  184. if(NOT CMSIS_${FAMILY}${CORE_U}_SYSTEM)
  185. message(VERBOSE "FindCMSIS: system_stm32${FAMILY_L}xx.c for ${FAMILY}${CORE_U} has not been found")
  186. continue()
  187. endif()
  188. set(STM_DEVICES_FOUND TRUE)
  189. foreach(DEVICE ${STM_DEVICES})
  190. message(TRACE "FindCMSIS: Iterating DEVICE ${DEVICE}")
  191. stm32_get_cores(DEV_CORES FAMILY ${FAMILY} DEVICE ${DEVICE})
  192. if(CORE AND (NOT ${CORE} IN_LIST DEV_CORES))
  193. message(TRACE "FindCMSIS: skip device because CORE ${CORE} provided doesn't correspond to FAMILY ${FAMILY} DEVICE ${DEVICE}")
  194. continue()
  195. endif()
  196. stm32_get_chip_type(${FAMILY} ${DEVICE} TYPE)
  197. string(TOLOWER ${DEVICE} DEVICE_L)
  198. string(TOLOWER ${TYPE} TYPE_L)
  199. get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
  200. if(NOT "ASM" IN_LIST languages)
  201. message(STATUS "FindCMSIS: Not generating target for startup file and linker script because ASM language is not enabled")
  202. continue()
  203. endif()
  204. find_file(CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP
  205. NAMES startup_stm32${TYPE_L}.s
  206. startup_stm32${TYPE_L}${CORE_Ucm}.s
  207. PATHS "${CMSIS_${FAMILY}${CORE_U}_PATH}/Source/Templates/gcc"
  208. NO_DEFAULT_PATH
  209. )
  210. list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP}")
  211. if(NOT CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP)
  212. set(STM_DEVICES_FOUND FALSE)
  213. message(VERBOSE "FindCMSIS: did not find file: startup_stm32${TYPE_L}.s or startup_stm32${TYPE_L}${CORE_Ucm}.s")
  214. break()
  215. endif()
  216. if(NOT (TARGET CMSIS::STM32::${TYPE}${CORE_C}))
  217. message(TRACE "FindCMSIS: creating library CMSIS::STM32::${TYPE}${CORE_C}")
  218. add_library(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE IMPORTED)
  219. target_link_libraries(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE CMSIS::STM32::${FAMILY}${CORE_C} STM32::${TYPE}${CORE_C})
  220. target_sources(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP}")
  221. target_sources(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_SYSTEM}")
  222. endif()
  223. add_library(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE IMPORTED)
  224. target_link_libraries(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE CMSIS::STM32::${TYPE}${CORE_C})
  225. cmsis_generate_default_linker_script(${FAMILY} ${DEVICE} "${CORE}")
  226. endforeach()
  227. if(STM_DEVICES_FOUND)
  228. set(CMSIS_${COMP}_FOUND TRUE)
  229. message(DEBUG "CMSIS_${COMP}_FOUND TRUE")
  230. else()
  231. set(CMSIS_${COMP}_FOUND FALSE)
  232. message(DEBUG "CMSIS_${COMP}_FOUND FALSE")
  233. endif()
  234. foreach(RTOS_COMP ${CMSIS_FIND_COMPONENTS_RTOS})
  235. if (${RTOS_COMP} STREQUAL "RTOS_V2")
  236. set(RTOS_COMP_VERSION "2")
  237. else()
  238. unset(RTOS_COMP_VERSION)
  239. endif()
  240. find_path(CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH
  241. NAMES "cmsis_os${RTOS_COMP_VERSION}.h"
  242. PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_${RTOS_COMP}"
  243. NO_DEFAULT_PATH
  244. )
  245. if (NOT CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH)
  246. continue()
  247. endif()
  248. find_file(CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE
  249. NAMES "cmsis_os${RTOS_COMP_VERSION}.c"
  250. PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_${RTOS_COMP}"
  251. NO_DEFAULT_PATH
  252. )
  253. if (NOT CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE)
  254. continue()
  255. endif()
  256. if(NOT (TARGET CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP}))
  257. add_library(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE IMPORTED)
  258. target_link_libraries(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE CMSIS::STM32::${FAMILY}${CORE_C})
  259. target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH}")
  260. target_sources(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE}")
  261. endif()
  262. list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE}")
  263. list(APPEND CMSIS_INCLUDE_DIRS "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH}")
  264. set(CMSIS_${RTOS_COMP}_FOUND TRUE)
  265. endforeach()
  266. list(REMOVE_DUPLICATES CMSIS_INCLUDE_DIRS)
  267. list(REMOVE_DUPLICATES CMSIS_SOURCES)
  268. endforeach()
  269. include(FindPackageHandleStandardArgs)
  270. find_package_handle_standard_args(CMSIS
  271. REQUIRED_VARS CMSIS_INCLUDE_DIRS CMSIS_SOURCES
  272. FOUND_VAR CMSIS_FOUND
  273. VERSION_VAR CMSIS_VERSION
  274. HANDLE_COMPONENTS
  275. )