Domanda:
Best practice per documentare porte / periferiche?
RubberDuck
2015-08-10 22:03:06 UTC
view on stackexchange narkive permalink

Recentemente mi sono interessato allo sviluppo integrato e mi chiedo come la maggior parte delle persone documenta i propri progetti. Ad esempio:

  • Ogni pin su PORTE è collegato a un LED ed è alias come LEDPORT .
  • I metodi relativi alla funzionalità LED si trovano in led.h .
  • Timer / Contatore 0 su PORTC controlla la velocità di lampeggiamento dei LED.

etc.

Posso certamente usare un elenco puntato come questo mentre il progetto è piccolo, ma ho la sensazione che diventerà ingombrante in quanto il progetto si trasforma in qualcosa di più complesso. Come viene fatto in genere? Esiste un formato preferito per questo tipo di documentazione nel mondo dello sviluppo embedded professionale?


Dopo aver ricevuto un feedback, sto pensando a qualcosa del genere, sembra ragionevole?

  | Porta | Pin | Periferico | Desc | ---- | --- | ---------- | ---- | E | 0 | Led0 || E | 1 | Led1 || ... | ... | ... || C | 0 | Timer | Controlla la frequenza di lampeggiamento dei LED  
Che dispositivo stai usando?Dipende davvero da quello (tipo di opinione orientata lo so), perché vuoi adottare la stessa struttura del tuo dispositivo per rendere il documento coerente.
Non avrei pensato che avrebbe importato @MathieuL, ma attualmente sto usando un ATXMega128A.
Bene, dipende più da se usi o meno molte delle API fornite con il tuo MCU.Se usi a malapena l'APIS rispetto a quello che si adatta al tuo team, ma se fai molto affidamento su un set di API prova ad avere un "aspetto" di come funzionano le API, le API TI non sono scritte o documentate come le API stm32ad esempio anche se usano l'architettura ARM (parlo di Tiva di Ti)
In realtà è un bel richiamo @MathieuL.In realtà sto attivamente evitando le API per ora perché voglio imparare cose a un livello piuttosto basso.Forse se * li usassi *, questo documento non varrebbe nemmeno la pena.
Potete creare una classe per la funzionalità LED e incapsulare la porta LED (PORTE) all'interno di quella classe?La porta può essere hardcoded o assegnata tramite il costruttore.
È C @NickAlexeev.Nessuna classe, ma l'ho incapsulata all'interno del proprio file e intestazione.
Lavoro su un progetto che ha centinaia di punti I / O.Usiamo fogli di calcolo Excel per documentare tutti i punti di I / O.Poiché tutto l'I / O è distribuito su diverse schede microcontrollore, penso che vengano utilizzati più fogli Excel, organizzati in base a dove si trovano fisicamente nella macchina (i sensori e gli attuatori, cioè)
Cinque risposte:
cowboydan
2015-08-10 22:20:36 UTC
view on stackexchange narkive permalink

La risposta breve è "qualunque cosa abbia senso per te e per il resto della tua squadra".

Dal momento che non è molto informativo su come implementare qualcosa, in ultima analisi, il punto è comunicare il comportamento previsto.

I commenti non possono essere testati. In generale, sono un rischio per diventare obsoleti e non mantenuti. I commenti possono aiutare a comprendere il perché . Ci sono altri ingegneri intelligenti come te che scopriranno il come leggendo la fonte effettiva.

Suggerirei di fare qualche ricerca sulla scrittura di un Hardware Abstraction Layer (HAL). Questo fa un paio di cose.

  1. Un HAL mostrerà in un file quali pin vengono utilizzati per quale scopo. Potrebbe anche essere consigliabile indicare quali pin non vengono utilizzati (sono utili per il debug / richiamo di nuovi progetti, quindi dedica due minuti extra per documentare le porte / pin inutilizzati ora e risparmia 15 minuti per cercarli quando ne hai bisogno loro.)

  2. Scrivendo un HAL, il codice che usa il tuo HAL (l'applicazione incorporata) non si preoccuperà di quale sia il pinout effettivo. Ciò faciliterà la portabilità quando (non se) è necessario cambiare i micro in quanto il peso del lavoro che dovrebbe svolgersi è nell'HAL stesso e non nell'applicazione.

In sintesi, non c'è niente di sbagliato nei commenti, ma il codice eseguibile è l'unica cosa che conta in termini di ciò che sta realmente accadendo.

Uno dei motivi per cui scrivo unit test è perché il codice è l'unica documentazione che non è mai obsoleta.Lo vedo come un'applicazione di quel principio.++
Approssimativamente, le mappature delle porte saranno solo un file h specifico del progetto che contiene tutte le mappature delle porte, come `#define LED0_PORT PORTE` e` #define LED0 (1 << 0) `.E poi nella parte indipendente dall'hardware, scriverai cose come `LED0_PORT | = LED0;`.Se in un secondo momento è necessario spostare il LED0 su un altro pin in un'altra revisione PCB, è sufficiente modificare il file h.E assicurati di usare esattamente lo stesso nome per i segnali PCB delle macro / variabili C, per ridurre al minimo la confusione tra hw e sw (specialmente se hw e sw sono fatti da persone diverse).
Wouter van Ooijen
2015-08-10 23:06:30 UTC
view on stackexchange narkive permalink

Ho trovato l'approccio simile a una tabella abbastanza utile, ma per me stesso e per gli utenti del mio hardware (principalmente studenti). Questo proviene da una semplice scheda LPC1114, dove la maggior parte dei pin uC sono forniti sui connettori:

enter image description here

Questa tabella (in realtà solo una parte) è molto più complicato, perché la maggior parte dei pin sono multiplexati:

enter image description here

Nota che in entrambi i casi la documentazione è per una scheda che è fatta (e quindi documentato) da me, ma programmato da qualcun altro e utilizzato per più di uno scopo. Quindi il design dell'hardware ha una "vita" propria, separata da qualsiasi software. Quando hai un progetto per il quale progetti sia l'hardware che il software, il tuo approccio potrebbe essere diverso.

Ma alla fine tu (ei tuoi lettori) dovrete decidere cosa è più utile.

Niall
2015-08-03 01:07:46 UTC
view on stackexchange narkive permalink

Per la maggior parte, si applicherebbe la "solita" documentazione, come per qualsiasi altro progetto.

Per le porte e i campi di bit, trovo che un approccio basato su tabelle sia il migliore. La tabella ha una colonna per ogni bit e una colonna di descrizione. In ogni riga sono disposte le combinazioni di bit, tipicamente utilizzando 1 o 0 e non importa con una x o uno spazio, il descrizione descrive il significato della combinazione. Discussioni più lunghe vengono lasciate come note o ulteriori paragrafi con maggiori dettagli.

Mi piace.Gli conferisce un elemento visivo che trovo appropriato.
Tecnicamente "non importa" dovrebbe essere una "X".
Dwayne Reid
2015-08-10 23:42:38 UTC
view on stackexchange narkive permalink

Sono una persona di tipo assembly PIC vecchia scuola, quindi i miei suggerimenti potrebbero non essere applicabili a ciò che stai facendo. Ma in generale, documento ciò che il pin della porta sta facendo proprio nel punto del codice in cui è definito il pin.

Ecco un esempio:

  ADC_INIT EQU b "00000100"; ra0,1,3 = a / d ra2,4,5 = digitale; NOTA: RA3 è a / d quindi RA0,1 può essere A i / p: attenzione agli accessi R-M-W !; PORTA A Device Bits nota: ra 0,1 ingressi a / d quindi nessuna etichetta per loro #define _MUXCLK RA, 2; RA2, a / d ext mux clk out (attivo LO) #define _MUXRST RA, 3; RA3, a / d ext mux reset out (attivo HI) #define _PBWR RA, 4; RA4, pulsante "WRITE" (LO attivo) #define _PBRD RA, 5; RA5, pulsante "READ" (LO attivo) RA_INIT EQU b'00010000 '; spegnere lo scarico aperto o / p ra4 (primi anni '71) DDR_A EQU b'00110011 '; ddr: ra 2,3 == out, ra 0,1,4,5 == inDIPWRMSK EQU b'00010000 '; DIPRDMSK EQU b'00100000' ;; ATTENZIONE: il pin di uscita MUXRST è configurato come ingresso a / d in ADCON1 ( il più piccolo; possibile configurazione dell'ingresso a / d) il che significa che legge SEMPRE 0 per; i / p digitale. Qualsiasi istruzione di porta A R-M-W come bsf, bcf, tstf, xor, ior; forzerà MUXRST LO. MUXCLK è anche o / p: ogni volta che MUXCLK cambia, MUXRST andrà a LO. Si consiglia di NON utilizzare MAI altri pin sulla porta RA come uscite .; Porta B Bit dispositivo #define _IPCRXD RB, 0; RB0, input dati IPC (LO attivo) #define _IPCTXD RB, 1; RB1, uscita dati IPC (attivo HI) #define _DHTRLD RB, 2; RB2, display riscaldatore LED uscita dati #define _DSTAT RB, 3; RB3, visualizza lo stato Ingressi & (bidirezionali) #define _STROBE RB, 4; RB4, ctrl, DipSw, display strobo, eeprom! CS #define _SERCLK RB, 5; RB5, ctrl, DipSw, display CLOCK #define _EECLK RB, 6; RB6, orologio eeprom #define _SERDAT RB, 7; RB7, ctrl, DipSw, eeprom DATA (bidirezionale) RB_INIT EQU b'00000001 '; stato dati della porta B iniziale
DDR_B EQU b'10001001 '; ddr: rb 1,2,4,5,6 == out, rb 0,3,7 == inDDR_BLO EQU b'10001001'; AND 0s force bits LODDR_BHI EQU b'00000001 '; OR 1s forza bit HI; Bit del dispositivo PORT C #define _LCD0 RC, 0; RC0, LCD bit 4 Nota: modalità 4 bit: presente #define _LCD1 RC, 1; RC1, LCD bit 5 prima nybble superiore, strobo, #define _LCD2 RC, 2; RC2, LCD bit 6 presente nybble inferiore, strobo #define _LCD3 RC, 3; RC3, LCD bit 7 #define _LCDS RC, 4; RC4, selezione registro LCD: 0 == comando 1 == dati #define _LCDE RC, 5; RC5, E clock: normalmente == 0, impulso 1 allo strobo #define _SRTX RC, 6; RC6, bit Tx RS-232 #define _SRRX RC, 7; RC7, RS-232 Rx BitRC_INIT EQU b'00000000 '; porta iniziale C statusDDR_C EQU b'11000000 '; porta C ddr: rc0..6 == out, rc7 == in; b6 == i / p fino all'errore di layout della scheda risolto o patchato; controllo scheda principale bit s / r tutte le uscite attive HI; b0 = K8 b1 = K7 b2 = K6 b3 = K5 b4 = K4 b5 = K3 b6 = K2 b7 = K1 #define _MGAS_M MAINRLY, 0; valvola gas principale 24 Vac #define _BLOWR6 MAINRLY, 1; ventilatore di scarico 6 #define _BLOWR7 MAINRLY, 2; ventilatore di scarico 7 #define _PRHT2 MAINRLY, 3; 1 == preriscaldamento ON #define _PRHT1 MAINRLY, 4; 1 == preriscaldamento ON #define _Z1GAS MAINRLY, 5 == zona gas ON #define _Z1SBY MAINRLY, 6; 1 == modalità standby (0 == full heat) #define _SW24V MAINRLY, 7; Relè alimentazione 24 Vac; controllo scheda espansione bit s / r tutte le uscite attive HI; b0 = K8 b1 = K7 b2 = K6 b3 = K5 b4 = K4 b5 = K3 b6 = K2 b7 = K1 #define _PRHT4 EXPRLY, 0; 1 == preriscaldamento ON #define _PRHT3 EXPRLY, 1; 1 == preriscaldamento ON #define _Z4SBY EXPRLY, 2; 1 == modalità standby (0 == full heat) #define _Z4GAS EXPRLY, 3; 1 == zone gas ON #define _Z2GAS EXPRLY, 4; 1 == zona gas ON #define _Z2SBY EXPRLY, 5; 1 == modalità standby (0 == full heat) #define _Z3GAS EXPRLY, 6; 1 == zona gas ON #define _Z3SBY EXPRLY, 7; 1 == modalità standby ( 0 == calore completo)
; bit di controllo relè esterno; b0 = K1 b1 = K2 b2 = K3 b3 = K4 b4, b5 = dip sw mux b6 = K5 b7 = K6 #define _MGAS_O OFBRLY, 0; 110 Vac valvola gas principale #define _BLOWR1 OFBRLY, 1 ; blower 1 #define _BLOWR2 OFBRLY, 2; blower 2 #define _BLOWR3 OFBRLY, 3; blower 3 #define _DSMUXB OFBRLY, 4; dip sw selector mux ctrl bit B #define _DSMUXA OFBRLY, 5; dip sw selector mux ctrl bit Atrl # define _BLOWR4 OFBRLY, 6; blower 5 #define _BLOWR5 OFBRLY, 7; blower 4; NOTA: le routine in background scrivono OFBRLY bit 0-3 e ignorano OFBRLY bit 4-7.; Dip sw mux bit sono mappati nelle posizioni bit 4&5. I bit OFBRLY 4&5 vengono mappati; nelle posizioni dei bit 6&7. I bit OFBRLY 6&7 sono ignorati e sono destinati ad essere; utilizzati come flag per i soffiatori 6&7 (MAINRLY bit 1&2) .; ingressi di commutazione trinary locale (SW1EVEN, SW1ODD) Z1MASK EQU b'10000000 '; zona 1 EQU00 maskZ2 2 maschera; Z3MASK EQU b'00100000 '; maschera zona 3 BTHOLD EQU b'00010000'; blocco timer batch: 00 = una volta, 11 = sempre STRTCAN EQU b'00001000 '; interruttore avvio / arresto timer batch UPDN EQU b'00000100'; timer batch interruttore su / giù  
Houston Fortney
2015-08-16 00:15:53 UTC
view on stackexchange narkive permalink

Cosa uso:

Sullo schema: il nome sarebbe "PA1_INDICATOR_LED" Nel codice da qualche parte:

  define INDICATOR_LED_ON () () define INDICATOR_LED_OFF () ()  

Dove le parentesi sono riempite con qualsiasi codice capovolga il bit sul tuo HW.



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...