¿Mejores prácticas para documentar puertos / periféricos?

6

Recientemente me interesé por el desarrollo integrado y me pregunto cómo la mayoría de las personas documentan sus proyectos. Por ejemplo:

  
  • Cada pin en PORTE está conectado a un LED y tiene un alias como LEDPORT .
  •   
  • Los métodos relacionados con la funcionalidad del LED se encuentran en led.h .
  •   
  • El temporizador / contador 0 en PORTC controla la velocidad de parpadeo de los LEDS.
  •   

etc.

Ciertamente puedo usar una lista de viñetas como esta mientras el proyecto es pequeño, pero tengo la sensación de que se volverá difícil de manejar a medida que el proyecto se convierta en algo más complejo. ¿Cómo se hace esto típicamente? ¿Existe un formato preferido para este tipo de documentación en el mundo del desarrollo integrado profesional?

Después de recibir algunos comentarios, estoy pensando en algo como esto, ¿parece razonable?

|Port|Pin|Peripheral|Desc
|----|---|----------|----
|E   |0  |Led0      |
|E   |1  |Led1      |
|... |...|...       |
|C   |0  |Timer     |Controls the Led blink rate
    
pregunta RubberDuck

5 respuestas

4

La respuesta corta es "lo que tenga sentido para usted y para el resto de su equipo".

Dado que eso no es muy informativo en cuanto a cómo implementar algo, en última instancia, la comunicación del comportamiento deseado es el punto.

Los comentarios no pueden ser probados. Son un riesgo de quedar obsoletos y no mantenerse en general. Sin embargo, los comentarios pueden ayudar a entender el por qué . Hay otros ingenieros inteligentes como usted que descubrirán cómo cómo leyendo la fuente real.

Recomendaría realizar una investigación sobre cómo escribir una Capa de abstracción de hardware (HAL). Esto hace un par de cosas.

  1. Una HAL mostrará en un archivo qué pines se están usando para qué propósito. También puede ser aconsejable indicar qué pines no se usan (son útiles para la depuración / recuperación de nuevos diseños, así que tómese los dos minutos adicionales para documentar los puertos / pines no utilizados ahora y ahórrese 15 minutos para buscarlos cuando los necesite. ellos.)

  2. Al escribir una HAL, el código que usa tu HAL (la aplicación incorporada) no le importará cuál es el pinout real. Esto facilitará la portabilidad cuando (no si) necesita cambiar micros, ya que la mayor parte del trabajo que tendría que tener lugar está en la propia HAL y no en su aplicación.

En resumen, no hay nada de malo en los comentarios, pero el código ejecutable es lo único que importa en términos de lo que realmente está sucediendo.

    
respondido por el cowboydan
3

Encontré el enfoque tipo tabla bastante completo, pero para mí y para los usuarios de mi hardware (en su mayoría estudiantes). Esto es de una simple placa LPC1114, donde se proporcionan la mayoría de los pines de uC en los conectores:

Estatabla(enrealidadsolounaparte)esmuchomáscomplicada,porquelamayoríadelospinesestánmultiplexados:

Tengaencuentaqueenamboscasos,ladocumentaciónesparaunaplacaquehecreado(y,porlotanto,documentado)pormí,peroqueestáprogramadaporotrapersonayqueseutilizaparamásdeunpropósito.Porlotanto,eldiseñodelhardwaretieneuna"vida" propia, separada de cualquier software. Cuando tiene un proyecto para el que diseña tanto el hardware como el software, su enfoque podría ser diferente.

Pero al final, usted (y sus lectores) tendrán que decidir qué es lo más útil.

    
respondido por el Wouter van Ooijen
3

En su mayor parte, la documentación "habitual" se aplicaría, como con cualquier otro proyecto.

Para los campos de puertos y bits, encuentro que un enfoque basado en tablas es el mejor. La tabla tiene una columna para cada bit y una columna de descripción. En cada fila, las combinaciones de bits están dispuestas, normalmente utilizando 1 o 0 y no importa con un x o en blanco, la descripción describe el significado de la combinación. Las discusiones más largas se dejan como notas o párrafos adicionales con más detalle.

    
respondido por el Niall
2

Soy una persona de asamblea PIC de la vieja escuela, por lo que mis sugerencias pueden no ser aplicables a lo que está haciendo. Pero en general, documento lo que hace el pin de puerto justo en el punto del código donde se define el pin.

Aquí hay un ejemplo:

    ADC_INIT        EQU b'00000100' ; ra0,1,3 = a/d   ra2,4,5 = digital
;NOTE: RA3 is a/d so that RA0,1 can be A i/p:  watch out for R-M-W accesses!


; PORT A Device Bits    note: ra 0,1 a/d inputs so no labels for them
    #define _MUXCLK  RA,2        ; RA2, a/d ext mux clk out (active LO)
    #define _MUXRST  RA,3        ; RA3, a/d ext mux reset out (active HI)
    #define _PBWR    RA,4        ; RA4, "WRITE" button (active LO)
    #define _PBRD    RA,5        ; RA5, "READ" button (active LO)

RA_INIT         EQU b'00010000' ; turn off open drain o/p ra4 (early '71s)
DDR_A           EQU b'00110011' ; ddr: ra 2,3==out,  ra 0,1,4,5==in
DIPWRMSK        EQU b'00010000' ;
DIPRDMSK        EQU b'00100000' ;

;WARNING: Output pin MUXRST is configured as a/d input in ADCON1 (the smallest
;possible a/d input configuration) which means that it ALWAYS reads 0 for
;digital i/p.  Any port A R-M-W instructions such as bsf, bcf, tstf, xor, ior
;will force MUXRST LO.  MUXCLK is also o/p: anytime MUXCLK changes, MUXRST will
;go LO.  Reccomend NEVER to use any other pins on port RA as outputs.


; PORT B Device Bits
    #define _IPCRXD RB,0        ; RB0, IPC data input (active LO)
    #define _IPCTXD RB,1        ; RB1, IPC data out (active HI)
    #define _DHTRLD RB,2        ; RB2, display heater LEDs data output
    #define _DSTAT  RB,3        ; RB3, display status & inputs (bidirectional)
    #define _STROBE RB,4        ; RB4, ctrl, DipSw, display strobe, eeprom !CS
    #define _SERCLK RB,5        ; RB5, ctrl, DipSw, display CLOCK
    #define _EECLK  RB,6        ; RB6, eeprom clock
    #define _SERDAT RB,7        ; RB7, ctrl, DipSw, eeprom DATA (bidirectional)

RB_INIT         EQU b'00000001' ;initial port B data status
DDR_B           EQU b'10001001' ;ddr: rb 1,2,4,5,6==out,  rb 0,3,7==in
DDR_BLO         EQU b'10001001' ;AND  0s force bits LO
DDR_BHI         EQU b'00000001' ;OR  1s force bits HI


; PORT C Device Bits
   #define _LCD0    RC,0        ; RC0, LCD bit 4    Note: 4 bit mode: present
   #define _LCD1    RC,1        ; RC1, LCD bit 5    upper nybble first, strobe,
   #define _LCD2    RC,2        ; RC2, LCD bit 6    present lower nybble, strobe
   #define _LCD3    RC,3        ; RC3, LCD bit 7
   #define _LCDS    RC,4        ; RC4, LCD reg select: 0==command  1==data
   #define _LCDE    RC,5        ; RC5, E clock: normally ==0, pulse 1 to strobe
   #define _SRTX    RC,6        ; RC6, RS-232 Tx bit
   #define _SRRX    RC,7        ; RC7, RS-232 Rx Bit

RC_INIT         EQU b'00000000' ; initial port C status
DDR_C           EQU b'11000000' ; port C ddr: rc0..6==out, rc7==in
;b6==i/p till board layout error fixed or patched


; main board control s/r bits           all outputs active HI
;b0=K8  b1=K7   b2=K6   b3=K5   b4=K4   b5=K3   b6=K2   b7=K1
    #define _MGAS_M MAINRLY,0   ;24 Vac main gas valve
    #define _BLOWR6 MAINRLY,1   ;exhaust blower 6
    #define _BLOWR7 MAINRLY,2   ;exhaust blower 7
    #define _PRHT2  MAINRLY,3   ;1== preheat ON
    #define _PRHT1  MAINRLY,4   ;1== preheat ON
    #define _Z1GAS  MAINRLY,5   ;1== zone gas ON
    #define _Z1SBY  MAINRLY,6   ;1== standby mode (0==full heat)
    #define _SW24V  MAINRLY,7   ;24 Vac Power relay


; expansion board control s/r bits       all outputs active HI
;b0=K8  b1=K7   b2=K6   b3=K5   b4=K4   b5=K3   b6=K2   b7=K1
    #define _PRHT4  EXPRLY,0    ;1== preheat ON
    #define _PRHT3  EXPRLY,1    ;1== preheat ON
    #define _Z4SBY  EXPRLY,2    ;1== standby mode (0==full heat)
    #define _Z4GAS  EXPRLY,3    ;1== zone gas ON
    #define _Z2GAS  EXPRLY,4    ;1== zone gas ON
    #define _Z2SBY  EXPRLY,5    ;1== standby mode (0==full heat)
    #define _Z3GAS  EXPRLY,6    ;1== zone gas ON
    #define _Z3SBY  EXPRLY,7    ;1== standby mode (0==full heat)


;off board relay control bits
;b0=K1  b1=K2   b2=K3   b3=K4   b4,b5=dip sw mux    b6=K5   b7=K6
    #define _MGAS_O OFBRLY,0    ;110 Vac main gas valve
    #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 A
    #define _BLOWR4 OFBRLY,6    ;blower 5
    #define _BLOWR5 OFBRLY,7    ;blower 4
;NOTE: background routines write OFBRLY bits 0-3 and ignore OFBRLY bits 4-7.
;Dip sw mux bits are mapped to bit positions 4&5.  OFBRLY bits 4&5 are mapped
;into bit positions 6&7.  OFBRLY bits 6&7 are ignored and are intended to be
;used as flags for blowers 6&7 (MAINRLY bits 1&2).


;local trinary switch inputs (SW1EVEN, SW1ODD)
Z1MASK          EQU b'10000000' ;zone 1 mask
Z2MASK          EQU b'01000000' ;zone 2 mask
;Z3MASK          EQU b'00100000' ;zone 3 mask
BTHOLD          EQU b'00010000' ;batch timer hold: 00=once, 11=always
STRTCAN         EQU b'00001000' ;batch timer start - stop switch
UPDN            EQU b'00000100' ;batch timer up - down switch
    
respondido por el Dwayne Reid
1

Lo que yo uso:

En el esquema: el nombre sería "PA1_INDICATOR_LED" En el código en alguna parte:

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

Donde se rellenan los paréntesis con el código que invierte el bit en su HW.

    
respondido por el Houston Fortney

Lea otras preguntas en las etiquetas