Usare interrupt esterni in applicazioni in tempo reale

Azure Sphere supporta l'uso di interrupt esterni in RTApps per MT3620. Sui core in tempo reale MT3620, tali interrupt non utilizzano direttamente GPIO; sono invece cablate indipendentemente da GPIO. Un'RTApp può configurare un interrupt esterno in modo che possa rilevare e rispondere a un segnale su un pin esterno.

Consulta il manuale dell'utente di MT3620 M4 per informazioni sui core in tempo reale su MT3620. Per ulteriori informazioni su indirizzi di base del registro, numeri di interrupt e dettagli simili, richiedere "MT3620 M4 Datasheet" a Avnet tramite posta elettronica Azure.Sphere@avnet.com.

Requisiti per gli interrupt esterni

Per utilizzare un interrupt esterno in un'RTApp sull'MT3620:

  • Richiedere l'interrupt nel file app_manifest.json.
  • Scrivi un gestore di interrupt che risponda al segnale.
  • Inizializzare, configurare e abilitare la funzionalità di interrupt.

Impostazioni del manifesto dell'applicazione

Per usare un interrupt esterno, un'RTApp deve elencarlo nel campo "ExternalInterrupt" della sezione Funzionalità del manifesto dell'applicazione. Identificare l'interrupt da una stringa da EINT0 a EINT23. Ad esempio, la riga seguente specifica l'interruzione esterna 8:

   "Capabilities": {
    "ExternalInterrupt": [ "EINT8"]
  }

Gli interrupt esterni vengono multixed con GPIO allo stesso modo delle altre periferiche e le stesse regole si applicano per quanto riguarda il multiplexing. La RTApp può usare qualsiasi EINT che preferisci, a condizione che nessun'altra applicazione (di alto livello o RTApp) sul dispositivo usi una periferica che esegue il mapping allo stesso blocco. Per informazioni sulla modalità di multiplexed delle interfacce periferiche, vedi Periferiche di I/O .

Se lo scenario dell'applicazione Azure Sphere include anche uno scudo Ethernet, EINT4-EINT7 non è disponibile per rtApp, perché lo scudo usa GPIO 5 (che esegue il mapping a EINT5) in un'app di alto livello, riservando così tutti gli altri pin all'interno di quel blocco.

Gestore interrupt

Il gestore di interrupt deve avere lo stesso nome dell'interrupt richiesto nella tabella vettoriale per M4. Vedere i esempi di driver Codethink Labs MT3620 M4 in GitHub per file VectorTable.h e VectorTable.c di esempio.

Nel file VectorTable.c di esempio, la voce seguente nella tabella vettoriale rappresenta EINT8, ovvero il pin 0 nel blocco 3:

[INT(28)] = gpio_g2_irq0,

Il gestore di interrupt corrispondente nell'esempio è gpio_g2_irq0:

void gpio_g2_irq0(void)
{
    UART_Print(debug, "Interrupt handled.\r\n");
}

Nella tabella vettoriale per la propria applicazione, è possibile assegnare al gestore di interrupt il nome desiderato.

Inizializzare, configurare e abilitare l'interrupt

Nella funzione main() dell'RTApp includere codice per inizializzare la tabella vettoriale, configurare il registro di controllo EINT per l'interrupt e abilitare il gestore interrupt.

Gli esempi di driver Codethink definiscono una VectorTableInit() funzione. È possibile adattare questa funzione di inizializzazione alle proprie esigenze.

Per configurare il registro di controllo EINT, è necessario inizializzarlo come definito nel foglio dati M4. Ad esempio, la funzione seguente inizializza il blocco che contiene un oggetto specificato pin. La funzione definisce tutti gli interrupt esterni con il valore di registro 0x300, che consente il debouncing e gli interrupt active-low.

#define MT3620_CM4_IRQ_DBNC_CNTRL_DEF 0x300

int32_t EINT_ConfigurePin(uint32_t pin)
{
    mt3620_gpio_block_e block = pinToBlock(pin);

    if ((block < MT3620_GPIO_BLOCK_0) || (block > MT3620_GPIO_BLOCK_5)) {
        return ERROR_EINT_NOT_A_PIN;
    }

    uint32_t pinMask  = getPinMask(pin, block);
    uint32_t eintBlock = block - MT3620_GPIO_BLOCK_0;

    switch(pinMask) {
        case 1:
            mt3620_cm4_irq[eintBlock]->cm4_dbnc_con0 = MT3620_CM4_IRQ_DBNC_CNTRL_DEF;
            break;
        case 2:
            mt3620_cm4_irq[eintBlock]->cm4_dbnc_con1 = MT3620_CM4_IRQ_DBNC_CNTRL_DEF;
            break;
        case 4:
            mt3620_cm4_irq[eintBlock]->cm4_dbnc_con2 = MT3620_CM4_IRQ_DBNC_CNTRL_DEF;
            break;
        case 8:
            mt3620_cm4_irq[eintBlock]->cm4_dbnc_con3 = MT3620_CM4_IRQ_DBNC_CNTRL_DEF;
            break;
        default:
            break;
    }

    return ERROR_NONE;
}

Un'app può chiamare questa funzione come segue:

if (EINT_ConfigurePin(8) != ERROR_NONE) {
    UART_Print(debug, "ERROR: EINT initialization failed\r\n");
}

Infine, l'app deve abilitare l'interrupt; Questo esempio usa la NVIC_Enable funzione degli esempi di driver Codethink:

NVIC_EnableIRQ(28, 2);

API di interrupt esterno e codice di esempio

Oltre al codice di esempio generale di Codethink Labs, puoi trovare un'API del driver e la documentazione corrispondente da MediaTek.