Compartilhar via


Use interrupções externas em aplicativos com capacidade de tempo real

Importante

Esta é a documentação do Azure Sphere (herdado). O Azure Sphere (herdado) será desativado em 27 de setembro de 2027 e os usuários devem migrar para o Azure Sphere (integrado) até esse momento. Use o seletor de versão localizado acima do sumário para exibir a documentação do Azure Sphere (Integrado).

O Azure Sphere dá suporte ao uso de interrupções externas em RTApps para o MT3620. Nos núcleos em tempo real MT3620, essas interrupções não usam o GPIO diretamente; em vez disso, eles são conectados independentemente do GPIO. Um RTApp pode configurar uma interrupção externa para que possa detectar e responder a um sinal em um pino externo.

Consulte o Manual do Usuário do MT3620 M4 para obter informações sobre os núcleos em tempo real no MT3620. Para obter informações adicionais sobre endereços base de registro, números de interrupção e detalhes semelhantes, solicite a "Folha de dados MT3620 M4" da Avnet enviando um e-mail para Azure.Sphere@avnet.com.

Requisitos de interrupção externa

Para usar uma interrupção externa em um RTApp no MT3620:

  • Solicite a interrupção no arquivo app_manifest.json.
  • Escreva um manipulador de interrupção que responda ao sinal.
  • Inicialize, configure e habilite a funcionalidade de interrupção.

Configurações do manifesto do aplicativo

Para usar uma interrupção externa, um RTApp deve listá-la no campo "ExternalInterrupt" da seção Recursos do manifesto do aplicativo. Identifique a interrupção por uma string de EINT0 a EINT23. Por exemplo, a linha a seguir especifica a interrupção externa 8:

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

As interrupções externas são multiplexadas com GPIO da mesma forma que outros periféricos, e as mesmas regras se aplicam à multiplexação. Seu RTApp pode usar qualquer EINT de sua preferência, desde que nenhum outro aplicativo (de alto nível ou RTApp) no dispositivo use um periférico que mapeie para o mesmo bloco. Consulte Periféricos de E/S para obter informações sobre como as interfaces periféricas são multiplexadas.

Se o cenário de aplicativo do Azure Sphere também incluir um escudo Ethernet, EINT4-EINT7 não estará disponível para o RTApp, pois o escudo usa GPIO 5 (que mapeia para EINT5) em um aplicativo de alto nível, reservando assim todos os outros pinos dentro desse bloco.

Manipulador de interrupção

Seu manipulador de interrupção deve ter o mesmo nome que a interrupção solicitada na tabela de vetores para o M4. Consulte os exemplos de driver MT3620 M4 do Codethink Labs no GitHub para obter arquivos VectorTable.h e VectorTable.c de exemplo.

No arquivo VectorTable.c de exemplo, a seguinte entrada na tabela vetorial representa EINT8, que é o pino 0 no bloco 3:

[INT(28)] = gpio_g2_irq0,

O manipulador de interrupção correspondente no exemplo é gpio_g2_irq0:

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

Na tabela vetorial do seu próprio aplicativo, você pode nomear o manipulador de interrupção como quiser.

Inicializar, configurar e habilitar a interrupção

Na função main() do RTApp, inclua o código para inicializar a tabela de vetores, configure o registro de controle EINT para a interrupção e habilite o manipulador de interrupção.

Os exemplos de driver do Codethink definem uma VectorTableInit() função. É possível adaptar essa função de inicialização às suas necessidades.

Para configurar o registro de controle EINT, você precisará inicializá-lo conforme definido na folha de dados M4. Por exemplo, a função a seguir inicializa o bloco que contém um pin. A função define todas as interrupções externas com o valor de registro 0x300, o que permite debouncing e interrupções ativas-baixas.

#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;
}

Um aplicativo pode chamar essa função da seguinte maneira:

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

Por fim, o aplicativo deve habilitar a interrupção; este exemplo usa a NVIC_Enable função dos exemplos de driver do Codethink:

NVIC_EnableIRQ(28, 2);

API de interrupção externa e código de exemplo

Além do código de exemplo geral do Codethink Labs, você pode encontrar uma API de driver e a documentação correspondente da MediaTek.

  • Código-fonte de interrupção externa da MediaTek
  • Arquivo de cabeçalho de interrupção externa da MediaTek
  • Manual de referência da API EINT da MediaTek