Compartilhar via


Usar interrupções externas em aplicativos com capacidade em tempo real

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

Consulte o Manual de Usuário 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 o "MT3620 M4 Datasheet" da Avnet por email 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á-lo no campo "ExternalInterrupt" da seção Recursos do manifesto do aplicativo. Identifique a interrupção por uma cadeia de caracteres de EINT0 para 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 ao multiplexing. Seu RTApp pode usar qualquer EINT que preferir, 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 multiplexed.

Se o cenário de aplicativo do Azure Sphere também incluir um escudo Ethernet, o 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 todos os outros pinos nesse bloco.

Manipulador de interrupção

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

No arquivo VectorTable.c de exemplo, a seguinte entrada na tabela do vetor representa o 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 de vetor do seu próprio aplicativo, você pode nomear o manipulador de interrupção como desejar.

Inicializar, configurar e habilitar a interrupção

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

Os exemplos de driver codethink definem uma VectorTableInit() função. Você pode adaptar essa função de inicialização aos seus requisitos.

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 especificado pin. A função define todas as interrupções externas com o valor de registro 0x300, que permite interrupções debouncing e 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;
}

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 função dos NVIC_Enable exemplos de driver 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.