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