Causa principale del sovraccarico del motore

L'applicazione è un disk loader come parte di un optical disk driver. Questo modulo software controlla il funzionamento del motore secondo l'interrupt esterno da un sensore di posizione. Il modulo funziona bene indipendentemente, ma il motore non si può fermare in una posizione specifica dopo l'integrazione con altri moduli.

Il progettista deve controllare il codice per il motor driver; il codice e' molto semplice (scrive nella "port register" con i valori H/L).

volatile unsigned char *io_port = 0xFF00
void motor_on(void)
{
*io_port |= 0x04;
}
void motor_off(void)
{
*io_port &= 0xFB;
}

L'ingegnere ha catturato e fermato l'esecuzione del codice con un debugger, ha trovato anche che la "port register" e' stata scritta con High (la porta esterna e' tenuta come Low). Infine, si e' rivolto, per aiuto, all'ingegnere Mr T che ha riesaminato il codice assembly del sorgente di cui sopra. L'unica operazione C è composta da quattro istruzioni l'assembly, come segue:

*io_port &= 0xFB;
mov #0xFF00, r3     ; move port register address to r3
mov @r3, r1             ; move port register content to r1
and #0xFB, r1           ; logical operation
mov r1, @r3             ; move result back to port register

Nel frattempo, Mr T. ha visto che un timer di gestione LED e' condiviso con lo stesso pin del motore di controllo e la priorità dell'interrupt timer è inferiore rispetto al interrupt esterno del motore di controllo. Mr. T ha simulato l'occorrenza del bug.

;LED driver in timer interrupt (currently Motor is ON)
mov #0xFF00, r4
mov @r4, r2
or      #0x40,r2
;Interrupt from Motor control
mov #0xFF00, r3     ; move port register address to r3
mov @r3, r1             ; move port register content to r1
and #0xFB, r1           ; logical operation
mov r1, @r3             ; move result back to port register
;switch back to LED timer interrupt, now Motor is OFF
mov r2,@r4
;The motor is switched to ON, since the bit2 is written with H

Ci sono 3 soluzioni:

  1. Il software dovrebbe distribuire l'approccio del'interrupt mask. Durante il funzionamento del motore, gli altri interrupts devono essere disattivati.
  2. Spostare la operazione di interrupt service routine al main loop. Disabilitare l'accesso verso la "port register". La programmazione del RTOS dovrebbe essere progettata molto bene, in caso contrario, vi sono alcuni altri effetti collaterali.
  3. Riassegnare l'accesso verso la porta per ogni cambio di I/O.

Dal momento che il layout dell'hardware è difficile da cambiare e' nessun RTOS e' utilizzato, quindi la soluzione A e' approvata.

Per concludere

Nel 8051 classico, i registri della porta sono "bit-addressable" e più microcontrollori RISC utilizzano la memoria della mappa dei registri della porta. Di conseguenza, la porta di accesso prende un solo ciclo di istruzione della macchina 8051, mentre prende più cicli di istruzione in microcontrollori RISC. L'accesso alla porta, nelle macchine RISC, può essere interrotto e/o alterato.

Poiche l'accesso alla porta e' solo una linea di codice in linguaggio C, e' molto facile da ignorare. Se si vuole portare il progetto dal microcontrollore CISC a RISC, il progettista dovrebbe considerare quanto sopra.

Lo stesso principio e' efficace per l'accesso ai timer ed al DMA. Gli ingegneri dovrebbero ricordarsi di questo problema durante la progettazione dell'architettura del software.

Post dal 25 luglio 2008

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend