build(mcu): add linker script + USB CDC glue (PR 2 — firmware links)

Closes the link for the STM32F746ZGT7 bring-up:

- linker/STM32F746ZGTx_FLASH.ld: 1 MB flash @ 0x08000000, 256 KB RAM @
  0x20010000 (SRAM1+SRAM2 contiguous), 64 KB DTCM for stack/heap, 16 KB
  ITCM. Standard Cube-style section layout.
- 9_1_3_C_Cpp_Code/usb_device.{h,c}: MX_USB_DEVICE_Init wiring CDC class
  + interface into hUsbDeviceFS.
- 9_1_3_C_Cpp_Code/usbd_conf.{h,c}: HAL PCD bridge — hpcd_USB_OTG_FS,
  USBD_LL_* callbacks, HAL_PCD_MspInit (PA11/PA12 AF10, OTG_FS clock,
  OTG_FS_IRQn), static allocator for USBD_malloc.
- 9_1_3_C_Cpp_Code/usbd_desc.{h,c}: device + string descriptors, VID
  0x0483 / PID 0x5740 (STM32 VCP), serial derived from 96-bit UID.
- 9_1_3_C_Cpp_Code/usbd_cdc_if.{h,c}: CDC_Transmit_FS + class callbacks;
  host-to-device bytes forwarded via weak CDC_on_receive hook so
  USBHandler can override from C++ without a hard dep.

Makefile:
- default target now 'link' (produces firmware.elf/.bin/.hex).
- APP_CPP no longer excludes main.cpp; LIB_CPP no longer excludes
  gps_handler.cpp.
- USB_C picks up Core + CDC class .c files (minus *_template.c).
- Drops vendor system_stm32f7xx.c — the app-customised copy in
  9_1_1_C_Cpp_Libraries/ is the real one; keeping both caused duplicate
  symbols.

Incidental fixes to main.cpp (pre-existing bugs exposed by first real
compile):
- DIAG_GPIO at main.cpp:662-663 was called with 3 args; macro takes
  (subsys, name, port, pin). Passed the STATUS0/STATUS1 port+pin pair.
- PI used at main.cpp:1589-1594 for atan2 conversions but never
  defined. Added a local #define PI 3.14159265358979323846f near the
  top of the file.

Result: firmware.elf = 118 548 B text / 776 B data / 12 672 B bss.
Fits comfortably in 1 MB flash; DTCM stack/heap clears 64 KB with room.
This commit is contained in:
Jason
2026-04-23 07:53:41 +05:45
parent 52977fb488
commit 9f3eb756f9
11 changed files with 604 additions and 31 deletions
+20 -29
View File
@@ -1,19 +1,12 @@
# ============================================================================
# AERIS-10 STM32F746ZGT7 firmware build (PR 1: compile-only)
# AERIS-10 STM32F746ZGT7 firmware build
# ============================================================================
# Part: STM32F746ZGT7 (Cortex-M7, 1 MB flash, 320 KB RAM, 216 MHz, LQFP144)
# Toolchain: arm-none-eabi-gcc 15.x (brew --cask gcc-arm-embedded)
#
# PR 1 scope: compile every source file to an object. Linking is expected to
# fail because STM32CubeIDE-generated glue (main.c entry, SystemClock_Config,
# MX_*_Init, stm32f7xx_it.c, stm32f7xx_hal_msp.c, linker script, USB CDC
# glue) is missing. PR 2 will hand-write those files and close the link.
#
# Targets:
# make -- compile all .c/.cpp/.s to objects (default)
# make compile -- same
# make link -- attempt to link (WILL FAIL in PR 1; left here so the
# missing-symbol list drives PR 2 scope)
# make -- compile + link, produces firmware.elf/.bin/.hex (default)
# make compile -- compile only (stops at objects)
# make clean -- remove build/
# ============================================================================
@@ -63,25 +56,24 @@ CXXFLAGS := $(COMMON) -std=gnu++17 -fno-exceptions -fno-rtti -fno-threadsafe-sta
ASFLAGS := $(MCU) $(DEFS) -g3
# ---- sources ---------------------------------------------------------------
# Application C/C++
# main.cpp needs Cube-generated usb_device.h / usbd_cdc_if.h — PR 2 target.
# Exclude from PR 1 compile; um982_gps.c/.h compile cleanly and stay in.
APP_C := $(wildcard $(APP)/*.c)
APP_CPP_ALL := $(wildcard $(APP)/*.cpp)
APP_CPP := $(filter-out $(APP)/main.cpp, $(APP_CPP_ALL))
# App C/C++ — PR 2 adds usb_device.c, usbd_conf.c, usbd_desc.c, usbd_cdc_if.c
# (wildcard picks them up) and re-enables main.cpp + gps_handler.cpp.
APP_C := $(wildcard $(APP)/*.c)
APP_CPP := $(wildcard $(APP)/*.cpp)
LIB_C := $(wildcard $(LIB)/*.c)
# gps_handler.cpp includes usb_device.h (Cube glue) — deferred to PR 2
LIB_CPP := $(filter-out $(LIB)/gps_handler.cpp, $(wildcard $(LIB)/*.cpp))
LIB_CPP := $(wildcard $(LIB)/*.cpp)
# Vendor: all enabled HAL modules compile cleanly because each _hal_<x>.c is
# guarded by `#ifdef HAL_<X>_MODULE_ENABLED` in stm32f7xx_hal_conf.h.
# Build every .c in Src/ and let the guard do the filtering.
# Exclude *_template.c — ST ships these as user-copy stubs, not compile targets
# Vendor HAL: each _hal_<x>.c is guarded by HAL_<X>_MODULE_ENABLED in
# stm32f7xx_hal_conf.h, so compiling all of them is safe. Skip ST's
# *_template.c stubs (user-copy boilerplate, not compile targets).
HAL_C := $(filter-out %_template.c, $(wildcard $(VENDOR)/stm32f7xx_hal_driver/Src/*.c))
# USB Device Library requires a user-written usbd_conf.h (Cube glue, PR 2).
# PR 1 leaves this empty so the vendor tree compiles without that config.
USB_C :=
SYS_C := $(VENDOR)/cmsis_device_f7/Source/Templates/system_stm32f7xx.c
# USB Device library: Core + CDC class (skip *_template.c user stubs).
USB_C := $(filter-out %_template.c, \
$(wildcard $(VENDOR)/stm32_mw_usb_device/Core/Src/*.c) \
$(wildcard $(VENDOR)/stm32_mw_usb_device/Class/CDC/Src/*.c))
# system_stm32f7xx.c already lives in 9_1_1_C_Cpp_Libraries/ (app-customised);
# drop the vendor copy to avoid duplicate symbols.
SYS_C :=
STARTUP := $(VENDOR)/cmsis_device_f7/Source/Templates/gcc/startup_stm32f746xx.s
SRCS_C := $(APP_C) $(LIB_C) $(HAL_C) $(USB_C) $(SYS_C)
@@ -95,8 +87,7 @@ OBJS := \
DEPS := $(OBJS:.o=.d)
# ---- link (PR 2) -----------------------------------------------------------
# Linker script is hand-written in PR 2 at linker/STM32F746ZGTx_FLASH.ld
# ---- link ------------------------------------------------------------------
LDSCRIPT := linker/STM32F746ZGTx_FLASH.ld
LDFLAGS := $(MCU) -T$(LDSCRIPT) -Wl,--gc-sections -Wl,-Map=$(BUILD)/firmware.map \
-specs=nano.specs -specs=nosys.specs -static
@@ -108,7 +99,7 @@ HEX := $(BUILD)/firmware.hex
# ---- rules -----------------------------------------------------------------
.PHONY: all compile link clean size
all: compile
all: link
compile: $(OBJS)
@echo "compiled $(words $(OBJS)) objects"