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
@@ -70,6 +70,10 @@ extern "C" {
#include "stm32f7xx_hal.h"
#ifndef PI
#define PI 3.14159265358979323846f
#endif
@@ -659,8 +663,8 @@ SystemError_t checkSystemHealth(void) {
if (HAL_GetTick() - last_clock_check > 5000) {
GPIO_PinState s0 = HAL_GPIO_ReadPin(AD9523_STATUS0_GPIO_Port, AD9523_STATUS0_Pin);
GPIO_PinState s1 = HAL_GPIO_ReadPin(AD9523_STATUS1_GPIO_Port, AD9523_STATUS1_Pin);
DIAG_GPIO("CLK", "AD9523 STATUS0", s0);
DIAG_GPIO("CLK", "AD9523 STATUS1", s1);
DIAG_GPIO("CLK", "AD9523 STATUS0", AD9523_STATUS0_GPIO_Port, AD9523_STATUS0_Pin);
DIAG_GPIO("CLK", "AD9523 STATUS1", AD9523_STATUS1_GPIO_Port, AD9523_STATUS1_Pin);
if (s0 == GPIO_PIN_RESET || s1 == GPIO_PIN_RESET) {
current_error = ERROR_AD9523_CLOCK;
DIAG_ERR("CLK", "AD9523 clock health check FAILED (STATUS0=%d STATUS1=%d)", s0, s1);
@@ -0,0 +1,15 @@
#include "usb_device.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_cdc.h"
#include "usbd_cdc_if.h"
USBD_HandleTypeDef hUsbDeviceFS;
void MX_USB_DEVICE_Init(void)
{
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) { Error_Handler(); }
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) { Error_Handler(); }
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) { Error_Handler(); }
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) { Error_Handler(); }
}
@@ -0,0 +1,20 @@
#ifndef __USB_DEVICE__H__
#define __USB_DEVICE__H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f7xx.h"
#include "stm32f7xx_hal.h"
#include "usbd_def.h"
extern USBD_HandleTypeDef hUsbDeviceFS;
void MX_USB_DEVICE_Init(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,62 @@
#include "usbd_cdc_if.h"
#define APP_RX_DATA_SIZE 2048
#define APP_TX_DATA_SIZE 2048
extern USBD_HandleTypeDef hUsbDeviceFS;
static uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
static uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
static int8_t CDC_Init_FS(void);
static int8_t CDC_DeInit_FS(void);
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length);
static int8_t CDC_Receive_FS(uint8_t *Buf, uint32_t *Len);
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = {
CDC_Init_FS,
CDC_DeInit_FS,
CDC_Control_FS,
CDC_Receive_FS,
NULL,
};
static int8_t CDC_Init_FS(void)
{
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
return USBD_OK;
}
static int8_t CDC_DeInit_FS(void) { return USBD_OK; }
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length)
{
(void)cmd; (void)pbuf; (void)length;
return USBD_OK;
}
/* Called from usbd_cdc.c when host has sent bytes to device.
* The app handler (USBHandler::processUSBData) lives in C++; call it via a
* weak C hook so C++ can override without pulling USBHandler into this TU. */
__attribute__((weak)) void CDC_on_receive(uint8_t *Buf, uint32_t Len)
{
(void)Buf; (void)Len;
}
static int8_t CDC_Receive_FS(uint8_t *Buf, uint32_t *Len)
{
CDC_on_receive(Buf, *Len);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return USBD_OK;
}
uint8_t CDC_Transmit_FS(uint8_t *Buf, uint16_t Len)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)hUsbDeviceFS.pClassDataCmsit[hUsbDeviceFS.classId];
if (hcdc == NULL) return USBD_FAIL;
if (hcdc->TxState != 0) return USBD_BUSY;
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
return USBD_CDC_TransmitPacket(&hUsbDeviceFS);
}
@@ -0,0 +1,18 @@
#ifndef __USBD_CDC_IF_H__
#define __USBD_CDC_IF_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "usbd_cdc.h"
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
uint8_t CDC_Transmit_FS(uint8_t *Buf, uint16_t Len);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,165 @@
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "usbd_conf.h"
PCD_HandleTypeDef hpcd_USB_OTG_FS;
/* ---------- HAL → USBD LL bridge callbacks ---------- */
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
{
USBD_LL_SetupStage((USBD_HandleTypeDef *)hpcd->pData, (uint8_t *)hpcd->Setup);
}
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_DataOutStage((USBD_HandleTypeDef *)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
}
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_DataInStage((USBD_HandleTypeDef *)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
}
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
{
USBD_LL_SOF((USBD_HandleTypeDef *)hpcd->pData);
}
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
{
USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
if (hpcd->Init.speed == PCD_SPEED_HIGH) speed = USBD_SPEED_HIGH;
USBD_LL_SetSpeed((USBD_HandleTypeDef *)hpcd->pData, speed);
USBD_LL_Reset((USBD_HandleTypeDef *)hpcd->pData);
}
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
{
USBD_LL_Suspend((USBD_HandleTypeDef *)hpcd->pData);
__HAL_PCD_GATE_PHYCLOCK(hpcd);
}
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
{
USBD_LL_Resume((USBD_HandleTypeDef *)hpcd->pData);
}
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef *)hpcd->pData, epnum);
}
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef *)hpcd->pData, epnum);
}
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) { USBD_LL_DevConnected((USBD_HandleTypeDef *)hpcd->pData); }
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) { USBD_LL_DevDisconnected((USBD_HandleTypeDef *)hpcd->pData); }
/* ---------- HAL PCD MSP (clock + GPIO + NVIC) ---------- */
void HAL_PCD_MspInit(PCD_HandleTypeDef *pcdHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (pcdHandle->Instance == USB_OTG_FS)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
/* PA11 = USB_OTG_FS_DM, PA12 = USB_OTG_FS_DP */
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
HAL_NVIC_SetPriority(OTG_FS_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
}
}
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *pcdHandle)
{
if (pcdHandle->Instance == USB_OTG_FS)
{
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11 | GPIO_PIN_12);
HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
}
}
/* ---------- USBD LL → HAL bridge ---------- */
static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status)
{
switch (hal_status) {
case HAL_OK: return USBD_OK;
case HAL_ERROR: return USBD_FAIL;
case HAL_BUSY: return USBD_BUSY;
default: return USBD_FAIL;
}
}
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{
hpcd_USB_OTG_FS.pData = pdev;
pdev->pData = &hpcd_USB_OTG_FS;
hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
hpcd_USB_OTG_FS.Init.dev_endpoints = 6;
hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
hpcd_USB_OTG_FS.Init.vbus_sensing_enable= DISABLE;
hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK) Error_Handler();
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
return USBD_OK;
}
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) { return USBD_Get_USB_Status(HAL_PCD_DeInit(pdev->pData)); }
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) { return USBD_Get_USB_Status(HAL_PCD_Start(pdev->pData)); }
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) { return USBD_Get_USB_Status(HAL_PCD_Stop(pdev->pData)); }
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
{ return USBD_Get_USB_Status(HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type)); }
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { return USBD_Get_USB_Status(HAL_PCD_EP_Close(pdev->pData, ep_addr)); }
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { return USBD_Get_USB_Status(HAL_PCD_EP_Flush(pdev->pData, ep_addr)); }
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { return USBD_Get_USB_Status(HAL_PCD_EP_SetStall(pdev->pData, ep_addr)); }
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr){ return USBD_Get_USB_Status(HAL_PCD_EP_ClrStall(pdev->pData, ep_addr)); }
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
if ((ep_addr & 0x80) == 0x80) return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
}
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr)
{ return USBD_Get_USB_Status(HAL_PCD_SetAddress(pdev->pData, dev_addr)); }
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
{ return USBD_Get_USB_Status(HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size)); }
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
{ return USBD_Get_USB_Status(HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size)); }
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{ return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr); }
/* ---------- static allocator (USBD_malloc / free) ---------- */
void *USBD_static_malloc(uint32_t size)
{
static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef) / 4) + 1];
(void)size;
return mem;
}
void USBD_static_free(void *p) { (void)p; }
@@ -0,0 +1,44 @@
#ifndef __USBD_CONF__H__
#define __USBD_CONF__H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f7xx.h"
#include "stm32f7xx_hal.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define USBD_MAX_NUM_INTERFACES 1U
#define USBD_MAX_NUM_CONFIGURATION 1U
#define USBD_MAX_STR_DESC_SIZ 512U
#define USBD_SELF_POWERED 1U
#define USBD_DEBUG_LEVEL 0U
#define USBD_LPM_ENABLED 0U
#define USBD_SUPPORT_USER_STRING_DESC 0U
#define USBD_CDC_INTERVAL 2000U
#define DEVICE_FS 0
#define USBD_malloc USBD_static_malloc
#define USBD_free USBD_static_free
#define USBD_memset memset
#define USBD_memcpy memcpy
#define USBD_Delay HAL_Delay
#define USBD_UsrLog(...) do {} while (0)
#define USBD_ErrLog(...) do {} while (0)
#define USBD_DbgLog(...) do {} while (0)
void *USBD_static_malloc(uint32_t size);
void USBD_static_free(void *p);
void Error_Handler(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,104 @@
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_conf.h"
#define USBD_VID 0x0483 /* STMicroelectronics */
#define USBD_PID_FS 0x5740 /* STM32 Virtual COM Port */
#define USBD_LANGID_STRING 0x0409 /* English (US) */
#define USBD_MANUFACTURER_STRING "STMicroelectronics"
#define USBD_PRODUCT_STRING_FS "AERIS-10 Radar Virtual COM Port"
#define USBD_CONFIGURATION_STRING_FS "CDC Config"
#define USBD_INTERFACE_STRING_FS "CDC Interface"
#ifndef USB_SIZ_STRING_SERIAL
#define USB_SIZ_STRING_SERIAL 0x1A
#endif
static uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
static uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
static uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
static uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
static uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
static uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
static uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
USBD_DescriptorsTypeDef FS_Desc = {
USBD_FS_DeviceDescriptor,
USBD_FS_LangIDStrDescriptor,
USBD_FS_ManufacturerStrDescriptor,
USBD_FS_ProductStrDescriptor,
USBD_FS_SerialStrDescriptor,
USBD_FS_ConfigStrDescriptor,
USBD_FS_InterfaceStrDescriptor,
};
__ALIGN_BEGIN static uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
0x12, /* bLength */
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
0x00, 0x02, /* bcdUSB 2.00 */
0x02, /* bDeviceClass: CDC */
0x02, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
USB_MAX_EP0_SIZE, /* bMaxPacketSize0 */
LOBYTE(USBD_VID), HIBYTE(USBD_VID),
LOBYTE(USBD_PID_FS), HIBYTE(USBD_PID_FS),
0x00, 0x02, /* bcdDevice 2.00 */
USBD_IDX_MFC_STR,
USBD_IDX_PRODUCT_STR,
USBD_IDX_SERIAL_STR,
USBD_MAX_NUM_CONFIGURATION
};
__ALIGN_BEGIN static uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
USB_LEN_LANGID_STR_DESC,
USB_DESC_TYPE_STRING,
LOBYTE(USBD_LANGID_STRING), HIBYTE(USBD_LANGID_STRING),
};
__ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
/* 12-char serial derived from 96-bit unique device ID */
__ALIGN_BEGIN static uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
USB_SIZ_STRING_SERIAL, USB_DESC_TYPE_STRING,
};
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
{
for (uint8_t idx = 0; idx < len; idx++) {
uint8_t nibble = (value >> 28) & 0x0F;
pbuf[2 * idx] = (nibble < 10) ? ('0' + nibble) : ('A' + nibble - 10);
pbuf[2 * idx + 1] = 0;
value <<= 4;
}
}
static void Get_SerialNum(void)
{
uint32_t deviceserial0 = *(uint32_t *)UID_BASE;
uint32_t deviceserial1 = *(uint32_t *)(UID_BASE + 4);
uint32_t deviceserial2 = *(uint32_t *)(UID_BASE + 8);
deviceserial0 += deviceserial2;
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
static uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ (void)speed; *length = sizeof(USBD_FS_DeviceDesc); return USBD_FS_DeviceDesc; }
static uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ (void)speed; *length = sizeof(USBD_LangIDDesc); return USBD_LangIDDesc; }
static uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ (void)speed; USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); return USBD_StrDesc; }
static uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ (void)speed; USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); return USBD_StrDesc; }
static uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ (void)speed; *length = USB_SIZ_STRING_SERIAL; Get_SerialNum(); return USBD_StringSerial; }
static uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ (void)speed; USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length); return USBD_StrDesc; }
static uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ (void)speed; USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc, length); return USBD_StrDesc; }
@@ -0,0 +1,16 @@
#ifndef __USBD_DESC_H
#define __USBD_DESC_H
#ifdef __cplusplus
extern "C" {
#endif
#include "usbd_def.h"
extern USBD_DescriptorsTypeDef FS_Desc;
#ifdef __cplusplus
}
#endif
#endif
+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"
@@ -0,0 +1,134 @@
/*
******************************************************************************
** STM32F746ZGTx linker script (AERIS-10 PR 2)
**
** Memory layout (STM32F746ZGT7, LQFP144, 1 MB flash / 320 KB RAM):
** ITCM : 0x00000000, 16 KB (CPU tightly-coupled instruction RAM)
** FLASH : 0x08000000, 1 MB
** DTCM : 0x20000000, 64 KB (CPU tightly-coupled data RAM — stack/heap)
** RAM : 0x20010000,256 KB (SRAM1 240 KB + SRAM2 16 KB contiguous)
**
** Entry: Reset_Handler (from vendor/cmsis_device_f7 startup).
** Heap: grows up from _end. Stack: grows down from end of DTCM (_estack).
******************************************************************************
*/
ENTRY(Reset_Handler)
_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* top of DTCM for MSP */
_Min_Heap_Size = 0x200;
_Min_Stack_Size = 0x400;
MEMORY
{
ITCM (rx) : ORIGIN = 0x00000000, LENGTH = 16K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 64K
RAM (rw) : ORIGIN = 0x20010000, LENGTH = 256K
}
SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
} >FLASH
.rodata :
{
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
_sidata = LOADADDR(.data);
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >DTCM AT> FLASH
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >DTCM
._user_heap_stack (NOLOAD) :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >DTCM
/* Larger buffers can be placed in .sram using __attribute__((section(".sram"))) */
.sram (NOLOAD) :
{
. = ALIGN(4);
*(.sram)
*(.sram*)
. = ALIGN(4);
} >RAM
/DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) }
.ARM.attributes 0 : { *(.ARM.attributes) }
}