SXXXXXXX_PyDownloadFwViaSRIO/doc/profiles_guide.md
2026-01-22 17:10:05 +01:00

6.5 KiB

Profile Management System

Overview

Il sistema di gestione dei profili è stato completamente ristrutturato per supportare una configurazione gerarchica a tre livelli che rispecchia fedelmente il formato targets.ini della vecchia applicazione C++/Qt.

Struttura

1. GlobalConfig

Configurazione globale del sistema:

  • ip: Indirizzo IP per la comunicazione SRIO
  • port: Porta per comunicazione TFTP/SRIO
  • srio_base: Indirizzo base SRIO (es. 0x500000)
  • fpga_base: Indirizzo base FPGA (es. 0x0)
  • fpga_sector: Dimensione settore FPGA (es. 0x010000)
  • smart: Flag modalità smart (0 o 1)
  • section: Sezione flash di default (es. "APP1")
  • default_target: Target di default da usare

2. FlashModel

Definizione riutilizzabile di modelli FPGA:

  • id_model: ID univoco del modello (0, 1, 2, ...)
  • model: Nome del modello (es. "xcku040", "rfif")
  • description: Descrizione leggibile
  • flash_type: Tipo di flash (0 o 1)
  • is_4byte_addressing: True per indirizzamento a 4 byte
  • num_sectors: Numero totale di settori
  • golden_start/stop: Area Golden (firmware di boot)
  • user_start/stop: Area User (firmware applicativo)
  • test_address: Indirizzo opzionale per test

3. FlashTarget

Target specifico (FPGA installata):

  • id_target: ID univoco del target (es. "EIF_FPGA1")
  • description: Descrizione leggibile
  • slot_address: Indirizzo slot SRIO (es. 0x13)
  • architecture: Architettura (es. "Xilinx", "RFIF")
  • name: Nome del target
  • file_prefix: Prefisso per i file firmware
  • id_model: Riferimento all'ID del modello
  • binary_path: Path opzionale al file binario

Utilizzo

Caricamento da INI

from pathlib import Path
from pydownloadfwviasrio.profiles import ProfileManager

# Crea manager e carica da targets.ini
manager = ProfileManager()
manager.load_from_ini(Path("_OLD/Vecchia_app/FpgaBeamMeUp/targets.ini"))

# Salva in formato JSON
manager.config_path = Path("flash_profiles.json")
manager.save()

Caricamento da JSON

from pydownloadfwviasrio.profiles import ProfileManager

# Carica configurazione esistente
manager = ProfileManager(Path("flash_profiles.json"))

# Accedi alla configurazione globale
print(f"IP: {manager.global_config.ip}")
print(f"Port: {manager.global_config.port}")

Accesso ai Target e Modelli

# Ottieni un target specifico
target = manager.get_target("AESA_RFIF")
if target:
    print(f"Slot: 0x{target.slot_address:02X}")
    print(f"Architecture: {target.architecture}")

# Ottieni il modello associato
model = manager.get_model(target.id_model)
if model:
    print(f"Model: {model.model}")
    print(f"Sectors: {model.num_sectors}")
    print(f"Addressing: {'4-byte' if model.is_4byte_addressing else '3-byte'}")

# O usa il metodo comodo per ottenere entrambi
result = manager.get_target_with_model("AESA_RFIF")
if result:
    target, model = result
    # ... usa target e model

Iterazione sui Target

# Lista tutti i target disponibili
for id_target in manager.list_targets():
    target = manager.get_target(id_target)
    model = manager.get_model(target.id_model)
    print(f"{id_target}: {target.description}")
    print(f"  Model: {model.model} ({model.description})")

Aggiunta/Modifica

from pydownloadfwviasrio.profiles import FlashModel, FlashTarget

# Aggiungi un nuovo modello
new_model = FlashModel(
    id_model=3,
    model="xcku115",
    description="512Mbit xcku115",
    flash_type=1,
    is_4byte_addressing=True,
    num_sectors=1024,
    golden_start=0x00000000,
    golden_stop=0x01FFFFFF,
    user_start=0x02000000,
    user_stop=0x03FFFFFF,
)
manager.add_model(new_model)

# Aggiungi un nuovo target
new_target = FlashTarget(
    id_target="TEST_FPGA1",
    description="Test FPGA 0x20",
    slot_address=0x20,
    architecture="Xilinx",
    name="TEST_FPGA1",
    file_prefix="TEST_FPGA1",
    id_model=3,  # Riferimento al modello appena creato
)
manager.add_target(new_target)

# Salva le modifiche
manager.save()

Esportazione in INI

# Esporta la configurazione in formato INI
manager.export_to_ini(Path("new_targets.ini"))

Vantaggi della Nuova Struttura

  1. DRY (Don't Repeat Yourself): I modelli si definiscono una volta sola e vengono referenziati dai target
  2. Manutenibilità: Modifiche al modello si propagano automaticamente a tutti i target che lo usano
  3. Estensibilità: Facile aggiungere nuovi target senza duplicare configurazioni
  4. Retrocompatibilità: Supporta sia formato JSON che INI
  5. Type Safety: Uso di dataclass con type hints per validazione automatica

Migrazione da Vecchio Formato

Il vecchio formato (lista di FlashProfile) è deprecato ma ancora supportato per retrocompatibilità. Per convertire:

from pydownloadfwviasrio.profiles import initialize_from_targets_ini

# Conversione automatica da targets.ini
manager = initialize_from_targets_ini(
    ini_path=Path("_OLD/Vecchia_app/FpgaBeamMeUp/targets.ini"),
    json_path=Path("flash_profiles.json")
)

File di Configurazione Iniziali

Il progetto include già un file flash_profiles.json generato dal targets.ini originale con:

  • 3 modelli: xcku040, xcku060, rfif
  • 9 target: EIF_FPGA1/2, XIF1_FPGA1/2, XIF2_FPGA1/2, DFE_FPGA1/2, AESA_RFIF

Script di Utilità

Nella cartella tools/ sono disponibili:

  • convert_ini_to_json.py: Converte targets.ini in flash_profiles.json
  • example_profile_usage.py: Esempio completo di utilizzo del sistema
  • test_conversion.py: Test di conversione bidirezionale INI ↔ JSON

Esempio Completo

from pathlib import Path
from pydownloadfwviasrio.profiles import ProfileManager

# Carica configurazione
manager = ProfileManager(Path("flash_profiles.json"))

# Ottieni target di default con modello
default_id = manager.global_config.default_target
result = manager.get_target_with_model(default_id)

if result:
    target, model = result
    
    print(f"Programming target: {target.id_target}")
    print(f"Slot address: 0x{target.slot_address:02X}")
    print(f"IP:Port: {manager.global_config.ip}:{manager.global_config.port}")
    print(f"Model: {model.model}")
    print(f"Flash type: {model.flash_type}")
    print(f"Addressing: {'4-byte' if model.is_4byte_addressing else '3-byte'}")
    print(f"Golden area: 0x{model.golden_start:08X} - 0x{model.golden_stop:08X}")
    print(f"User area: 0x{model.user_start:08X} - 0x{model.user_stop:08X}")
    
    # Qui puoi usare questi dati per la programmazione...