diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..68f4ae2
Binary files /dev/null and b/.DS_Store differ
diff --git a/.extSettings b/.extSettings
new file mode 100644
index 0000000..4745392
--- /dev/null
+++ b/.extSettings
@@ -0,0 +1,4 @@
+[Appli:ProjectFiles]
+[Appli:Groups]
+Application/User/Appli/TouchGFX/target=../Appli/TouchGFX/target/CortexMMCUInstrumentation.cpp
+[Appli:Others]
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5a3d1d0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,56 @@
+# CubeMX
+.mxproject
+backup_*.ioc
+
+# TouchGFX
+Appli/TouchGFX/*_backup.touchgfx
+Appli/TouchGFX/build/
+Appli/TouchGFX/config/
+Appli/TouchGFX/generated/
+Appli/TouchGFX/simulator/
+Appli/TouchGFX/target.config
+Appli/Middlewares/ST/touchgfx/
+Appli/Middlewares/ST/touchgfx_components/
+Appli/Middlewares/ST/touchgfx_backup*/
+Boot/TouchGFX/build/
+gcc/components.mk
+
+# IAR
+EWARM/settings/
+EWARM/Appli/settings/
+EWARM/Appli/STM32*/
+EWARM/Appli/*.dep
+EWARM/Appli/*.ewt
+EWARM/Boot/settings/
+EWARM/Boot/STM32*/
+EWARM/Boot/*.dep
+EWARM/Boot/*.ewt
+
+# CubeIDE
+STM32CubeIDE/.settings/
+STM32CubeIDE/Appli/.settings/
+STM32CubeIDE/Appli/Debug/
+STM32CubeIDE/Appli/Release/
+STM32CubeIDE/Boot/.settings/
+STM32CubeIDE/Boot/Debug/
+STM32CubeIDE/Boot/Release/
+
+# Keil
+MDK-ARM/*uvgui*
+MDK-ARM/Appli/RTE/
+MDK-ARM/Appli/STM32*/
+MDK-ARM/Appli/DebugConfig/
+MDK-ARM/Appli/*.lst
+MDK-ARM/Appli/*.out
+MDK-ARM/Appli/*vguix.*
+MDK-ARM/Boot/RTE/
+MDK-ARM/Boot/STM32*/
+MDK-ARM/Boot/DebugConfig/
+MDK-ARM/Boot/*.lst
+MDK-ARM/Boot/*.out
+MDK-ARM/Boot/*vguix.*
+
+# CMake
+build/*
+Appli/build/
+Boot/build/
diff --git a/.project b/.project
new file mode 100644
index 0000000..4e27647
--- /dev/null
+++ b/.project
@@ -0,0 +1,11 @@
+
+
+ CelloEffects
+
+
+
+
+
+
+
+
diff --git a/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs b/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
new file mode 100644
index 0000000..98a69fc
--- /dev/null
+++ b/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+sfrviewstate={"fFavorites"\:{"fLists"\:{}},"fProperties"\:{"fNodeProperties"\:{}}}
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000..ca32736
--- /dev/null
+++ b/.vscode/c_cpp_properties.json
@@ -0,0 +1,44 @@
+{
+ "version": 4,
+ "configurations": [
+ {
+ "name": "STM32H7S78-DK",
+ "compilerPath": "/usr/local/bin/arm-none-eabi-gcc",
+ "cStandard": "gnu11",
+ "cppStandard": "gnu++14",
+ "intelliSenseMode": "linux-gcc-arm",
+ "defines": [
+ "CORE_CM7",
+ "STM32H7S7xx",
+ "USE_HAL_DRIVER"
+ ],
+ "includePath": [
+ "${workspaceFolder}/Appli/TouchGFX/gui/include",
+ "${workspaceFolder}/Appli/TouchGFX/generated/gui_generated/include",
+ "${workspaceFolder}/Appli/TouchGFX/generated/fonts/include",
+ "${workspaceFolder}/Appli/TouchGFX/generated/images/include",
+ "${workspaceFolder}/Appli/TouchGFX/generated/texts/include",
+ "${workspaceFolder}/Appli/TouchGFX/generated/videos/include",
+ "${workspaceFolder}/Appli/TouchGFX/target/generated",
+ "${workspaceFolder}/Appli/TouchGFX/App/generated",
+ "${workspaceFolder}/Appli/Middlewares/ST/touchgfx/framework/include",
+ "${workspaceFolder}/Middlewares",
+ "${workspaceFolder}/gcc/Middlewares",
+ "${workspaceFolder}/Appli/TouchGFX/target",
+ "${workspaceFolder}/Appli/TouchGFX/App",
+ "${workspaceFolder}/Drivers/CMSIS/Include",
+ "${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32H7RSxx/Include",
+ "${workspaceFolder}/Drivers/STM32H7RSxx_HAL_Driver/Inc",
+ "${workspaceFolder}/Drivers/CMSIS/RTOS2/Include",
+ "${workspaceFolder}/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK",
+ "${workspaceFolder}/Drivers/STM32H7RSxx_BSP/Components/wm8904",
+ "${workspaceFolder}/Appli/Core/Inc",
+ "${workspaceFolder}/Appli/Middlewares/ST/touchgfx_components/gpu2d/TouchGFXNema/include",
+ "${workspaceFolder}/Appli/Middlewares/ST/touchgfx_components/gpu2d/NemaGFX/include",
+ "${workspaceFolder}/Middlewares/Third_Party/FreeRTOS/Source/include",
+ "${workspaceFolder}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2",
+ "${workspaceFolder}/gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F"
+ ]
+ }
+ ]
+}
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..5411cdd
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,40 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Debug Boot",
+ "type": "cortex-debug",
+ "request": "launch",
+ "cwd": "${workspaceFolder}",
+ "executable": "${workspaceFolder}/Boot/TouchGFX/build/bin/target.elf",
+ "servertype": "external",
+ "gdbTarget": "localhost:61234",
+ "gdbPath": "/usr/local/bin/arm-none-eabi-gdb",
+ "overrideLaunchCommands": [
+ "monitor halt",
+ "load",
+ "tbreak main",
+ "monitor reset"
+ ],
+ "preLaunchTask": "Start ST-LINK GDB Server",
+ "postDebugTask": "Stop ST-LINK GDB Server"
+ },
+ {
+ "name": "Debug Appli",
+ "type": "cortex-debug",
+ "request": "launch",
+ "cwd": "${workspaceFolder}",
+ "executable": "${workspaceFolder}/Appli/TouchGFX/build/bin/target.elf",
+ "servertype": "external",
+ "gdbTarget": "localhost:61234",
+ "gdbPath": "/usr/local/bin/arm-none-eabi-gdb",
+ "overrideLaunchCommands": [
+ "monitor halt",
+ "load",
+ "tbreak main"
+ ],
+ "preLaunchTask": "Start ST-LINK GDB Server",
+ "postDebugTask": "Stop ST-LINK GDB Server"
+ }
+ ]
+}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..dbdf8fa
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,91 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Build (Boot + Appli)",
+ "type": "shell",
+ "command": "/usr/local/opt/make/libexec/gnubin/make",
+ "args": ["-j8"],
+ "options": { "cwd": "${workspaceFolder}/gcc" },
+ "group": { "kind": "build", "isDefault": true },
+ "problemMatcher": ["$gcc"],
+ "presentation": { "reveal": "always", "panel": "shared", "clear": true }
+ },
+ {
+ "label": "Clean",
+ "type": "shell",
+ "command": "/usr/local/opt/make/libexec/gnubin/make",
+ "args": ["clean"],
+ "options": { "cwd": "${workspaceFolder}/gcc" },
+ "group": "build",
+ "problemMatcher": []
+ },
+ {
+ "label": "Flash Boot",
+ "type": "shell",
+ "command": "/Applications/STMicroelectronics/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.macos64_2.2.500.202603051304/tools/bin/STM32_Programmer_CLI",
+ "args": [
+ "-c", "port=SWD",
+ "-el", "${workspaceFolder}/gcc/MX66UW1G45G_STM32H7S78-DK.stldr",
+ "-w", "${workspaceFolder}/Boot/TouchGFX/build/bin/target.hex",
+ "-v",
+ "-rst"
+ ],
+ "group": "none",
+ "problemMatcher": []
+ },
+ {
+ "label": "Flash Appli",
+ "type": "shell",
+ "command": "/Applications/STMicroelectronics/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.macos64_2.2.500.202603051304/tools/bin/STM32_Programmer_CLI",
+ "args": [
+ "-c", "port=SWD",
+ "-el", "${workspaceFolder}/gcc/MX66UW1G45G_STM32H7S78-DK.stldr",
+ "-w", "${workspaceFolder}/Appli/TouchGFX/build/bin/target.hex",
+ "-v",
+ "-rst"
+ ],
+ "group": "none",
+ "problemMatcher": []
+ },
+ {
+ "label": "Flash All (Boot + Appli)",
+ "dependsOrder": "sequence",
+ "dependsOn": ["Flash Boot", "Flash Appli"],
+ "problemMatcher": []
+ },
+ {
+ "label": "Start ST-LINK GDB Server",
+ "type": "shell",
+ "command": "/Applications/STMicroelectronics/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.macos64_2.2.500.202604010938/tools/bin/ST-LINK_gdbserver",
+ "args": [
+ "-p", "61234",
+ "-l", "1",
+ "-d",
+ "-cp", "/Applications/STMicroelectronics/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.macos64_2.2.500.202603051304/tools/bin",
+ "-el", "${workspaceFolder}/gcc/MX66UW1G45G_STM32H7S78-DK.stldr",
+ "-m", "1",
+ "-k"
+ ],
+ "isBackground": true,
+ "problemMatcher": {
+ "pattern": {
+ "regexp": "^(x)(x)$"
+ },
+ "background": {
+ "activeOnStart": true,
+ "beginsPattern": "^STMicroelectronics ST-LINK GDB server",
+ "endsPattern": "Waiting for debugger connection|Error in initializing ST-LINK device"
+ }
+ },
+ "presentation": { "reveal": "always", "panel": "dedicated" }
+ },
+ {
+ "label": "Stop ST-LINK GDB Server",
+ "type": "shell",
+ "command": "pkill -f ST-LINK_gdbserver || true",
+ "problemMatcher": [],
+ "presentation": { "reveal": "silent" }
+ }
+ ]
+}
diff --git a/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld b/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld
index e611708..2c0d2f6 100644
--- a/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld
+++ b/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld
@@ -148,14 +148,14 @@ SECTIONS
. = ALIGN(4);
} >FLASH
- .ARM.extab (READONLY) :
+ .ARM.extab :
{
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >FLASH
- .ARM (READONLY) :
+ .ARM :
{
. = ALIGN(4);
__exidx_start = .;
@@ -164,7 +164,7 @@ SECTIONS
. = ALIGN(4);
} >FLASH
- .preinit_array (READONLY) :
+ .preinit_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
@@ -173,7 +173,7 @@ SECTIONS
. = ALIGN(4);
} >FLASH
- .init_array (READONLY) :
+ .init_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
@@ -183,7 +183,7 @@ SECTIONS
. = ALIGN(4);
} >FLASH
- .fini_array (READONLY) :
+ .fini_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
diff --git a/Boot/stm32h7s7xx_flash.ld b/Boot/stm32h7s7xx_flash.ld
index 7b72de4..4ab62c2 100644
--- a/Boot/stm32h7s7xx_flash.ld
+++ b/Boot/stm32h7s7xx_flash.ld
@@ -100,14 +100,14 @@ SECTIONS
. = ALIGN(4);
} >FLASH
- .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >FLASH
- .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
__exidx_start = .;
@@ -116,7 +116,7 @@ SECTIONS
. = ALIGN(4);
} >FLASH
- .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
@@ -125,7 +125,7 @@ SECTIONS
. = ALIGN(4);
} >FLASH
- .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
@@ -135,7 +135,7 @@ SECTIONS
. = ALIGN(4);
} >FLASH
- .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
diff --git a/gcc/macos_wine_wrappers/fontconvert.sh b/gcc/macos_wine_wrappers/fontconvert.sh
new file mode 100755
index 0000000..066ddcb
--- /dev/null
+++ b/gcc/macos_wine_wrappers/fontconvert.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# Lance le fontconvert.out Windows du projet via le Wine embarqué dans TouchGFX.app
+# (TouchGFX Designer pour macOS est une appli Wineskin - c'est le meme mecanisme que ST utilise).
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+
+WINE64="/Applications/STMicroelectronics/TouchGFX.app/Contents/SharedSupport/wine/bin/wine64"
+TOOL="$PROJECT_ROOT/Appli/Middlewares/ST/touchgfx/framework/tools/fontconvert/build/win/fontconvert.out"
+
+if [ ! -x "$WINE64" ]; then
+ echo "Wine introuvable ($WINE64). TouchGFX.app (Designer) doit etre installe dans /Applications/STMicroelectronics." >&2
+ exit 1
+fi
+
+export DYLD_FALLBACK_LIBRARY_PATH="/Applications/STMicroelectronics/TouchGFX.app/Contents/Frameworks:/Applications/STMicroelectronics/TouchGFX.app/Contents/SharedSupport/wine/lib"
+
+"$WINE64" "$TOOL" "$@" 2>/dev/null
diff --git a/gcc/macos_wine_wrappers/imageconvert.sh b/gcc/macos_wine_wrappers/imageconvert.sh
new file mode 100755
index 0000000..fe62e88
--- /dev/null
+++ b/gcc/macos_wine_wrappers/imageconvert.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# Lance l'imageconvert.out Windows du projet via le Wine embarqué dans TouchGFX.app
+# (TouchGFX Designer pour macOS est une appli Wineskin - c'est le meme mecanisme que ST utilise).
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+
+WINE64="/Applications/STMicroelectronics/TouchGFX.app/Contents/SharedSupport/wine/bin/wine64"
+TOOL="$PROJECT_ROOT/Appli/Middlewares/ST/touchgfx/framework/tools/imageconvert/build/win/imageconvert.out"
+
+if [ ! -x "$WINE64" ]; then
+ echo "Wine introuvable ($WINE64). TouchGFX.app (Designer) doit etre installe dans /Applications/STMicroelectronics." >&2
+ exit 1
+fi
+
+export DYLD_FALLBACK_LIBRARY_PATH="/Applications/STMicroelectronics/TouchGFX.app/Contents/Frameworks:/Applications/STMicroelectronics/TouchGFX.app/Contents/SharedSupport/wine/lib"
+
+"$WINE64" "$TOOL" "$@" 2>/dev/null
diff --git a/gcc/makefile_appli b/gcc/makefile_appli
index b58e5bb..4f8ab88 100644
--- a/gcc/makefile_appli
+++ b/gcc/makefile_appli
@@ -121,6 +121,11 @@ os_source_files += \
ifeq ($(UNAME), Linux)
imageconvert_executable := $(touchgfx_path)/framework/tools/imageconvert/build/linux/imageconvert.out
fontconvert_executable := $(touchgfx_path)/framework/tools/fontconvert/build/linux/fontconvert.out
+else ifeq ($(UNAME), Darwin)
+# Pas de binaire macOS pour imageconvert/fontconvert (Windows/Linux only) : on passe par le
+# Wine embarque dans TouchGFX.app (TouchGFX Designer pour macOS est une appli Wineskin).
+imageconvert_executable := gcc/macos_wine_wrappers/imageconvert.sh
+fontconvert_executable := gcc/macos_wine_wrappers/fontconvert.sh
else
imageconvert_executable := $(touchgfx_path)/framework/tools/imageconvert/build/win/imageconvert.out
fontconvert_executable := $(touchgfx_path)/framework/tools/fontconvert/build/win/fontconvert.out
@@ -184,6 +189,7 @@ cpp_compiler_options += \
linker_options += \
--specs=nosys.specs \
+ --specs=nano.specs \
-Os \
-Wl,--gc-sections -static \
-Wl,--print-memory-usage \
@@ -300,10 +306,21 @@ board_include_paths := \
$(Drivers_path)/CMSIS/Device/ST/STM32H7RSxx/Include \
$(Drivers_path)/STM32H7RSxx_HAL_Driver/Inc \
$(Drivers_path)/CMSIS/RTOS2/Include \
+ $(Drivers_path)/STM32H7RSxx_BSP/STM32H7S78-DK \
+ $(Drivers_path)/STM32H7RSxx_BSP/Components/wm8904 \
Appli/Core/Inc \
$(gpu2d_path)/TouchGFXNema/include \
$(gpu2d_path)/NemaGFX/include
+board_c_files += \
+ $(Drivers_path)/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.c \
+ $(Drivers_path)/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.c \
+ $(Drivers_path)/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.c \
+ $(Drivers_path)/STM32H7RSxx_BSP/Components/wm8904/wm8904.c \
+ $(Drivers_path)/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.c \
+ $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_mdf.c \
+ $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2s.c
+
asm_source_files := \
gcc/startup_stm32h7s7l8hxh_appli.s
@@ -466,4 +483,4 @@ _clean_:
# Create directory to avoid error if it does not exist
@mkdir -p $(asset_root_path)
# Remove assets folder if it is empty (i.e. no gui_generated folder)
- @rmdir --ignore-fail-on-non-empty $(asset_root_path)
+ @rmdir $(asset_root_path) 2>/dev/null || true
diff --git a/gcc/nul b/gcc/nul
new file mode 100644
index 0000000..0515180
--- /dev/null
+++ b/gcc/nul
@@ -0,0 +1 @@
+find: /c/ST/STM32CubeCLT/STM32CubeCLT//STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI.exe: No such file or directory
diff --git a/nul b/nul
new file mode 100644
index 0000000..0515180
--- /dev/null
+++ b/nul
@@ -0,0 +1 @@
+find: /c/ST/STM32CubeCLT/STM32CubeCLT//STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI.exe: No such file or directory
diff --git a/setup-vscode-macos.sh b/setup-vscode-macos.sh
new file mode 100755
index 0000000..0e3524a
--- /dev/null
+++ b/setup-vscode-macos.sh
@@ -0,0 +1,572 @@
+#!/bin/bash
+# ==============================================================================
+# setup-vscode-macos.sh
+#
+# Rend un projet STM32CubeIDE (genere par STM32CubeMX, toolchain GCC/Makefile)
+# compilable, flashable et debogable depuis VS Code sur macOS.
+#
+# Reutilisable tel quel sur un autre projet STM32CubeIDE : copiez ce script a
+# la racine du projet (a cote du dossier "gcc/") et lancez-le.
+#
+# Ce qu'il fait :
+# 1. Verifie/installe la toolchain (arm-none-eabi-gcc, GNU make 4.x)
+# 2. Localise STM32CubeIDE et ses outils embarques (ST-LINK_gdbserver,
+# STM32CubeProgrammer)
+# 3. Corrige les incompatibilites macOS connues dans les Makefiles/scripts
+# de lien generes par CubeMX (mot-cle READONLY, rmdir BSD, --specs)
+# 4. Si le projet utilise TouchGFX : cree des wrappers Wine (via TouchGFX.app,
+# qui embarque Wine) pour les outils imageconvert/fontconvert, qui n'ont
+# pas de version macOS
+# 5. Signe arm-none-eabi-gdb avec les entitlements necessaires au debogage
+# sur macOS (cree un certificat de signature de code auto-signe si besoin)
+# 6. Genere .vscode/tasks.json, c_cpp_properties.json et launch.json
+# 7. Lance une compilation de test pour valider
+#
+# Ce que ce script NE PEUT PAS deviner de maniere fiable (a vos yeux de
+# verifier si la compilation de test echoue) :
+# - Des fichiers sources ajoutes au projet APRES la derniere generation du
+# Makefile par CubeMX (ex: un driver BSP ajoute a la main) : le Makefile
+# genere peut alors ne pas les lister, meme s'ils apparaissent bien dans
+# le .cproject de STM32CubeIDE. Si la compilation de test echoue avec des
+# "undefined reference" ou "No such file or directory", il faudra ajouter
+# ces fichiers/chemins a la main dans gcc/makefile_ (variables
+# board_c_files += ... et board_include_paths += ...).
+# - Le point d'acces SWD (access port) et la strategie de reset a utiliser
+# pour le debogage : ce script utilise des valeurs par defaut modifiables
+# en tete de script (DEBUG_ACCESS_PORT, DEBUG_RESET_STRATEGY). Pour un
+# projet different, verifiez ces valeurs dans un fichier .launch existant
+# de STM32CubeIDE (dossier STM32CubeIDE/**/*.launch), champs
+# "com.st.stm32cube.ide.mcu.debug.launch.access_port_id" et
+# "com.st.stm32cube.ide.mcu.debug.stlink.reset_strategy".
+#
+# ==============================================================================
+
+set -uo pipefail
+
+# ------------------------------------------------------------------------------
+# Parametres modifiables
+# ------------------------------------------------------------------------------
+DEBUG_GDB_PORT="61234"
+DEBUG_ACCESS_PORT="0" # "-m " pour ST-LINK_gdbserver. Mettre 1 si le
+ # projet a une architecture boot+appli en memoire
+ # externe (verifier le .launch existant, voir ci-dessus)
+DEBUG_CONNECT_UNDER_RESET="1" # 1 = ajoute "-k" (connexion sous reset)
+GDB_SIGN_IDENTITY="gdb-cert"
+
+# ------------------------------------------------------------------------------
+# Utilitaires
+# ------------------------------------------------------------------------------
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$SCRIPT_DIR"
+STEP=0
+
+log() { STEP=$((STEP+1)); echo ""; echo "[$STEP] $*"; }
+info() { echo " $*"; }
+warn() { echo " ATTENTION: $*" >&2; }
+die() { echo "ERREUR: $*" >&2; exit 1; }
+
+# ==============================================================================
+log "Verification de la toolchain ARM"
+# ==============================================================================
+if ! command -v arm-none-eabi-gcc >/dev/null 2>&1; then
+ info "arm-none-eabi-gcc introuvable, installation via Homebrew..."
+ command -v brew >/dev/null 2>&1 || die "Homebrew n'est pas installe (https://brew.sh). Installez-le puis relancez ce script."
+ brew install --cask gcc-arm-embedded 2>/dev/null || brew install arm-none-eabi-gcc || die "Echec de l'installation d'arm-none-eabi-gcc"
+fi
+ARM_GCC_PATH="$(command -v arm-none-eabi-gcc)"
+info "arm-none-eabi-gcc : $ARM_GCC_PATH ($(arm-none-eabi-gcc --version | head -1))"
+
+ARM_GDB_PATH="$(command -v arm-none-eabi-gdb || true)"
+[ -z "$ARM_GDB_PATH" ] && die "arm-none-eabi-gdb introuvable (devrait etre installe avec arm-none-eabi-gcc)"
+info "arm-none-eabi-gdb : $ARM_GDB_PATH"
+
+# ==============================================================================
+log "Verification de GNU Make 4.x (celui d'Apple, 3.81, est trop ancien)"
+# ==============================================================================
+GNU_MAKE=""
+if make --version 2>/dev/null | head -1 | grep -qE "GNU Make (4|5|6|7|8|9)"; then
+ GNU_MAKE="$(command -v make)"
+else
+ for candidate in /usr/local/opt/make/libexec/gnubin/make /opt/homebrew/opt/make/libexec/gnubin/make; do
+ [ -x "$candidate" ] && GNU_MAKE="$candidate" && break
+ done
+ if [ -z "$GNU_MAKE" ]; then
+ info "GNU Make recent introuvable, installation via Homebrew (sera nomme 'gmake')..."
+ command -v brew >/dev/null 2>&1 || die "Homebrew n'est pas installe (https://brew.sh)."
+ brew install make || die "Echec de l'installation de make"
+ for candidate in /usr/local/opt/make/libexec/gnubin/make /opt/homebrew/opt/make/libexec/gnubin/make; do
+ [ -x "$candidate" ] && GNU_MAKE="$candidate" && break
+ done
+ fi
+fi
+[ -z "$GNU_MAKE" ] && die "Impossible de localiser un GNU Make >= 4.0 apres installation"
+info "GNU Make utilise : $GNU_MAKE ($("$GNU_MAKE" --version | head -1))"
+
+# ==============================================================================
+log "Localisation du dossier de build GCC du projet"
+# ==============================================================================
+GCC_DIR=""
+for d in "$PROJECT_ROOT/gcc" "$PROJECT_ROOT/GCC" "$PROJECT_ROOT/Gcc"; do
+ [ -d "$d" ] && GCC_DIR="$d" && break
+done
+[ -z "$GCC_DIR" ] && die "Dossier 'gcc/' introuvable a la racine du projet ($PROJECT_ROOT). Ce script attend un projet CubeMX genere avec la toolchain 'STM32CubeIDE / Makefile'."
+info "Dossier de build : $GCC_DIR"
+
+mapfile -t SUBMAKEFILES < <(find "$GCC_DIR" -maxdepth 1 -type f \( -iname "makefile_*" \) | sort)
+TOP_MAKEFILE="$GCC_DIR/Makefile"
+[ -f "$TOP_MAKEFILE" ] || die "Makefile principal introuvable dans $GCC_DIR"
+if [ "${#SUBMAKEFILES[@]}" -eq 0 ]; then
+ SUBMAKEFILES=("$TOP_MAKEFILE")
+fi
+info "Makefile(s) detecte(s) : ${SUBMAKEFILES[*]}"
+
+# ==============================================================================
+log "Localisation de STM32CubeIDE et de ses outils embarques"
+# ==============================================================================
+CUBEIDE_APP=""
+for d in "/Applications/STMicroelectronics/STM32CubeIDE.app" "/Applications/STM32CubeIDE.app"; do
+ [ -d "$d" ] && CUBEIDE_APP="$d" && break
+done
+[ -z "$CUBEIDE_APP" ] && CUBEIDE_APP="$(mdfind "kMDItemFSName == 'STM32CubeIDE.app'" 2>/dev/null | head -1)"
+[ -z "$CUBEIDE_APP" ] && die "STM32CubeIDE.app introuvable dans /Applications. Installez-le depuis st.com (necessaire pour le flash/debug via ST-Link)."
+info "STM32CubeIDE : $CUBEIDE_APP"
+
+GDBSERVER_BIN="$(find "$CUBEIDE_APP/Contents/Eclipse/plugins" -maxdepth 1 -iname "*stlink-gdb-server*" -type d 2>/dev/null | sort -V | tail -1)/tools/bin/ST-LINK_gdbserver"
+CUBEPROG_BIN_DIR="$(find "$CUBEIDE_APP/Contents/Eclipse/plugins" -maxdepth 1 -iname "*cubeprogrammer*" -type d 2>/dev/null | sort -V | tail -1)/tools/bin"
+CUBEPROG_CLI="$CUBEPROG_BIN_DIR/STM32_Programmer_CLI"
+
+[ -x "$GDBSERVER_BIN" ] || die "ST-LINK_gdbserver introuvable sous $CUBEIDE_APP"
+[ -x "$CUBEPROG_CLI" ] || die "STM32_Programmer_CLI introuvable sous $CUBEIDE_APP"
+info "ST-LINK_gdbserver : $GDBSERVER_BIN"
+info "STM32_Programmer_CLI: $CUBEPROG_CLI"
+
+# ==============================================================================
+log "Recherche d'un chargeur de memoire externe (.stldr), si applicable"
+# ==============================================================================
+EXT_LOADER="$(find "$PROJECT_ROOT" -iname "*.stldr" -maxdepth 3 2>/dev/null | head -1)"
+if [ -n "$EXT_LOADER" ]; then
+ info "External loader trouve : $EXT_LOADER"
+ EXT_LOADER_ARGS_PROG=(-el "$EXT_LOADER")
+ EXT_LOADER_ARGS_GDB="-el \${workspaceFolder}/$(python3 -c "import os,sys; print(os.path.relpath(sys.argv[1], sys.argv[2]))" "$EXT_LOADER" "$PROJECT_ROOT" 2>/dev/null || echo "$EXT_LOADER")"
+else
+ info "Aucun external loader trouve (normal si le projet n'utilise pas de memoire externe XSPI/QSPI)."
+ EXT_LOADER_ARGS_PROG=()
+ EXT_LOADER_ARGS_GDB=""
+fi
+
+# ==============================================================================
+log "Correction des incompatibilites macOS dans les scripts de lien (.ld)"
+# ==============================================================================
+LD_FILES=$(find "$PROJECT_ROOT" -iname "*.ld" -not -path "*/STM32CubeIDE/*" 2>/dev/null)
+FIXED_LD=0
+for ld in $LD_FILES; do
+ if grep -q "(READONLY)" "$ld" 2>/dev/null; then
+ sed -i '' 's/ (READONLY)//' "$ld"
+ info "Corrige (mot-cle READONLY, GCC11+ uniquement) : $ld"
+ FIXED_LD=$((FIXED_LD+1))
+ fi
+done
+[ "$FIXED_LD" -eq 0 ] && info "Rien a corriger."
+
+# ==============================================================================
+log "Correction des incompatibilites macOS dans les Makefiles"
+# ==============================================================================
+for mk in "${SUBMAKEFILES[@]}" "$TOP_MAKEFILE"; do
+ [ -f "$mk" ] || continue
+
+ # rmdir --ignore-fail-on-non-empty n'existe pas sur macOS (BSD rmdir)
+ if grep -q -- "--ignore-fail-on-non-empty" "$mk" 2>/dev/null; then
+ sed -i '' -E 's/rmdir --ignore-fail-on-non-empty ([^ ]+)/rmdir \1 2>\/dev\/null || true/' "$mk"
+ info "Corrige (rmdir portable) : $mk"
+ fi
+
+ # --specs=nosys.specs sans --specs=nano.specs cause des symboles
+ # __sf_fake_stdin/stdout/stderr non resolus avec FreeRTOS
+ if grep -q -- "--specs=nosys.specs" "$mk" 2>/dev/null && ! grep -q -- "--specs=nano.specs" "$mk" 2>/dev/null; then
+ sed -i '' 's/--specs=nosys.specs/--specs=nosys.specs \\\n\t--specs=nano.specs/' "$mk"
+ info "Ajoute --specs=nano.specs au linker : $mk"
+ fi
+
+ # Ajout d'une branche Darwin pour imageconvert/fontconvert si TouchGFX est utilise
+ if grep -q "imageconvert_executable" "$mk" 2>/dev/null && ! grep -q "UNAME), Darwin" "$mk" 2>/dev/null; then
+ TOUCHGFX_WIN_IMG=$(grep -oE '[A-Za-z0-9_/.-]+/win/imageconvert\.out' "$mk" | head -1)
+ TOUCHGFX_WIN_FONT=$(grep -oE '[A-Za-z0-9_/.-]+/win/fontconvert\.out' "$mk" | head -1)
+ if [ -n "$TOUCHGFX_WIN_IMG" ]; then
+ info "TouchGFX detecte dans $mk - mise en place des wrappers Wine macOS"
+
+ TOUCHGFX_APP=""
+ for d in "/Applications/STMicroelectronics/TouchGFX.app" "/Applications/TouchGFX.app"; do
+ [ -d "$d" ] && TOUCHGFX_APP="$d" && break
+ done
+ [ -z "$TOUCHGFX_APP" ] && TOUCHGFX_APP="$(mdfind "kMDItemFSName == 'TouchGFX.app'" 2>/dev/null | head -1)"
+
+ if [ -z "$TOUCHGFX_APP" ] || [ ! -x "$TOUCHGFX_APP/Contents/SharedSupport/wine/bin/wine64" ]; then
+ warn "TouchGFX.app (Designer) introuvable ou non-Wineskin sous /Applications - impossible de generer les wrappers automatiquement."
+ warn "Installez TouchGFX Designer pour macOS depuis st.com, puis relancez ce script."
+ else
+ WRAP_DIR="$GCC_DIR/macos_wine_wrappers"
+ mkdir -p "$WRAP_DIR"
+ WINE64="$TOUCHGFX_APP/Contents/SharedSupport/wine/bin/wine64"
+ WINE_LIBS="$TOUCHGFX_APP/Contents/Frameworks:$TOUCHGFX_APP/Contents/SharedSupport/wine/lib"
+
+ for pair in "imageconvert:$TOUCHGFX_WIN_IMG" "fontconvert:$TOUCHGFX_WIN_FONT"; do
+ name="${pair%%:*}"; relpath="${pair#*:}"
+ [ -z "$relpath" ] && continue
+ cat > "$WRAP_DIR/$name.sh" << EOF
+#!/bin/sh
+# Lance $name.out (Windows) via le Wine embarque dans TouchGFX.app
+export DYLD_FALLBACK_LIBRARY_PATH="$WINE_LIBS"
+exec "$WINE64" "$PROJECT_ROOT/$relpath" "\$@" 2>/dev/null
+EOF
+ chmod +x "$WRAP_DIR/$name.sh"
+ info "Wrapper cree : $WRAP_DIR/$name.sh"
+ done
+
+ # Insere une branche Darwin juste avant le "else" qui gere Windows/Linux
+ MK_REL_GCC=$(basename "$mk")
+ awk -v wrapdir="$(python3 -c "import os,sys; print(os.path.relpath(sys.argv[1], sys.argv[2]))" "$WRAP_DIR" "$PROJECT_ROOT" 2>/dev/null || echo "gcc/macos_wine_wrappers")" '
+ /ifeq \(\$\(UNAME\), Linux\)/ { print; infile=1; next }
+ infile && /^else$/ && !inserted {
+ print "else ifeq ($(UNAME), Darwin)"
+ print "imageconvert_executable := " wrapdir "/imageconvert.sh"
+ print "fontconvert_executable := " wrapdir "/fontconvert.sh"
+ inserted=1
+ }
+ { print }
+ ' "$mk" > "$mk.tmp" && mv "$mk.tmp" "$mk"
+ info "Branche Darwin ajoutee dans $mk"
+ fi
+ fi
+ fi
+done
+
+# ==============================================================================
+log "Compilation de test"
+# ==============================================================================
+( cd "$GCC_DIR" && "$GNU_MAKE" -j"$(sysctl -n hw.ncpu)" )
+BUILD_STATUS=$?
+if [ "$BUILD_STATUS" -ne 0 ]; then
+ warn "La compilation a echoue. Causes frequentes :"
+ warn " - fichiers sources ajoutes au projet apres la derniere generation du"
+ warn " Makefile (comparez avec STM32CubeIDE/*/. cproject) -> a ajouter a la main"
+ warn " dans gcc/makefile_ (board_c_files += / board_include_paths +=)"
+ warn "Les fichiers .vscode/ seront quand meme generes ; relancez juste le build"
+ warn "depuis VS Code une fois les corrections faites."
+else
+ info "Compilation reussie."
+fi
+
+# ==============================================================================
+log "Signature de code pour arm-none-eabi-gdb (necessaire pour deboguer sur macOS)"
+# ==============================================================================
+if codesign -dv "$ARM_GDB_PATH" 2>&1 | grep -q "com.apple.security.cs.debugger" 2>/dev/null; then
+ info "Deja signe correctement."
+elif security find-identity -v -p codesigning 2>/dev/null | grep -q "$GDB_SIGN_IDENTITY"; then
+ info "Certificat '$GDB_SIGN_IDENTITY' deja present, signature de gdb..."
+ cat > /tmp/gdb-entitlement.xml << 'EOF'
+
+
+
+
+ com.apple.security.cs.debugger
+
+ com.apple.security.get-task-allow
+
+
+
+EOF
+ codesign --entitlements /tmp/gdb-entitlement.xml -fs "$GDB_SIGN_IDENTITY" "$ARM_GDB_PATH"
+else
+ info "Creation d'un certificat de signature de code auto-signe '$GDB_SIGN_IDENTITY'..."
+ info "(macOS va probablement demander votre mot de passe pour lui faire confiance)"
+ KEYCHAIN="$HOME/Library/Keychains/login.keychain-db"
+ openssl req -new -newkey rsa:2048 -x509 -days 3650 -nodes \
+ -keyout /tmp/gdb-cert.key -out /tmp/gdb-cert.crt \
+ -subj "/CN=$GDB_SIGN_IDENTITY" \
+ -addext "basicConstraints=critical,CA:true" \
+ -addext "keyUsage=critical,digitalSignature,keyCertSign" \
+ -addext "extendedKeyUsage=critical,codeSigning" >/dev/null 2>&1
+ openssl pkcs12 -export -out /tmp/gdb-cert.p12 -inkey /tmp/gdb-cert.key -in /tmp/gdb-cert.crt \
+ -passout pass:temp -legacy >/dev/null 2>&1
+ security import /tmp/gdb-cert.p12 -k "$KEYCHAIN" -P temp -T /usr/bin/codesign -T /usr/bin/security
+ security add-trusted-cert -p codeSign -k "$KEYCHAIN" /tmp/gdb-cert.crt
+ rm -f /tmp/gdb-cert.key /tmp/gdb-cert.crt /tmp/gdb-cert.p12
+
+ cat > /tmp/gdb-entitlement.xml << 'EOF'
+
+
+
+
+ com.apple.security.cs.debugger
+
+ com.apple.security.get-task-allow
+
+
+
+EOF
+ codesign --entitlements /tmp/gdb-entitlement.xml -fs "$GDB_SIGN_IDENTITY" "$ARM_GDB_PATH" \
+ || warn "La signature a echoue - relancez ce script apres avoir accepte la demande de confiance macOS."
+fi
+
+# ==============================================================================
+log "Extraction des chemins d'include / defines (pour l'auto-completion VS Code)"
+# ==============================================================================
+MAIN_APP_MAKEFILE="${SUBMAKEFILES[-1]}"
+INCLUDE_PATHS_RAW=$("$GNU_MAKE" -f "$MAIN_APP_MAKEFILE" -C "$GCC_DIR" -p 2>/dev/null | grep -m1 "^include_paths " | sed 's/^include_paths[[:space:]]*:=[[:space:]]*//')
+DEFINES_RAW=$("$GNU_MAKE" -f "$MAIN_APP_MAKEFILE" -C "$GCC_DIR" -p 2>/dev/null | grep -m1 "^c_compiler_options " | grep -oE '\-D[A-Za-z0-9_]+' | sed 's/^-D//')
+
+INCLUDE_JSON=""
+for p in $INCLUDE_PATHS_RAW; do
+ INCLUDE_JSON="$INCLUDE_JSON \"\${workspaceFolder}/$p\",\n"
+done
+DEFINES_JSON=""
+for d in $DEFINES_RAW; do
+ DEFINES_JSON="$DEFINES_JSON \"$d\",\n"
+done
+info "$(echo -e "$INCLUDE_JSON" | grep -c workspaceFolder) chemins d'include et $(echo -e "$DEFINES_JSON" | grep -c '\".*\"') defines extraits."
+
+# ==============================================================================
+log "Detection de la structure du projet (mono-projet ou Boot+Appli)"
+# ==============================================================================
+BOOT_ELF=""
+APPLI_ELF=""
+if [ -d "$PROJECT_ROOT/Boot" ] && [ -d "$PROJECT_ROOT/Appli" ]; then
+ info "Structure Boot + Appli detectee (architecture avec bootloader externe)."
+ BOOT_ELF=$(find "$PROJECT_ROOT/Boot" -iname "target.elf" 2>/dev/null | head -1)
+ APPLI_ELF=$(find "$PROJECT_ROOT/Appli" -iname "target.elf" 2>/dev/null | head -1)
+else
+ info "Structure mono-projet detectee."
+ APPLI_ELF=$(find "$PROJECT_ROOT" -iname "target.elf" -not -path "*/STM32CubeIDE/*" 2>/dev/null | head -1)
+fi
+[ -z "$BOOT_ELF" ] && [ -d "$PROJECT_ROOT/Boot" ] && BOOT_ELF="Boot/TouchGFX/build/bin/target.elf"
+[ -z "$APPLI_ELF" ] && APPLI_ELF="$(find "$GCC_DIR/.." -iname "target.elf" -not -path "*/STM32CubeIDE/*" 2>/dev/null | head -1)"
+BOOT_ELF_REL=${BOOT_ELF#"$PROJECT_ROOT/"}
+APPLI_ELF_REL=${APPLI_ELF#"$PROJECT_ROOT/"}
+
+# ==============================================================================
+log "Generation des fichiers .vscode/"
+# ==============================================================================
+mkdir -p "$PROJECT_ROOT/.vscode"
+GCC_DIR_REL=${GCC_DIR#"$PROJECT_ROOT/"}
+
+# --- c_cpp_properties.json ---
+{
+ echo "{"
+ echo " \"version\": 4,"
+ echo " \"configurations\": ["
+ echo " {"
+ echo " \"name\": \"STM32\","
+ echo " \"compilerPath\": \"$ARM_GCC_PATH\","
+ echo " \"cStandard\": \"gnu11\","
+ echo " \"cppStandard\": \"gnu++14\","
+ echo " \"intelliSenseMode\": \"linux-gcc-arm\","
+ echo " \"defines\": ["
+ echo -e "$DEFINES_JSON" | sed '$ s/,$//'
+ echo " ],"
+ echo " \"includePath\": ["
+ echo -e "$INCLUDE_JSON" | sed '$ s/,$//'
+ echo " ]"
+ echo " }"
+ echo " ]"
+ echo "}"
+} > "$PROJECT_ROOT/.vscode/c_cpp_properties.json"
+info "Genere : .vscode/c_cpp_properties.json"
+
+# --- tasks.json ---
+RESET_FLAG=""
+[ "$DEBUG_CONNECT_UNDER_RESET" = "1" ] && RESET_FLAG='"-k",'
+EXT_LOADER_PROG_ARGS=""
+[ -n "$EXT_LOADER" ] && EXT_LOADER_PROG_ARGS="\"-el\", \"\${workspaceFolder}/${EXT_LOADER#"$PROJECT_ROOT/"}\","
+EXT_LOADER_GDB_ARGS=""
+[ -n "$EXT_LOADER" ] && EXT_LOADER_GDB_ARGS="-el \${workspaceFolder}/${EXT_LOADER#"$PROJECT_ROOT/"} "
+
+cat > "$PROJECT_ROOT/.vscode/tasks.json" << EOF
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Build",
+ "type": "shell",
+ "command": "$GNU_MAKE",
+ "args": ["-j8"],
+ "options": { "cwd": "\${workspaceFolder}/$GCC_DIR_REL" },
+ "group": { "kind": "build", "isDefault": true },
+ "problemMatcher": ["\$gcc"],
+ "presentation": { "reveal": "always", "panel": "shared", "clear": true }
+ },
+ {
+ "label": "Clean",
+ "type": "shell",
+ "command": "$GNU_MAKE",
+ "args": ["clean"],
+ "options": { "cwd": "\${workspaceFolder}/$GCC_DIR_REL" },
+ "group": "build",
+ "problemMatcher": []
+ },
+ {
+ "label": "Flash",
+ "type": "shell",
+ "command": "$CUBEPROG_CLI",
+ "args": [
+ "-c", "port=SWD",
+ $EXT_LOADER_PROG_ARGS
+ "-w", "\${workspaceFolder}/$APPLI_ELF_REL",
+ "-v",
+ "-rst"
+ ],
+ "group": "none",
+ "problemMatcher": []
+ },
+ {
+ "label": "Start ST-LINK GDB Server",
+ "type": "shell",
+ "command": "$GDBSERVER_BIN",
+ "args": [
+ "-p", "$DEBUG_GDB_PORT",
+ "-l", "1",
+ "-d",
+ "-cp", "$CUBEPROG_BIN_DIR",
+ $EXT_LOADER_PROG_ARGS
+ "-m", "$DEBUG_ACCESS_PORT",
+ $RESET_FLAG
+ "-e"
+ ],
+ "isBackground": true,
+ "problemMatcher": {
+ "pattern": { "regexp": "^(x)(x)\$" },
+ "background": {
+ "activeOnStart": true,
+ "beginsPattern": "^STMicroelectronics ST-LINK GDB server",
+ "endsPattern": "Waiting for debugger connection|Error in initializing ST-LINK device"
+ }
+ },
+ "presentation": { "reveal": "always", "panel": "dedicated" }
+ },
+ {
+ "label": "Stop ST-LINK GDB Server",
+ "type": "shell",
+ "command": "pkill -f ST-LINK_gdbserver || true",
+ "problemMatcher": [],
+ "presentation": { "reveal": "silent" }
+ }
+ ]
+}
+EOF
+# Nettoyage des eventuelles virgules trainantes (arguments optionnels vides)
+sed -i '' -E 's/,([[:space:]]*\])/\1/' "$PROJECT_ROOT/.vscode/tasks.json"
+info "Genere : .vscode/tasks.json"
+
+if [ -n "$BOOT_ELF_REL" ] && [ -d "$PROJECT_ROOT/Boot" ]; then
+ cat >> /dev/null << 'NOTE'
+Structure Boot+Appli : deux tasks de flash separees ajoutees ci-dessous en plus.
+NOTE
+ python3 - "$PROJECT_ROOT/.vscode/tasks.json" "$BOOT_ELF_REL" "$APPLI_ELF_REL" "$CUBEPROG_CLI" "$EXT_LOADER" <<'PYEOF'
+import json, sys
+path, boot_elf, appli_elf, cli, extloader = sys.argv[1:6]
+with open(path) as f:
+ data = json.load(f)
+extra_args = ["-c", "port=SWD"]
+if extloader:
+ extra_args += ["-el", "${workspaceFolder}/" + extloader.split("/", 1)[-1] if "/" in extloader else extloader]
+def flash_task(label, elf_rel):
+ hex_rel = elf_rel.rsplit(".elf", 1)[0] + ".hex"
+ return {
+ "label": label, "type": "shell", "command": cli,
+ "args": extra_args + ["-w", "${workspaceFolder}/" + hex_rel, "-v", "-rst"],
+ "group": "none", "problemMatcher": []
+ }
+data["tasks"] = [t for t in data["tasks"] if t["label"] != "Flash"]
+data["tasks"].insert(2, flash_task("Flash Boot", boot_elf))
+data["tasks"].insert(3, flash_task("Flash Appli", appli_elf))
+data["tasks"].append({"label": "Flash All (Boot + Appli)", "dependsOrder": "sequence", "dependsOn": ["Flash Boot", "Flash Appli"], "problemMatcher": []})
+with open(path, "w") as f:
+ json.dump(data, f, indent=2)
+PYEOF
+ info "tasks.json adapte pour la structure Boot+Appli (Flash Boot / Flash Appli separes)."
+fi
+
+# --- launch.json ---
+LAUNCH_CMDS_APPLI='"monitor halt", "load", "tbreak main"'
+LAUNCH_CMDS_SINGLE='"monitor halt", "load", "tbreak main", "monitor reset"'
+
+if [ -n "$BOOT_ELF_REL" ] && [ -d "$PROJECT_ROOT/Boot" ]; then
+cat > "$PROJECT_ROOT/.vscode/launch.json" << EOF
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Debug Boot",
+ "type": "cortex-debug",
+ "request": "launch",
+ "cwd": "\${workspaceFolder}",
+ "executable": "\${workspaceFolder}/$BOOT_ELF_REL",
+ "servertype": "external",
+ "gdbTarget": "localhost:$DEBUG_GDB_PORT",
+ "gdbPath": "$ARM_GDB_PATH",
+ "overrideLaunchCommands": [$LAUNCH_CMDS_SINGLE],
+ "preLaunchTask": "Start ST-LINK GDB Server",
+ "postDebugTask": "Stop ST-LINK GDB Server"
+ },
+ {
+ "name": "Debug Appli",
+ "type": "cortex-debug",
+ "request": "launch",
+ "cwd": "\${workspaceFolder}",
+ "executable": "\${workspaceFolder}/$APPLI_ELF_REL",
+ "servertype": "external",
+ "gdbTarget": "localhost:$DEBUG_GDB_PORT",
+ "gdbPath": "$ARM_GDB_PATH",
+ "overrideLaunchCommands": [$LAUNCH_CMDS_APPLI],
+ "preLaunchTask": "Start ST-LINK GDB Server",
+ "postDebugTask": "Stop ST-LINK GDB Server"
+ }
+ ]
+}
+EOF
+ info "NOTE : structure Boot+Appli detectee. Workflow de debogage :"
+ info " 1) Lancer 'Debug Boot', attendre le flash, arreter la session"
+ info " 2) Lancer 'Debug Appli', attendre l'arret sur main()"
+ info " 3) Appuyer sur le bouton NRST physique de la carte"
+ info " 4) Cliquer Continue"
+ info " (verifiez ce comportement sur votre projet - certains projets mono-image n'en ont pas besoin)"
+else
+cat > "$PROJECT_ROOT/.vscode/launch.json" << EOF
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Debug",
+ "type": "cortex-debug",
+ "request": "launch",
+ "cwd": "\${workspaceFolder}",
+ "executable": "\${workspaceFolder}/$APPLI_ELF_REL",
+ "servertype": "external",
+ "gdbTarget": "localhost:$DEBUG_GDB_PORT",
+ "gdbPath": "$ARM_GDB_PATH",
+ "overrideLaunchCommands": [$LAUNCH_CMDS_SINGLE],
+ "preLaunchTask": "Start ST-LINK GDB Server",
+ "postDebugTask": "Stop ST-LINK GDB Server"
+ }
+ ]
+}
+EOF
+fi
+info "Genere : .vscode/launch.json"
+
+# ==============================================================================
+log "Termine"
+# ==============================================================================
+echo ""
+echo "Recapitulatif :"
+echo " - Build : Cmd+Shift+B dans VS Code, ou tache 'Build'"
+echo " - Flash : Terminal > Run Task > Flash (ou 'Flash Boot'/'Flash Appli')"
+echo " - Debug : panneau Run and Debug de VS Code"
+echo ""
+echo "Extensions VS Code requises (a installer manuellement si absentes) :"
+echo " - C/C++ (ms-vscode.cpptools)"
+echo " - Cortex-Debug (marus25.cortex-debug)"
+echo ""
+if [ "$BUILD_STATUS" -ne 0 ]; then
+ echo "ATTENTION : la compilation de test a echoue - voir les messages ci-dessus"
+ echo "avant de considerer la configuration comme terminee."
+fi