Gestione di bug, stranezze o fastidi nelle intestazioni fornite dal fornitore

3

Se il file di intestazione fornito da un venditore di qualcosa con cui il proprio codice deve interagire è carente in qualche modo, in quali casi è meglio:

  1. aggirare le carenze dell'intestazione nel codice principale
  2. Copia il file di intestazione nel progetto locale e risolvilo
  3. Correggi il file di intestazione nel punto in cui è memorizzato come strumento fornito dal fornitore
  4. Correggi il file di intestazione nel punto centrale, ma crea anche una copia locale e prova ad avere sempre le due corrispondenze
  5. Fai qualcos'altro

Ad esempio, il file di intestazione fornito da ST Micro per la serie STM320LF contiene le linee:

typedef struct
{
  __IO uint32_t MODER;
  __IO uint16_t OTYPER;
  uint16_t RESERVED0;
  ....
  __IO uint16_t BSRRL; /* BSRR register is split to 2 * 16-bit fields BSRRL */
  __IO uint16_t BSRRH; /* BSRR register is split to 2 * 16-bit fields BSRRH */
  ....    
} GPIO_TypeDef;

Nell'hardware e nella documentazione dell'hardware, BSRR è descritto come un singolo registro a 32 bit. Circa il 98% delle volte che si vuole scrivere su BSRR, si sarà interessati solo a scrivere la metà superiore o la metà inferiore; è quindi conveniente poter usare BSSRH e BSSRL come mezzo per scrivere metà del registro. D'altra parte, ci sono occasioni in cui è necessario che l'intero registro a 32 bit sia scritto come una singola operazione atomica. Il modo "ottimale" di scriverlo (mettendo da parte i problemi di spaziatura bianca) sarebbe:

typedef struct
{
  __IO uint32_t MODER;
  __IO uint16_t OTYPER;
  uint16_t RESERVED0;
  ....
  union // Allow BSRR access as 32-bit register or two 16-bit registers
  {
    __IO uint32_t BSRR; // 32-bit BSSR register as a whole
    struct { __IO uint16_t BSRRL, BSRRH; };// Two 16-bit parts
  };
  ....    
} GPIO_TypeDef;

Se la struttura è stata definita in questo modo, il codice potrebbe utilizzare BSRR quando necessario per scrivere tutti i 32 bit o BSRRH / BSRRL quando si scrivono 16 bit. Dato che l'intestazione non è così, sarebbe meglio usare l'intestazione come-è, ma applicare un icky typecast nel codice principale scrivendo ciò che sarebbe scritto in modo idioma come thePort->BSRR = 0x12345678; come *((uint32_t)&(thePort->BSSRH)) = 0x12345678; , o sarebbe essere meglio usare un file di intestazione con patch? Se quest'ultimo, dove dovrebbe essere archiviato il file con patch e come dovrebbe essere gestito?

Modifica

Nel file di dati di questo fornitore, i registri di dispositivi I / O sono definiti utilizzando definizioni di struttura come sopra con definizioni di macro come #define GPIOB (*((struct GPIO_TypeDef*)GPIO_BASE + 0x100)) . Poiché GPIOA , GPIOB ecc. Sono definiti come macro piuttosto che identificatori, qualsiasi sostituzione macro di GPIO_TypeDef che diventa effettiva dopo che la struttura è stata definita influenzerà gli usi futuri di quel tipo ma si applicherà anche a GPIOA , GPIOB , ecc. Quindi, la mia inclinazione attuale sarebbe quella di definire il mio file di intestazione a livello di progetto che #include s è il file del venditore, e quindi definisce la mia struttura e macro-sostituti il nome della mia struttura per il venditore. Ciò consentirebbe al codice di essere scritto di utilizzare i registri nel normale modo idiomatico mentre si utilizzano le definizioni fornite dal fornitore per quasi tutto il resto e pur fornendo un chiaro punto di patch.

    
posta supercat 06.10.2012 - 01:31
fonte

1 risposta

2

Mi asterrò dal cambiare i fornitori delle intestazioni e aggirò i limiti a meno che la soluzione alternativa non venga utilizzata troppe volte (più di una volta?). Ora applico le seguenti guide.

  • Nella maggior parte dei casi è presuntuoso pensare che conosca meglio di fornitore. (dice con un leggero accenno di sarcasmo)
  • L'aggiornamento della catena di strumenti in un secondo momento può essere un problema - risolvibile con un buon controllo di revisione del codice del fornitore.
  • Il codice non può più essere semplicemente documentato come "Prerequisito: Installa prodotto XYZ V1.2.3"
  • Il codice non corrisponde ai fornitori e alle aspettative degli altri - può essere più difficile discuterne se necessario - anche le discussioni con altri ingegneri hanno molta familiarità con le intestazioni dei fornitori.

Dove mi trovo in questa situazione, ho modificato le intestazioni dei venditori e ho pagato una sanzione costosa in seguito. Ora tendo a creare la mia intestazione che avvolge i fornitori, lasciando loro consegnati. Ho anche occasionalmente inviato i miglioramenti al fornitore per le versioni future. Tutte le ipotesi che il mio codice fa sulla dimensione e sulla forma delle strutture dati dei fornitori sono verificate in fase di compilazione (o in fase di esecuzione) usando #error e asseriti o altri mezzi adatti.

Quindi nell'esempio sopra, vorrei semplicemente creare "ImprovedGPIO_typeDef" con un

asser (sizeof (GPIO_typeDef) == sizeof (ImprovedGPIO_typedef));

    
risposta data 06.10.2012 - 09:45
fonte

Leggi altre domande sui tag