FindCMSIS.cmake 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. set(CMSIS_RTOS RTOS RTOS_V2)
  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. list(REMOVE_DUPLICATES CMSIS_FIND_COMPONENTS)
  10. # This section fills the RTOS or family components list
  11. foreach(COMP ${CMSIS_FIND_COMPONENTS})
  12. string(TOLOWER ${COMP} COMP_L)
  13. string(TOUPPER ${COMP} COMP)
  14. # Component is RTOS component
  15. if(${COMP} IN_LIST CMSIS_RTOS)
  16. list(APPEND CMSIS_FIND_COMPONENTS_RTOS ${COMP})
  17. continue()
  18. endif()
  19. # Component is not RTOS component, so check whether it is a family component
  20. string(REGEX MATCH "^STM32([A-Z][0-9])([0-9A-Z][0-9][A-Z][0-9A-Z])?_?(M[47])?.*$" COMP ${COMP})
  21. if(CMAKE_MATCH_1)
  22. list(APPEND CMSIS_FIND_COMPONENTS_FAMILIES ${COMP})
  23. endif()
  24. endforeach()
  25. if(NOT CMSIS_FIND_COMPONENTS_FAMILIES)
  26. set(CMSIS_FIND_COMPONENTS_FAMILIES ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
  27. endif()
  28. if(NOT CMSIS_FIND_COMPONENTS_RTOS)
  29. set(CMSIS_FIND_COMPONENTS_RTOS ${CMSIS_RTOS})
  30. endif()
  31. message(STATUS "Search for CMSIS families: ${CMSIS_FIND_COMPONENTS_FAMILIES}")
  32. message(STATUS "Search for CMSIS RTOS: ${CMSIS_FIND_COMPONENTS_RTOS}")
  33. include(stm32/devices)
  34. function(cmsis_generate_default_linker_script FAMILY DEVICE CORE)
  35. if(CORE)
  36. set(CORE_C "::${CORE}")
  37. set(CORE_U "_${CORE}")
  38. endif()
  39. set(OUTPUT_LD_FILE "${CMAKE_CURRENT_BINARY_DIR}/${DEVICE}${CORE_U}.ld")
  40. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} FLASH SIZE FLASH_SIZE ORIGIN FLASH_ORIGIN)
  41. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} RAM SIZE RAM_SIZE ORIGIN RAM_ORIGIN)
  42. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} CCRAM SIZE CCRAM_SIZE ORIGIN CCRAM_ORIGIN)
  43. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} HEAP SIZE HEAP_SIZE)
  44. stm32_get_memory_info(FAMILY ${FAMILY} DEVICE ${DEVICE} CORE ${CORE} STACK SIZE STACK_SIZE)
  45. add_custom_command(OUTPUT "${OUTPUT_LD_FILE}"
  46. COMMAND ${CMAKE_COMMAND}
  47. -DFLASH_ORIGIN="${FLASH_ORIGIN}"
  48. -DRAM_ORIGIN="${RAM_ORIGIN}"
  49. -DCCRAM_ORIGIN="${CCRAM_ORIGIN}"
  50. -DFLASH_SIZE="${FLASH_SIZE}"
  51. -DRAM_SIZE="${RAM_SIZE}"
  52. -DCCRAM_SIZE="${CCRAM_SIZE}"
  53. -DSTACK_SIZE="${STACK_SIZE}"
  54. -DHEAP_SIZE="${HEAP_SIZE}"
  55. -DLINKER_SCRIPT="${OUTPUT_LD_FILE}"
  56. -P "${STM32_CMAKE_DIR}/stm32/linker_ld.cmake"
  57. )
  58. add_custom_target(CMSIS_LD_${DEVICE}${CORE_U} DEPENDS "${OUTPUT_LD_FILE}")
  59. add_dependencies(CMSIS::STM32::${DEVICE}${CORE_C} CMSIS_LD_${DEVICE}${CORE_U})
  60. stm32_add_linker_script(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE "${OUTPUT_LD_FILE}")
  61. endfunction()
  62. foreach(COMP ${CMSIS_FIND_COMPONENTS_FAMILIES})
  63. string(TOLOWER ${COMP} COMP_L)
  64. string(TOUPPER ${COMP} COMP)
  65. string(REGEX MATCH "^STM32([A-Z][0-9])([0-9A-Z][0-9][A-Z][0-9A-Z])?_?(M[47])?.*$" COMP ${COMP})
  66. if((NOT CMAKE_MATCH_1) AND (NOT CMAKE_MATCH_2))
  67. message(FATAL_ERROR "Unknown CMSIS component: ${COMP}")
  68. endif()
  69. if(CMAKE_MATCH_2)
  70. set(FAMILY ${CMAKE_MATCH_1})
  71. set(STM_DEVICES "${CMAKE_MATCH_1}${CMAKE_MATCH_2}")
  72. else()
  73. set(FAMILY ${CMAKE_MATCH_1})
  74. stm32_get_devices_by_family(STM_DEVICES FAMILY ${FAMILY})
  75. endif()
  76. if(CMAKE_MATCH_3)
  77. set(CORE ${CMAKE_MATCH_3})
  78. set(CORE_C "::${CORE}")
  79. set(CORE_U "_${CORE}")
  80. else()
  81. unset(CORE)
  82. unset(CORE_C)
  83. unset(CORE_U)
  84. endif()
  85. string(TOLOWER ${FAMILY} FAMILY_L)
  86. if((NOT STM32_CMSIS_${FAMILY}_PATH) AND (NOT STM32_CUBE_${FAMILY}_PATH) AND (DEFINED ENV{STM32_CUBE_${FAMILY}_PATH}))
  87. set(STM32_CUBE_${FAMILY}_PATH $ENV{STM32_CUBE_${FAMILY}_PATH} CACHE PATH "Path to STM32Cube${FAMILY}")
  88. message(STATUS "ENV STM32_CUBE_${FAMILY}_PATH specified, using STM32_CUBE_${FAMILY}_PATH: ${STM32_CUBE_${FAMILY}_PATH}")
  89. endif()
  90. if((NOT STM32_CMSIS_${FAMILY}_PATH) AND (NOT STM32_CUBE_${FAMILY}_PATH))
  91. set(STM32_CUBE_${FAMILY}_PATH /opt/STM32Cube${FAMILY} CACHE PATH "Path to STM32Cube${FAMILY}")
  92. message(STATUS "Neither STM32_CUBE_${FAMILY}_PATH nor STM32_CMSIS_${FAMILY}_PATH specified using default STM32_CUBE_${FAMILY}_PATH: ${STM32_CUBE_${FAMILY}_PATH}")
  93. endif()
  94. find_path(CMSIS_${FAMILY}${CORE_U}_CORE_PATH
  95. NAMES Include/cmsis_gcc.h
  96. PATHS "${STM32_CMSIS_PATH}" "${STM32_CUBE_${FAMILY}_PATH}/Drivers/CMSIS"
  97. NO_DEFAULT_PATH
  98. )
  99. if (NOT CMSIS_${FAMILY}${CORE_U}_CORE_PATH)
  100. continue()
  101. endif()
  102. find_path(CMSIS_${FAMILY}${CORE_U}_PATH
  103. NAMES Include/stm32${FAMILY_L}xx.h
  104. PATHS "${STM32_CMSIS_${FAMILY}_PATH}" "${STM32_CUBE_${FAMILY}_PATH}/Drivers/CMSIS/Device/ST/STM32${FAMILY}xx"
  105. NO_DEFAULT_PATH
  106. )
  107. if (NOT CMSIS_${FAMILY}${CORE_U}_PATH)
  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. find_file(CMSIS_${FAMILY}${CORE_U}_SOURCE
  129. NAMES system_stm32${FAMILY_L}xx.c
  130. PATHS "${CMSIS_${FAMILY}${CORE_U}_PATH}/Source/Templates"
  131. NO_DEFAULT_PATH
  132. )
  133. list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_SOURCE}")
  134. if (NOT CMSIS_${FAMILY}${CORE_U}_SOURCE)
  135. continue()
  136. endif()
  137. if(NOT (TARGET CMSIS::STM32::${FAMILY}${CORE_C}))
  138. add_library(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE IMPORTED)
  139. target_link_libraries(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE STM32::${FAMILY}${CORE_C})
  140. target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_CORE_PATH}/Include")
  141. target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_PATH}/Include")
  142. target_sources(CMSIS::STM32::${FAMILY}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_SOURCE}")
  143. endif()
  144. set(STM_DEVICES_FOUND TRUE)
  145. foreach(DEVICE ${STM_DEVICES})
  146. stm32_get_cores(DEV_CORES FAMILY ${FAMILY} DEVICE ${DEVICE})
  147. if(CORE AND (NOT ${CORE} IN_LIST DEV_CORES))
  148. continue()
  149. endif()
  150. stm32_get_chip_type(${FAMILY} ${DEVICE} TYPE)
  151. string(TOLOWER ${DEVICE} DEVICE_L)
  152. string(TOLOWER ${TYPE} TYPE_L)
  153. find_file(CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP
  154. NAMES startup_stm32${TYPE_L}.s
  155. PATHS "${CMSIS_${FAMILY}${CORE_U}_PATH}/Source/Templates/gcc"
  156. NO_DEFAULT_PATH
  157. )
  158. list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP}")
  159. if(NOT CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP)
  160. set(STM_DEVICES_FOUND FALSE)
  161. break()
  162. endif()
  163. if(NOT (TARGET CMSIS::STM32::${TYPE}${CORE_C}))
  164. add_library(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE IMPORTED)
  165. target_link_libraries(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE CMSIS::STM32::${FAMILY}${CORE_C} STM32::${TYPE}${CORE_C})
  166. target_sources(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${TYPE}_STARTUP}")
  167. endif()
  168. add_library(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE IMPORTED)
  169. target_link_libraries(CMSIS::STM32::${DEVICE}${CORE_C} INTERFACE CMSIS::STM32::${TYPE}${CORE_C})
  170. cmsis_generate_default_linker_script(${FAMILY} ${DEVICE} "${CORE}")
  171. endforeach()
  172. if(STM_DEVICES_FOUND)
  173. set(CMSIS_${COMP}_FOUND TRUE)
  174. else()
  175. set(CMSIS_${COMP}_FOUND FALSE)
  176. endif()
  177. foreach(RTOS_COMP ${CMSIS_FIND_COMPONENTS_RTOS})
  178. if (${RTOS_COMP} STREQUAL "RTOS_V2")
  179. set(RTOS_COMP_VERSION "2")
  180. else()
  181. unset(RTOS_COMP_VERSION)
  182. endif()
  183. find_path(CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH
  184. NAMES "cmsis_os${RTOS_COMP_VERSION}.h"
  185. PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_${RTOS_COMP}"
  186. NO_DEFAULT_PATH
  187. )
  188. if (NOT CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH)
  189. continue()
  190. endif()
  191. find_file(CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE
  192. NAMES "cmsis_os${RTOS_COMP_VERSION}.c"
  193. PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_${RTOS_COMP}"
  194. NO_DEFAULT_PATH
  195. )
  196. if (NOT CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE)
  197. continue()
  198. endif()
  199. if(NOT (TARGET CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP}))
  200. add_library(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE IMPORTED)
  201. target_link_libraries(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE CMSIS::STM32::${FAMILY}${CORE_C})
  202. target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH}")
  203. target_sources(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE}")
  204. endif()
  205. list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE}")
  206. list(APPEND CMSIS_INCLUDE_DIRS "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH}")
  207. set(CMSIS_${RTOS_COMP}_FOUND TRUE)
  208. endforeach()
  209. list(REMOVE_DUPLICATES CMSIS_INCLUDE_DIRS)
  210. list(REMOVE_DUPLICATES CMSIS_SOURCES)
  211. endforeach()
  212. include(FindPackageHandleStandardArgs)
  213. find_package_handle_standard_args(CMSIS
  214. REQUIRED_VARS CMSIS_INCLUDE_DIRS CMSIS_SOURCES
  215. FOUND_VAR CMSIS_FOUND
  216. VERSION_VAR CMSIS_VERSION
  217. HANDLE_COMPONENTS
  218. )