Skip to main content

embedded-medical-device

Firmware development for STM32, nRF52840, and RP2040 medical devices with BLE/USB communication, IEEE 11073 protocols, and secure data handling. When building point-of-care devices (pulse oximeters, BP monitors, glucose meters), embedded gateways, or medical IoT endpoints with TinyGo.

소스 정보

저장소
plurigrid/asi
최근 소스 활동
2026년 6월 10일 11:55
감지된 SKILL.md 언어
영어
스타
67
포크
12

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
2 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
embedded-medical-device
description
Firmware development for STM32, nRF52840, and RP2040 medical devices with BLE/USB communication, IEEE 11073 protocols, and secure data handling. When building point-of-care devices (pulse oximeters, BP monitors, glucose meters), embedded gateways, or medical IoT endpoints with TinyGo.
license
Proprietary. See LICENSE.txt for medical device regulations and compliance.
compatibility
Requires TinyGo 0.40.0+, ARM Cortex-M target support, Nordic SoftDevice (nRF52840), STM32CubeMX (STM32 targets), or Pico SDK (RP2040). Crypto via hardware CryptoAuth secure element (ATECC608A/B) recommended for FDA/IEC 62443 compliance.
metadata
{"version":"1.0.0","device-targets":"nRF52840,STM32F4,STM32H7,RP2040","protocol-support":"IEEE 11073,FHIR,BLE,USB-CDC,UART","crypto-support":"SHA256,AES-128-GCM,ECDSA (hardware-backed)","binary-size-estimated":"45-120 KB (depends on protocol stack)"}
allowed-tools
Bash(tinygo:build*) Bash(openocd:*) Bash(nrfjprog:*) Read
# Embedded Medical Device Firmware Development ## Quick Start ### nRF5340-DK Dual-Core Medical Device (Recommended) **Setup** (5 minutes): 1. Get nRF5340-DK ($99 from Nordic): includes J-Link debugger, USB UART, sensor connectors 2. Install TinyGo: `brew install tinygo` (supports nRF5340 in 0.40.0+) 3. Connect MAX30102 pulse ox sensor to I2C (GPIO 26=SDA, GPIO 27=SCL) 4. Connect serial monitor: `screen /dev/tty.usbmodem14101 115200` **Application processor firmware** (runs on main Cortex-M33): ```go package main import ( "github.com/tinygo-org/bluetooth" "machine" "time" ) func main() { // Initialize sensors on application processor i2c := machine.I2C0 i2c.Configure(machine.I2CConfig{ Frequency: 100_000, SCL: machine.GPIO27, SDA: machine.GPIO26, }) // Read sensor loop (never blocked by BLE on separate processor) ticker := time.NewTicker(10 * time.Millisecond) // 100 Hz sampling for range ticker.C { spo2 := readMAX30102(i2c) // 5µs I2C transaction hr := computeHeartRate(spo2) // Send to BLE (network processor handles async) sendToGATT(spo2, hr) println("SpO2:", spo2, "HR:", hr) } } func readMAX30102(i2c machine.I2C) uint8 { // Fast I2C read (doesn't block sensor loop thanks to dual-core) data := make([]byte, 2) i2c.ReadRegister(0x57, 0x07, data) // RED_LED_CONFIG return data[0] } func computeHeartRate(spo2 uint8) uint8 { return 72 // simplified; real firmware uses FFT on PPG waveform } func sendToGATT(spo2, hr uint8) { // Non-blocking send (network processor handles BLE) // See BLE section below } ``` **Network processor firmware** (runs on Cortex-M4, handles BLE interrupts): The Nordic SoftDevice runs on the network processor automatically. Your application processor calls BLE functions via IPC (Inter-Processor Communication), which is transparent to you—just use the `bluetooth` package as normal. **Key benefit**: While BLE is advertising or transmitting, your sensor loop on the application processor runs **uninterrupted**. This guarantees real-time sensor data at 200+ Hz (required for pulse oximetry accuracy). ### Minimal BLE Pulse Oximeter (nRF52840) ```go package main import ( "github.com/tinygo-org/bluetooth" "machine" "time" ) func main() { // Initialize BLE peripheral role (medical device advertises itself) adapter := bluetooth.DefaultAdapter adapter.Enable() // GATT service for pulse oximetry (IEEE 11073-20601) adv := adapter.StartAdvertisement(&bluetooth.AdvertisementOptions{ LocalName: "PulseOx-001", }) // Simulate SpO2 reading (normally from ADC connected to LED) ticker := time.NewTicker(1 * time.Second) for range ticker.C { spo2 := readSensorValue() // 95-100% typically // Notify connected client with spo2 value _ = spo2 } } func readSensorValue() uint8 { // Connect ADC to photodiode, compute SpO2 via FFT (see references/) return 97 } ``` ### Key Architecture ``` Medical Device Firmware (TinyGo) ├── BLE/USB Transport (tinygo-org/bluetooth or machine/usb/cdc) ├── Sensor Integration (ADC, I2C, SPI) ├── IEEE 11073 Protocol Stack (lightweight Rust/Go bridge or pure Go) ├── Hardware Crypto (via CryptoAuth secure element over I2C) ├── Data Validation (agentskills embedded skill validation) └── Secure Boot & Attestation (if available on target) ``` ## Part 1: Target Microcontroller Selection ### nRF5340-DK (Recommended for Next-Generation Medical Devices) - **Strengths**: Dual Cortex-M33 (Application + Network processors), 512 KB RAM, 1 MB flash, native BLE 5.3 + Thread, Matter support - **Always-on core**: Network processor handles BLE interrupt processing independently (critical for real-time sensor data) - **Use case**: Clinical-grade medical devices, continuous monitoring, low-power wireless gateways - **TinyGo support**: Excellent (new support in TinyGo 0.40.0+) - **Dev kit**: nRF5340-DK ($99, includes J-Link debugger, UART, multiple sensor connectors) - **Binary footprint**: ~80-100 KB with BLE 5.3 stack (smaller than nRF52840 due to Cortex-M33 efficiency) - **Power**: ~2.1 mA active BLE (vs 4 mA nRF52840), ideal for battery-powered medical devices - **Key advantage**: Dual-core means BLE interrupt processing never blocks sensor sampling **Medical advantage**: nRF5340's always-on network processor ensures **real-time sensor data** isn't missed during Bluetooth communication. Critical for pulse oximetry (200 Hz sampling) and ECG (500+ Hz). **Architecture**: ``` nRF5340-DK ├── Application Processor (Cortex-M33) │ ├── Main firmware (sensor logic, FHIR validation) │ ├── I2C: MAX30102 (pulse oximetry) or other sensors │ └── UART/SPI: Data logging to flash │ └── Network Processor (Cortex-M4) ├── Nordic SoftDevice (BLE 5.3, Thread) ├── Always-on real-time processing └── Can wake application processor on events ``` **Comparison to nRF52840**: | Feature | nRF5340-DK | nRF52840 | |---------|-----------|---------| | Dual-core | ✓ (M33+M4) | ✗ (single M4) | | Real-time sensors | ✓ Never blocked | Shared with BLE | | RAM | 512 KB | 256 KB | | BLE version | 5.3 (latest) | 5.2 | | Dev kit cost | $99 | $35-50 | | Power (active) | 2.1 mA | 4.0 mA | | Matter support | ✓ | ✗ | | TinyGo 0.40+ | ✓ | ✓ | **Recommendation**: Use **nRF5340-DK** for FDA submissions (dual-core ensures real-time guarantees), **nRF52840** for simple prototypes (cheaper, sufficient for low-frequency sensors). ### nRF52840 (Best for Medical BLE - Budget Option) - **Strengths**: Native BLE (no WiFi complexity), 256 KB RAM, 1 MB flash, Nordic SoftDevice support - **Use case**: Personal health devices (pulse oximeter, BP monitor, glucose meter) - **TinyGo support**: Excellent (Adafruit boards pre-loaded with SoftDevice) - **Boards**: Adafruit nRF52840 Feather, Arduino Nano 33 BLE, Pimoroni Tiny2040 - **Binary footprint**: ~60-80 KB with BLE stack - **Limitation**: Single-core means sensor sampling and BLE communication compete for CPU **Example**: nRF52840 Feather + Adafruit pulse oximeter breakout + ATECC608A secure element ``` nRF52840 Feather ├── SPI: ATECC608A (hardware crypto, tamper-resistant) ├── I2C: MAX30102 (pulse oximetry sensor) ├── GPIO: LED indicators, button └── BLE: Advertises SpO2 readings to mobile app ``` ### STM32F4/H7 (Clinical Bench Equipment) - **Strengths**: Large flash (512KB-2MB), fast Cortex-M4/M7, extensive peripherals - **Use case**: Benchtop analyzers, ECG machines, ventilator controllers - **TinyGo support**: Partial (some ST NUCLEO boards supported) - **Challenge**: No native BLE; requires external BLE module (e.g., nRF24L01 or separate nRF52) - **Binary footprint**: ~80-120 KB (depends on protocol stack) **Architecture**: STM32 + nRF24L01 bridge (separate MCU for wireless) ``` STM32F407 (clinical device logic) ├── UART1: Communication with nRF24L01 BLE bridge ├── ADC: Multi-channel sensor inputs (ECG leads, temperature, etc.) ├── Flash: 512 KB (firmware + patient data records) └── SPI: SD card for data logging nRF24L01 (separate TinyGo firmware) ├── BLE radio (if variant available) ├── Or: 2.4 GHz ISM band (medical telemetry) └── UART back to STM32 ``` ### RP2040 (Emerging, Dual-Core Promise) - **Strengths**: Cheap ($1-2), dual ARM Cortex-M0+, good peripherals - **Use case**: Distributed sensor networks, gateway devices - **TinyGo support**: Excellent (Raspberry Pi Pico native support, multicore in recent TinyGo) - **Challenge**: Limited RAM (264 KB), no native Bluetooth (but can add external module) - **Binary footprint**: ~40-60 KB minimal **Emerging pattern**: RP2040 in star topology ``` Gateway RP2040 (multicore, runs edge WASI) ├── Core 0: Collects data from peripheral BLE devices (via USB host or separate radio) ├── Core 1: Processes FHIR serialization, validates with agentskills └── USB-CDC: Streams structured data to medical gateway/EHR Peripheral nRF52840 devices (pulse ox, BP monitor, glucose meter) └── BLE: Advertises to gateway RP2040 (acting as central) ``` --- ## Part 2: BLE and IEEE 11073 Protocol Stack ### BLE + GATT Structure for Medical Devices IEEE 11073-20601 (Personal Health Device) defines GATT profiles: ``` Medical Device GATT Service ├── Device Information │ ├── Manufacturer: "Boxxy Medical" │ ├── Model: "PulseOx v1" │ └── Serial: (from secure element) ├── Pulse Oximetry Service (0x180D1 custom) │ ├── SpO2 Characteristic (read, notify) │ ├── HR Characteristic (read, notify) │ └── Status Characteristic (read) ├── Battery Service │ ├── Battery Level (read, notify) │ └── Battery Status (read) └── Generic Access ├── Device Name: "PulseOx-ABC123" └── Appearance: 0x0C41 (Pulse Oximeter) ``` ### TinyGo Bluetooth Example ```go package main import ( "github.com/tinygo-org/bluetooth" "encoding/binary" ) func main() { adapter := bluetooth.DefaultAdapter adapter.Enable() // Define GATT characteristics spo2Char := bluetooth.NewCharacteristic("SpO2", bluetooth.CharacteristicNotifyPermission, bluetooth.CharacteristicReadPermission) adapter.AddService(&bluetooth.Service{ UUID: bluetooth.New16BitUUID(0x180D), // Pulse Oximetry Characteristics: []*bluetooth.Characteristic{spo2Char}, }) // Advertise adv := adapter.StartAdvertisement(&bluetooth.AdvertisementOptions{ LocalName: "PulseOx-001", ServiceUUIDs: []bluetooth.UUID{ bluetooth.New16BitUUID(0x180D), }, }) // Notify client of SpO2 change (97%) spo2 := uint8(97) data := []byte{spo2} spo2Char.Notify(data) } ``` ### Bridging to FHIR (on gateway) For edge processing, the gateway (RP2040 or STM32+bridge) converts IEEE 11073 to FHIR: ```json { "resourceType": "Observation", "code": { "coding": [{ "system": "http://loinc.org", "code": "2708-6", "display": "Oxygen saturation in arterial blood" }] }, "valueQuantity": { "value": 97, "unit": "%", "system": "http://unitsofmeasure.org", "code": "%" }, "device": { "reference": "Device/PulseOx-ABC123", "identifier": { "system": "urn:oid:1.2.840.113556.4.5", "value": "ABC123" // from secure element serial } } } ``` --- ## Part 3: Secure Element Integration (ATECC608A/B) **Why hardware crypto**: Software crypto in TinyGo has failing test suites due to reflect limitations. FDA and IEC 62443 require certified, audited cryptography. ### Wiring (I2C) ``` nRF52840 Feather ATECC608A (Adafruit Breakout) ├── GPIO 26 (SDA) -------> SDA ├── GPIO 27 (SCL) -------> SCL ├── GND ----------------> GND └── 3.3V ----------------> VCC ``` ### TinyGo Code ```go package main import ( "github.com/waj334/tinygo-cryptoauthlib" "machine" ) func main() { // Initialize I2C i2c := machine.I2C0 i2c.Configure(machine.I2CConfig{ Frequency: 100_000, SCL: machine.GPIO27, SDA: machine.GPIO26, }) // Connect to secure element device, err := cryptoauthlib.NewATECC608A(i2c, cryptoauthlib.DefaultAddress) if err != nil { panic(err) } // SHA256 via hardware (faster, certified) data := []byte("patient_id_12345") hash, err := device.SHA256(data) if err != nil { panic(err) } // hash is now [32]byte // Sign challenge for device attestation challenge := [32]byte{} // received from medical gateway signature, err := device.Sign(challenge[:]) if err != nil { panic(err) } // signature is ECDSA signature [64]byte } ``` ### FDA Compliance Path 1. **ATECC608A** is pre-certified for cryptographic operations (FIPS 140-2 candidate) 2. **TinyGo binary** compiled with `-no-debug` and hashing logic is auditable and small 3. **Device attestation** via ECDSA signature chain: Secure Element → Gateway → EHR 4. **Tamper-resistant storage**: ATECC608A stores root key securely, never transmitted This satisfies **21 CFR Part 11** (electronic records, electronic signatures) and **IEC 62443-4-2** (secure development practices). --- ## Part 4: Skill Validation on Embedded Devices The `embedded.go` skill validation subsystem provides capability checking without reflection or standard library bloat. ### Compact Skill Registry (for firmware capabilities) ```go package main import ( "github.com/bmorphism/boxxy/internal/skill" ) func main() { // Initialize registry registry := skill.NewRegistry() // Register firmware capabilities as skills pulseox := &skill.EmbeddedSkill{ Name: "pulse-oximetry", Description: "Read SpO2 and HR via MAX30102 sensor over I2C", Trit: 1, // Generator (+1) role } registry.Register(pulseox) tempsensor := &skill.EmbeddedSkill{ Name: "temperature-monitor", Description: "Monitor body temperature via DS18B20 1-wire sensor", Trit: 0, // Coordinator role } registry.Register(tempsensor) // Check if capabilities are balanced (GF(3) conservation) if registry.IsBalanced() { println("Device capabilities balanced") } // Serialize to EEPROM for capability advertisement over BLE compact := registry.SerializeCompact() // Send `compact` string to mobile app or medical gateway } ``` ### Over-the-Wire Capability Announcement (BLE) ```go // Advertise firmware capabilities to connected gateway via characteristic capabilitiesChar := bluetooth.NewCharacteristic( "FirmwareCapabilities", bluetooth.CharacteristicReadPermission, )
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기