# `third_party/` — 벤더링된 제3자 의존성 (폐쇄망 / air-gapped)

이 디렉터리에는 STM32F407 펌웨어가 의존하는 **모든 제3자 소스가 고정 버전으로
벤더링**된다. 폐쇄망 빌드 원칙(`~/.claude/rules/common/build-deployment.md`):

> **빌드 머신만 다운로드하고, 타깃/빌드 자체는 외부를 절대 가져오지 않는다.**
> 모든 의존성·런타임·자산은 산출물에 내장된다.

- 인터넷 fetch 는 **빌드 머신에서 단 한 번**, 아래 `vendor.ps1` / `vendor.sh`
  로만 수행한다(저장소 클론).
- `CMakeLists.txt` 는 `third_party/` 안의 소스를 **그대로 참조**하며,
  `FetchContent`/`ExternalProject` 로 네트워크에서 받아오지 **않는다**.
- 이 디렉터리는 용량이 크고 외부 저장소의 사본이므로 git 에 커밋하지 않는다
  (`firmware/.gitignore` 에서 제외). 폐쇄망 반입 시에는 디렉터리째 오프라인
  번들(USB/tar)로 전달한다.

---

## 1. 벤더링 대상 (정확한 저장소 + 고정 태그)

> 아래 태그는 검증된 조합 기준의 권장 핀(pin)이다. 실제 핀 변경 시 본 표와
> `vendor.ps1`/`vendor.sh` 의 태그, 그리고 `firmware/VERSION` 의 빌드 메모를
> 함께 갱신할 것.

| 컴포넌트 | 용도 | 저장소 (canonical) | 고정 태그 | 안착 경로 |
|----------|------|---------------------|-----------|-----------|
| **STM32CubeF4** | HAL + LL 드라이버, CMSIS-Device F4, 시동코드 | `https://github.com/STMicroelectronics/STM32CubeF4` | `v1.28.0` | `third_party/STM32CubeF4/` |
| **CMSIS_5** (선택) | CMSIS-Core(M4F). CubeF4 내장본 사용 시 불필요 | `https://github.com/ARM-software/CMSIS_5` | `5.9.0` | `third_party/CMSIS_5/` |
| **FreeRTOS-Kernel** | RTOS 커널 (네이티브 API) | `https://github.com/FreeRTOS/FreeRTOS-Kernel` | `V11.1.0` | `third_party/FreeRTOS-Kernel/` |
| **lwIP** | TCP/IP 스택 (+ SNTP app) | `https://github.com/lwip-tcpip/lwip` | `STABLE-2_2_0_RELEASE` | `third_party/lwip/` |
| **lwIP contrib** (필요 시) | 포트 예제/추가 app | `https://github.com/lwip-tcpip/lwip-contrib` | `STABLE-2_2_0_RELEASE` | `third_party/lwip-contrib/` |
| **mbedTLS** | TLS1.2 클라이언트, SHA-256(sw) | `https://github.com/Mbed-TLS/mbedtls` | `mbedtls-3.6.2` (LTS) | `third_party/mbedtls/` |

런타임/툴 메모:
- 컴파일러: **arm-none-eabi-gcc 15.2** (오프라인 툴체인 번들에 포함, `third_party` 외부).
- 빌드 시스템: **CMake + Ninja** (빌드 머신 설치본).
- mbedTLS 3.6.x 는 LTS 라인 → 보안 패치 수명이 길어 폐쇄망 장기 운용에 유리.

---

## 2. 각 컴포넌트에서 실제로 쓰는 하위 경로

CubeF4 / FreeRTOS 는 전체 트리가 크지만, CMake 는 아래 핵심 경로만 컴파일·include 한다.

### STM32CubeF4 (`third_party/STM32CubeF4/`)
- HAL/LL 드라이버:
  - `Drivers/STM32F4xx_HAL_Driver/Inc/`
  - `Drivers/STM32F4xx_HAL_Driver/Src/`  (사용 모듈만: RCC, GPIO, CORTEX, ETH, I2C, UART, RNG, IWDG, RTC, DMA, PWR, FLASH …)
- CMSIS-Device F4:
  - `Drivers/CMSIS/Device/ST/STM32F4xx/Include/`        (`stm32f4xx.h`, `stm32f407xx.h`)
  - `Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f407xx.s`  ← **시동코드(GCC)**
  - `Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c`        ← **SystemInit**
- CMSIS-Core:
  - `Drivers/CMSIS/Include/`  (core_cm4.h 등; CMSIS_5 별도 벤더링 시 그쪽 사용)

> 링커 스크립트(`STM32F407VGTx_FLASH.ld`)는 프로젝트가 직접 보유(task stack 을
> CCM 64KB 에 배치하는 커스텀 섹션 포함). CubeF4 템플릿을 베이스로 수정한다.

### FreeRTOS-Kernel (`third_party/FreeRTOS-Kernel/`)
- 코어: 루트의 `tasks.c`, `queue.c`, `list.c`, `timers.c`, `event_groups.c`, `stream_buffer.c`
- 포트(Cortex-M4F, GCC): `portable/GCC/ARM_CM4F/` (`port.c`, `portmacro.h`)
- 힙: `portable/MemMang/heap_4.c`  ← **heap_4 사용**
- include: `include/`
- 설정 헤더 `FreeRTOSConfig.h` 는 프로젝트(`common/` 또는 board 별)가 보유.

### lwIP (`third_party/lwip/`)
- 코어: `src/core/`, `src/core/ipv4/`, `src/api/`, `src/netif/`
- include: `src/include/`
- **SNTP app**: `src/apps/sntp/sntp.c` + `src/include/lwip/apps/sntp.h`  ← 시간 동기(R4)
- 포트(이식): `lwipopts.h`, `sys_arch`(FreeRTOS 연동), LAN8720 RMII `ethernetif.c` 는
  프로젝트가 보유(CubeF4 LwIP 미들웨어 템플릿 또는 ST 예제를 베이스로 작성).

### mbedTLS (`third_party/mbedtls/`)
- 라이브러리: `library/` (TLS/x509/PK/MD/cipher/bignum/SHA-256 등)
- include: `include/`
- 설정: `mbedtls_config.h` (TLS1.2 only, ECDHE-RSA + AES-GCM, `MBEDTLS_SSL_IN/OUT_CONTENT_LEN ≈ 4096`,
  MFL extension, HW 가속 없음 → SHA-256/AES 소프트웨어)는 프로젝트(`common/`)가 보유.
- 엔트로피: STM32 HW RNG 를 `mbedtls_hardware_poll()` 로 연결(프로젝트 측 구현).

---

## 3. 벤더링 스크립트 (빌드 머신에서 1회)

`third_party/` 에 아래 스크립트를 두고, **인터넷이 되는 빌드/스테이징 머신에서만**
실행한다. 결과 디렉터리를 폐쇄망으로 반입한다.

> 두 스크립트 모두 위 표의 태그를 `--depth 1 --branch <tag>` 로 얕은 클론한다.
> 클론 후 각 저장소의 `.git/` 은 제거하여 번들 용량을 줄인다.

### Windows — `third_party/vendor.ps1` (작성 예시)
```powershell
# TODO(hw): 실제 환경에 맞게 태그 확인 후 실행. 빌드 머신 전용(폐쇄망 금지).
$ErrorActionPreference = 'Stop'
$root = $PSScriptRoot
$deps = @(
  @{ url='https://github.com/STMicroelectronics/STM32CubeF4'; tag='v1.28.0';                dir='STM32CubeF4' },
  @{ url='https://github.com/FreeRTOS/FreeRTOS-Kernel';        tag='V11.1.0';                dir='FreeRTOS-Kernel' },
  @{ url='https://github.com/lwip-tcpip/lwip';                 tag='STABLE-2_2_0_RELEASE';   dir='lwip' },
  @{ url='https://github.com/Mbed-TLS/mbedtls';                tag='mbedtls-3.6.2';          dir='mbedtls' }
)
foreach ($d in $deps) {
  $dst = Join-Path $root $d.dir
  if (Test-Path $dst) { Write-Host "skip $($d.dir) (exists)"; continue }
  git clone --depth 1 --branch $d.tag $d.url $dst
  Remove-Item -Recurse -Force (Join-Path $dst '.git')   # 번들 슬림화
}
Write-Host "[OK] vendored into $root"
```

### Linux/macOS — `third_party/vendor.sh` (작성 예시)
```sh
#!/usr/bin/env sh
# TODO(hw): 빌드 머신 전용(폐쇄망 금지).
set -eu
ROOT="$(cd "$(dirname "$0")" && pwd)"
clone() { # url tag dir
  [ -d "$ROOT/$3" ] && { echo "skip $3 (exists)"; return; }
  git clone --depth 1 --branch "$2" "$1" "$ROOT/$3"
  rm -rf "$ROOT/$3/.git"
}
clone https://github.com/STMicroelectronics/STM32CubeF4 v1.28.0              STM32CubeF4
clone https://github.com/FreeRTOS/FreeRTOS-Kernel        V11.1.0              FreeRTOS-Kernel
clone https://github.com/lwip-tcpip/lwip                 STABLE-2_2_0_RELEASE lwip
clone https://github.com/Mbed-TLS/mbedtls                mbedtls-3.6.2        mbedtls
echo "[OK] vendored into $ROOT"
```

> mbedTLS 일부 버전은 `library/` 빌드에 Python 생성 스크립트가 필요할 수 있다.
> 그 산출물도 **빌드 머신에서** 생성해 함께 반입한다(타깃은 생성 금지).

---

## 4. 검증 (폐쇄망 가정)

- [ ] `vendor.*` 실행 후 위 표의 모든 경로가 존재하는지 확인.
- [ ] **네트워크를 끊고** `cmake … && ninja` 로 `sht30_fw` 타깃이
      외부 fetch 없이 빌드되는지 확인.
- [ ] 결과물(`.elf/.bin/.hex`)과 `third_party/` 를 함께 오프라인 번들로 묶어
      반입 절차에 첨부.
- [ ] 어떤 단계라도 네트워크가 필요하면 **명시적으로 FLAG** (조용히 가정 금지).

---

## 5. 디렉터리 레이아웃 (CMake 기대값)

```
firmware/third_party/
 ├─ STM32CubeF4/        # HAL + CMSIS-Device F4 + startup_stm32f407xx.s + system_stm32f4xx.c
 ├─ FreeRTOS-Kernel/    # tasks/queue/timers/... + portable/GCC/ARM_CM4F + portable/MemMang/heap_4.c
 ├─ lwip/               # src/core, src/api, src/netif, src/apps/sntp (+ src/include)
 ├─ mbedtls/            # library/ + include/
 ├─ (CMSIS_5/)          # 선택: CubeF4 내장 CMSIS-Core 미사용 시
 ├─ (lwip-contrib/)     # 선택
 ├─ vendor.ps1          # 빌드 머신 전용 클론 스크립트 (Windows)
 ├─ vendor.sh           # 빌드 머신 전용 클론 스크립트 (POSIX)
 └─ README.md           # 이 문서
```
