forked from ObKo/stm32-cmake
-
Notifications
You must be signed in to change notification settings - Fork 1
/
FindCMSIS.cmake
326 lines (275 loc) · 14 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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# For information about why and how of this file: https://cmake.org/cmake/help/latest/command/find_package.html
set(CMSIS_RTOS RTOS RTOS_V2)
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()
if(STM32MP1 IN_LIST CMSIS_FIND_COMPONENTS)
list(REMOVE_ITEM CMSIS_FIND_COMPONENTS STM32MP1)
list(APPEND CMSIS_FIND_COMPONENTS STM32MP1_M4)
endif()
list(REMOVE_DUPLICATES CMSIS_FIND_COMPONENTS)
# This section fills the RTOS or family components list
foreach(COMP ${CMSIS_FIND_COMPONENTS})
string(TOLOWER ${COMP} COMP_L)
string(TOUPPER ${COMP} COMP)
# Component is RTOS component
if(${COMP} IN_LIST CMSIS_RTOS)
list(APPEND CMSIS_FIND_COMPONENTS_RTOS ${COMP})
continue()
endif()
# Component is not RTOS component, so check whether it is a family component
string(REGEX MATCH "^STM32([FGHLMUW]P?[0-9BL])([0-9A-Z][0-9M][A-Z][0-9A-Z])?_?(M0PLUS|M4|M7)?.*$" COMP ${COMP})
if(CMAKE_MATCH_1)
list(APPEND CMSIS_FIND_COMPONENTS_FAMILIES ${COMP})
endif()
endforeach()
if(NOT CMSIS_FIND_COMPONENTS_FAMILIES)
set(CMSIS_FIND_COMPONENTS_FAMILIES ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
endif()
if(NOT CMSIS_FIND_COMPONENTS_RTOS)
set(CMSIS_FIND_COMPONENTS_RTOS ${CMSIS_RTOS})
endif()
message(STATUS "Search for CMSIS families: ${CMSIS_FIND_COMPONENTS_FAMILIES}")
message(STATUS "Search for CMSIS RTOS: ${CMSIS_FIND_COMPONENTS_RTOS}")
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")
if(${FAMILY} STREQUAL MP1)
string(TOLOWER ${FAMILY} FAMILY_L)
find_file(CMSIS_${FAMILY}${CORE_U}_LD_SCRIPT
NAMES stm32mp15xx_m4.ld
PATHS "${CMSIS_${FAMILY}${CORE_U}_PATH}/Source/Templates/gcc/linker"
NO_DEFAULT_PATH
)
add_custom_command(OUTPUT "${OUTPUT_LD_FILE}"
COMMAND ${CMAKE_COMMAND}
-E copy ${CMSIS_${FAMILY}${CORE_U}_LD_SCRIPT} ${OUTPUT_LD_FILE})
else()
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"
)
endif()
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_FAMILIES})
string(TOLOWER ${COMP} COMP_L)
string(TOUPPER ${COMP} COMP)
string(REGEX MATCH "^STM32([FGHLMUW]P?[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})
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)
#STM32::${FAMILY}${CORE_C} contains compile options and is define in <family>.cmake
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")
endif()
# search for system_stm32[XX]xx.c
find_file(CMSIS_${FAMILY}${CORE_U}_SYSTEM
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}_SYSTEM}")
if(NOT CMSIS_${FAMILY}${CORE_U}_SYSTEM)
message(VERBOSE "FindCMSIS: system_stm32${FAMILY_L}xx.c for ${FAMILY}${CORE_U} has not been found")
continue()
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)
get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
if(NOT "ASM" IN_LIST languages)
message(STATUS "FindCMSIS: Not generating target for startup file and linker script because ASM language is not enabled")
continue()
endif()
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}")
target_sources(CMSIS::STM32::${TYPE}${CORE_C} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_SYSTEM}")
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()
foreach(RTOS_COMP ${CMSIS_FIND_COMPONENTS_RTOS})
if (${RTOS_COMP} STREQUAL "RTOS_V2")
set(RTOS_COMP_VERSION "2")
else()
unset(RTOS_COMP_VERSION)
endif()
find_path(CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH
NAMES "cmsis_os${RTOS_COMP_VERSION}.h"
PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_${RTOS_COMP}"
NO_DEFAULT_PATH
)
if (NOT CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH)
continue()
endif()
find_file(CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE
NAMES "cmsis_os${RTOS_COMP_VERSION}.c"
PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_${RTOS_COMP}"
NO_DEFAULT_PATH
)
if (NOT CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE)
continue()
endif()
if(NOT (TARGET CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP}))
add_library(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE IMPORTED)
target_link_libraries(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE CMSIS::STM32::${FAMILY}${CORE_C})
target_include_directories(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH}")
target_sources(CMSIS::STM32::${FAMILY}${CORE_C}::${RTOS_COMP} INTERFACE "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE}")
endif()
list(APPEND CMSIS_SOURCES "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_SOURCE}")
list(APPEND CMSIS_INCLUDE_DIRS "${CMSIS_${FAMILY}${CORE_U}_${RTOS_COMP}_PATH}")
set(CMSIS_${RTOS_COMP}_FOUND TRUE)
endforeach()
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
)