FindCMSIS.cmake 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. # For information about why and how of this file: https://cmake.org/cmake/help/latest/command/find_package.html
  2. if(NOT CMSIS_FIND_COMPONENTS)
  3. set(CMSIS_FIND_COMPONENTS ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
  4. endif()
  5. if(STM32H7 IN_LIST CMSIS_FIND_COMPONENTS)
  6. list(REMOVE_ITEM CMSIS_FIND_COMPONENTS STM32H7)
  7. list(APPEND CMSIS_FIND_COMPONENTS STM32H7_M7 STM32H7_M4)
  8. endif()
  9. if(STM32WB IN_LIST CMSIS_FIND_COMPONENTS)
  10. list(REMOVE_ITEM CMSIS_FIND_COMPONENTS STM32WB)
  11. list(APPEND CMSIS_FIND_COMPONENTS STM32WB_M4)
  12. endif()
  13. if(STM32WL IN_LIST CMSIS_FIND_COMPONENTS)
  14. list(REMOVE_ITEM CMSIS_FIND_COMPONENTS STM32WL)
  15. list(APPEND CMSIS_FIND_COMPONENTS STM32WL_M4 STM32WL_M0PLUS)
  16. endif()
  17. list(REMOVE_DUPLICATES CMSIS_FIND_COMPONENTS)
  18. include(stm32/devices)
  19. function(cmsis_generate_default_linker_script FAMILY DEVICE CORE)
  20. if(CORE)
  21. set(CORE_C "::${CORE}")
  22. set(CORE_U "_${CORE}")
  23. endif()
  24. set(OUTPUT_LD_FILE "${CMAKE_CURRENT_BINARY_DIR}/${DEVICE}${CORE_U}.ld")
  25. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} FLASH SIZE FLASH_SIZE ORIGIN FLASH_ORIGIN)
  26. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} RAM SIZE RAM_SIZE ORIGIN RAM_ORIGIN)
  27. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} CCRAM SIZE CCRAM_SIZE ORIGIN CCRAM_ORIGIN)
  28. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} RAM_SHARE SIZE RAM_SHARE_SIZE ORIGIN RAM_SHARE_ORIGIN)
  29. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} HEAP SIZE HEAP_SIZE)
  30. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} STACK SIZE STACK_SIZE)
  31. add_custom_command(OUTPUT "${OUTPUT_LD_FILE}"
  32. COMMAND ${CMAKE_COMMAND}
  33. -DFLASH_ORIGIN="${FLASH_ORIGIN}"
  34. -DRAM_ORIGIN="${RAM_ORIGIN}"
  35. -DCCRAM_ORIGIN="${CCRAM_ORIGIN}"
  36. -DRAM_SHARE_ORIGIN="${RAM_SHARE_ORIGIN}"
  37. -DFLASH_SIZE="${FLASH_SIZE}"
  38. -DRAM_SIZE="${RAM_SIZE}"
  39. -DCCRAM_SIZE="${CCRAM_SIZE}"
  40. -DRAM_SHARE_SIZE="${RAM_SHARE_SIZE}"
  41. -DSTACK_SIZE="${STACK_SIZE}"
  42. -DHEAP_SIZE="${HEAP_SIZE}"
  43. -DLINKER_SCRIPT="${OUTPUT_LD_FILE}"
  44. -P "${STM32_CMAKE_DIR}/stm32/linker_ld.cmake"
  45. )
  46. add_custom_target(CMSIS_LD_${DEVICE}${CORE_U} DEPENDS "${OUTPUT_LD_FILE}")
  47. add_dependencies(CMSIS::STM32::${DEVICE}${CORE_C} CMSIS_LD_${DEVICE}${CORE_U})
  48. stm32_add_linker_script(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE "${OUTPUT_LD_FILE}")
  49. endfunction()
  50. foreach(COMP ${CMSIS_FIND_COMPONENTS})
  51. string(TOLOWER ${COMP} COMP_L)
  52. string(TOUPPER ${COMP} COMP)
  53. string(REGEX MATCH "^STM32([FGHLW][0-9BL])([0-9A-Z][0-9M][A-Z][0-9A-Z])?_?(M0PLUS|M4|M7)?.*$" COMP ${COMP})
  54. # CMAKE_MATCH_<n> contains n'th subexpression
  55. # CMAKE_MATCH_0 contains full match
  56. if((NOT CMAKE_MATCH_1) AND (NOT CMAKE_MATCH_2))
  57. message(FATAL_ERROR "Unknown CMSIS component: ${COMP}")
  58. endif()
  59. if(CMAKE_MATCH_2)
  60. set(FAMILY ${CMAKE_MATCH_1})
  61. set(DEVICES "${CMAKE_MATCH_1}${CMAKE_MATCH_2}")
  62. message(TRACE "FindCMSIS: full device name match for COMP ${COMP}, DEVICES is ${DEVICES}")
  63. else()
  64. set(FAMILY ${CMAKE_MATCH_1})
  65. stm32_get_devices_by_family(DEVICES FAMILY ${FAMILY})
  66. message(TRACE "FindCMSIS: family only match for COMP ${COMP}, DEVICES is ${DEVICES}")
  67. endif()
  68. if(CMAKE_MATCH_3)
  69. set(CORE ${CMAKE_MATCH_3})
  70. set(CORE_C "::${CORE}")
  71. set(CORE_U "_${CORE}")
  72. set(CORE_Ucm "_c${CORE}")
  73. string(TOLOWER ${CORE_Ucm} CORE_Ucm)
  74. message(TRACE "FindCMSIS: core match in component name for COMP ${COMP}. CORE is ${CORE}")
  75. else()
  76. unset(CORE)
  77. unset(CORE_C)
  78. unset(CORE_U)
  79. unset(CORE_Ucm)
  80. endif()
  81. string(TOLOWER ${FAMILY} FAMILY_L)
  82. if((NOT STM32_CMSIS_${FAMILY}_PATH) AND (NOT STM32_CUBE_${FAMILY}_PATH))
  83. # try to set path from environment variable. Note it could be ...-NOT-FOUND and it's fine
  84. set(STM32_CUBE_${FAMILY}_PATH $ENV{STM32_CUBE_${FAMILY}_PATH} CACHE PATH "Path to STM32Cube${FAMILY}")
  85. endif()
  86. if((NOT STM32_CMSIS_${FAMILY}_PATH) AND (NOT STM32_CUBE_${FAMILY}_PATH))
  87. set(STM32_CUBE_${FAMILY}_PATH /opt/STM32Cube${FAMILY} CACHE PATH "Path to STM32Cube${FAMILY}")
  88. message(STATUS "Neither STM32_CUBE_${FAMILY}_PATH nor STM32_CMSIS_${FAMILY}_PATH specified using default STM32_CUBE_${FAMILY}_PATH: ${STM32_CUBE_${FAMILY}_PATH}")
  89. endif()
  90. # search for Include/cmsis_gcc.h
  91. find_path(CMSIS_${FAMILY}${CORE_U}_CORE_PATH
  92. NAMES Include/cmsis_gcc.h
  93. PATHS "${STM32_CMSIS_PATH}" "${STM32_CUBE_${FAMILY}_PATH}/Drivers/CMSIS"
  94. NO_DEFAULT_PATH
  95. )
  96. if (NOT CMSIS_${FAMILY}${CORE_U}_CORE_PATH)
  97. message(VERBOSE "FindCMSIS: cmsis_gcc.h for ${FAMILY}${CORE_U} has not been found")
  98. continue()
  99. endif()
  100. # search for Include/stm32[XX]xx.h
  101. find_path(CMSIS_${FAMILY}${CORE_U}_PATH
  102. NAMES Include/stm32${FAMILY_L}xx.h
  103. PATHS "${STM32_CMSIS_${FAMILY}_PATH}" "${STM32_CUBE_${FAMILY}_PATH}/Drivers/CMSIS/Device/ST/STM32${FAMILY}xx"
  104. NO_DEFAULT_PATH
  105. )
  106. if (NOT CMSIS_${FAMILY}${CORE_U}_PATH)
  107. message(VERBOSE "FindCMSIS: stm32${FAMILY_L}xx.h for ${FAMILY}${CORE_U} has not been found")
  108. continue()
  109. endif()
  110. list(APPEND CMSIS_INCLUDE_DIRS "${CMSIS_${FAMILY}${CORE_U}_CORE_PATH}/Include" "${CMSIS_${FAMILY}${CORE_U}_PATH}/Include")
  111. if(NOT CMSIS_${FAMILY}${CORE_U}_VERSION)
  112. find_file(CMSIS_${FAMILY}${CORE_U}_PDSC
  113. NAMES ARM.CMSIS.pdsc
  114. PATHS "${CMSIS_${FAMILY}${CORE_U}_CORE_PATH}"
  115. NO_DEFAULT_PATH
  116. )
  117. if (NOT CMSIS_${FAMILY}${CORE_U}_PDSC)
  118. set(CMSIS_${FAMILY}${CORE_U}_VERSION "0.0.0")
  119. else()
  120. 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]+\">")
  121. list(GET VERSION_STRINGS 0 STR)
  122. string(REGEX MATCH "<release version=\"([0-9]*)\\.([0-9]*)\\.([0-9]*)\" date=\"[0-9]+\\-[0-9]+\\-[0-9]+\">" MATCHED ${STR})
  123. set(CMSIS_${FAMILY}${CORE_U}_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" CACHE INTERNAL "CMSIS STM32${FAMILY}${CORE_U} version")
  124. endif()
  125. endif()
  126. set(CMSIS_${COMP}_VERSION ${CMSIS_${FAMILY}${CORE_U}_VERSION})
  127. set(CMSIS_VERSION ${CMSIS_${COMP}_VERSION})
  128. # search for system_stm32[XX]xx.c
  129. find_file(CMSIS_${FAMILY}${CORE_U}_SOURCE
  130. NAMES system_stm32${FAMILY_L}xx.c
  131. PATHS "${CMSIS_${FAMILY}${CORE_U}_PATH}/Source/Templates"
  132. NO_DEFAULT_PATH
  133. )
  134. list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_SOURCE}")
  135. if(NOT CMSIS_${FAMILY}${CORE_U}_SOURCE)
  136. message(VERBOSE "FindCMSIS: system_stm32${FAMILY_L}xx.c for ${FAMILY}${CORE_U} has not been found")
  137. continue()
  138. endif()
  139. if(NOT (TARGET CMSIS::STM32::${FAMILY}${CORE_C}))
  140. message(TRACE "FindCMSIS: creating library CMSIS::STM32::${FAMILY}${CORE_C}")
  141. add_library(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE IMPORTED)
  142. target_link_libraries(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE STM32::${FAMILY}${CORE_C})
  143. target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_CORE_PATH}/Include")
  144. target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_PATH}/Include")
  145. target_sources(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_SOURCE}")
  146. endif()
  147. set(DEVICES_FOUND TRUE)
  148. foreach(DEVICE ${DEVICES})
  149. message(TRACE "FindCMSIS: Iterating DEVICE ${DEVICE}")
  150. stm32_get_cores(DEV_CORES FAMILY ${FAMILY} DEVICE ${DEVICE})
  151. if(CORE AND (NOT ${CORE} IN_LIST DEV_CORES))
  152. message(TRACE "FindCMSIS: skip device because CORE ${CORE} provided doesn't correspond to FAMILY ${FAMILY} DEVICE ${DEVICE}")
  153. continue()
  154. endif()
  155. stm32_get_chip_type(${FAMILY} ${DEVICE} TYPE)
  156. string(TOLOWER ${DEVICE} DEVICE_L)
  157. string(TOLOWER ${TYPE} TYPE_L)
  158. find_file(CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP
  159. NAMES startup_stm32${TYPE_L}.s startup_stm32${TYPE_L}${CORE_Ucm}.s
  160. PATHS "${CMSIS_${FAMILY}${CORE_U}_PATH}/Source/Templates/gcc"
  161. NO_DEFAULT_PATH
  162. )
  163. list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP}")
  164. if(NOT CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP)
  165. set(DEVICES_FOUND FALSE)
  166. message(VERBOSE "FindCMSIS: did not find file: startup_stm32${TYPE_L}.s or startup_stm32${TYPE_L}${CORE_Ucm}.s")
  167. break()
  168. endif()
  169. if(NOT (TARGET CMSIS::STM32::${TYPE}${CORE_C}))
  170. message(TRACE "FindCMSIS: creating library CMSIS::STM32::${TYPE}${CORE_C}")
  171. add_library(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE IMPORTED)
  172. target_link_libraries(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE CMSIS::STM32::${FAMILY}${CORE_C} STM32::${TYPE}${CORE_C})
  173. target_sources(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP}")
  174. endif()
  175. add_library(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE IMPORTED)
  176. target_link_libraries(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE CMSIS::STM32::${TYPE}${CORE_C})
  177. cmsis_generate_default_linker_script(${FAMILY} ${DEVICE} "${CORE}")
  178. endforeach()
  179. if(DEVICES_FOUND)
  180. set(CMSIS_${COMP}_FOUND TRUE)
  181. message(DEBUG "CMSIS_${COMP}_FOUND TRUE")
  182. else()
  183. set(CMSIS_${COMP}_FOUND FALSE)
  184. message(DEBUG "CMSIS_${COMP}_FOUND FALSE")
  185. endif()
  186. list(REMOVE_DUPLICATES CMSIS_INCLUDE_DIRS)
  187. list(REMOVE_DUPLICATES CMSIS_SOURCES)
  188. endforeach()
  189. include(FindPackageHandleStandardArgs)
  190. find_package_handle_standard_args(CMSIS
  191. REQUIRED_VARS CMSIS_INCLUDE_DIRS CMSIS_SOURCES
  192. FOUND_VAR CMSIS_FOUND
  193. VERSION_VAR CMSIS_VERSION
  194. HANDLE_COMPONENTS
  195. )