8.4 KiB
Message Field Inspector - Documentazione
Panoramica
Sistema per l'ispezione ed export dei metadati dei campi dei messaggi MIL-STD-1553. Estrae automaticamente per ogni campo:
- Name: Nome completo del campo (es:
RDROperationalSettings.spare) - Offset: Indice della word nel messaggio (0-based)
- OffsetValue: Bit di partenza nella word (LSB = 0)
- Width: Numero di bit occupati dal campo
- Type: Tipo del campo (
bitfield,uint16,structure, etc.) - EnumType: Nome del tipo enum se applicabile
File Creati
1. message_inspector.py
Modulo principale con le classi:
FieldMetadata: Rappresenta i metadati di un singolo campoMessageInspector: Ispeziona strutturectypesed estrae metadatiinspect_all_messages(): Ispeziona tutti i messaggi del sistema
2. tools/export_message_fields.py
Script standalone per export completo di tutti i messaggi in formati JSON e XML.
Uso:
python tools/export_message_fields.py
Output generati:
message_fields_export.json: JSON con tutti i messaggimessage_fields_xml/*.xml: File XML separati per ogni messaggio
Formato Export
JSON
{
"A2_MsgRdrOperationCommand": [
{
"Name": "RdrModeCommandWord.des_ctrl",
"Offset": 0,
"OffsetValue": 9,
"Width": 3,
"Type": "bitfield",
"EnumType": "DesignationControl"
}
]
}
XML
<?xml version="1.0" encoding="UTF-8"?>
<Message name="A2_MsgRdrOperationCommand">
<Fields count="24">
<Field>
<Name>RdrModeCommandWord.des_ctrl</Name>
<Offset>0</Offset>
<OffsetValue>9</OffsetValue>
<Width>3</Width>
<Type>bitfield</Type>
<EnumType>DesignationControl</EnumType>
</Field>
</Fields>
</Message>
Uso Programmatico
Esempio 1: Ispezionare un singolo messaggio
from Grifo_E_1553lib.messages import MessageInspector
from Grifo_E_1553lib.messages.msg_rdr_operation_command import MsgRdrOperationCommand
# Ispeziona messaggio A2
fields = MessageInspector.inspect_message(MsgRdrOperationCommand)
# Stampa informazioni
for field in fields:
print(f"{field.name}: Word={field.word_offset}, Bit={field.bit_offset}, Width={field.width}")
Esempio 2: Export JSON di un messaggio
from Grifo_E_1553lib.messages import MessageInspector
from Grifo_E_1553lib.messages.msg_rdr_settings_and_parameters import MsgRdrSettingsAndParameters
# Ispeziona e converti in JSON
fields = MessageInspector.inspect_message(MsgRdrSettingsAndParameters)
json_output = MessageInspector.export_to_json(fields)
# Salva su file
with open('a1_fields.json', 'w') as f:
f.write(json_output)
Esempio 3: Ispezionare tutti i messaggi
from Grifo_E_1553lib.messages import inspect_all_messages
# Ottieni dizionario di tutti i messaggi
all_messages = inspect_all_messages()
# Itera sui messaggi
for msg_name, fields in all_messages.items():
print(f"\n{msg_name}: {len(fields)} campi")
for field in fields:
if field.width == 1: # Solo flag (1 bit)
print(f" - {field.name}")
Esempio 4: Filtrare campi per criterio
from Grifo_E_1553lib.messages import MessageInspector
from Grifo_E_1553lib.messages.msg_rdr_operation_command import MsgRdrOperationCommand
fields = MessageInspector.inspect_message(MsgRdrOperationCommand)
# Trova tutti i campi enum
enum_fields = [f for f in fields if f.enum_type]
print(f"Campi con enum: {len(enum_fields)}")
# Trova campi nella word 0
word0_fields = [f for f in fields if f.word_offset == 0]
print(f"Campi in word 0: {len(word0_fields)}")
# Trova campi multi-bit (non flag)
multibit_fields = [f for f in fields if f.width > 1]
print(f"Campi multi-bit: {len(multibit_fields)}")
Statistiche Export Corrente
Messaggi ispezionati: 11
- A1_MsgRdrSettingsAndParameters (38 campi)
- A2_MsgRdrOperationCommand (24 campi)
- A3_MsgGraphicSetting (92 campi)
- A4_MsgNavDataAndCursor (54 campi)
- A5_MsgInuHighSpeed (24 campi)
- A7_Msg1DataLinkTarget (22 campi)
- A8_Msg2DataLinkTarget (21 campi)
- B4_TrackedTarget02_10 (50 campi)
- B5_TrackedTarget01 (80 campi)
- B6_MsgRdrSettingsAndParametersTellback (82 campi)
- B7_MsgRdrStatusTellback (27 campi)
Totale campi: 502
Note Tecniche
Convenzioni Bit Numbering
Il sistema usa la convenzione Little Endian di ctypes:
- LSB = bit 0 (bit meno significativo)
- MSB = bit 15 (bit più significativo)
- I bitfield in
ctypes.LittleEndianStructuresono numerati sequenzialmente dall'inizio
Esempio:
_fields_ = [
("field_a", c_uint16, 2), # bit 0-1
("field_b", c_uint16, 3), # bit 2-4
("field_c", c_uint16, 11), # bit 5-15
]
Word Offset
L'offset delle word è 0-based:
- Word 0 = prima word del messaggio
- Word 1 = seconda word
- etc.
Le strutture nested incrementano automaticamente il word offset.
Limitazioni Attuali
- Solo ctypes.Structure: supporta solo messaggi basati su
ctypes.Structure/Union - Bitfield semplici: non gestisce bitfield complessi con maschere custom
- Enum mapping: richiede registrazione in
enum_map.ENUM_MAP
Integrazione Futura
GUI Integration
Il MessageInspector può essere integrato nella GUI per:
- Visualizzazione dettagli campo al click
- Tooltip con metadati campo
- Esportazione dinamica messaggi
Versioning ICD
Con la struttura v1/v2 in preparazione, l'inspector potrà:
- Comparare campi tra versioni
- Identificare differenze automaticamente
- Validare compatibilità binaria
Testing
Può essere usato per:
- Generare test di pack/unpack automatici
- Verificare dimensioni messaggi
- Validare mapping ICD vs implementazione
API Reference
FieldMetadata
class FieldMetadata:
name: str # Nome completo campo
word_offset: int # Indice word (0-based)
bit_offset: int # Bit di partenza (LSB=0)
width: int # Numero bit
field_type: str # Tipo campo
enum_type: str # Nome enum (optional)
def to_dict() -> Dict[str, Any]
MessageInspector
class MessageInspector:
@staticmethod
def inspect_message(message_class) -> List[FieldMetadata]
@staticmethod
def inspect_structure(structure_class, word_offset=0) -> List[FieldMetadata]
@staticmethod
def export_to_dict(fields) -> List[Dict[str, Any]]
@staticmethod
def export_to_json(fields, indent=2) -> str
@staticmethod
def export_to_xml(fields) -> str
inspect_all_messages()
def inspect_all_messages() -> Dict[str, List[FieldMetadata]]
Ritorna dizionario con chiave=nome_messaggio, valore=lista_campi.
Esempi Avanzati
Export CSV Personalizzato
import csv
from Grifo_E_1553lib.messages import inspect_all_messages
all_messages = inspect_all_messages()
with open('fields_export.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Message', 'Field', 'Word', 'Bit', 'Width', 'Type'])
for msg_name, fields in all_messages.items():
for field in fields:
writer.writerow([
msg_name,
field.name,
field.word_offset,
field.bit_offset,
field.width,
field.field_type
])
Comparazione tra Messaggi
from Grifo_E_1553lib.messages import MessageInspector
from Grifo_E_1553lib.messages.msg_rdr_settings_and_parameters import MsgRdrSettingsAndParameters
from Grifo_E_1553lib.messages.msg_rdr_settings_and_parameters_tellback import MsgRdrSettingsAndParametersTellback
# Confronta A1 e B6 (dovrebbero essere simili)
a1_fields = MessageInspector.inspect_message(MsgRdrSettingsAndParameters)
b6_fields = MessageInspector.inspect_message(MsgRdrSettingsAndParametersTellback)
print(f"A1: {len(a1_fields)} campi")
print(f"B6: {len(b6_fields)} campi")
# Trova differenze
a1_names = {f.name for f in a1_fields}
b6_names = {f.name for f in b6_fields}
print(f"\nCampi solo in A1: {a1_names - b6_names}")
print(f"Campi solo in B6: {b6_names - a1_names}")
Troubleshooting
Q: I bitfield hanno offset errati?
A: Verifica che la struttura usi ctypes.LittleEndianStructure e non ctypes.BigEndianStructure.
Q: Enum non vengono rilevati?
A: Controlla che siano registrati in Grifo_E_1553lib.data_types.enum_map.ENUM_MAP.
Q: Strutture nested non vengono ispezionate?
A: Verifica che ereditino da ctypes.Structure o ctypes.Union.