Os Dois Watchdogs do microcontrolador STM32F

No post anterior foi visto como configurar o clock do microcontrolador STM32F para rodar a 72 MHz, baseado no cristal externo.

Neste post serão explicados pra que são e como configurar os dois Watchdogs do STM32F (IWDG e WWDG).

O que é um Watchdog

O Watchdog (cão de guarda) é um periférico interno do microcontrolador que serve para identificar mal funcionamento do programa e reiniciar o sistema a partir de um reset.

É preciso recarregar/alimentar (reload/feed) periodicamente o Watchdog para que ele não cause um reset.

Então, quando um programa entra em um laço infinito ou entra em algum estado inconsistente que evita que o Watchdog seja adequadamente recarregado, o sistema vai resetar em um tempo máximo estipulado pela configuração do Watchdog.

IWDG – Independent Watchdog

O IWDG (Watchdog Independente) é chamado assim porque ele utiliza uma fonte de clock independente do clock do sistema.

Para habilitar o IWDG:

  • Abra o arquivo IOC do projeto, entrar em “Pinout & Configuration > IWDG” e então habilitá-lo em “Activated”.
  • O valor do prescaler (divisor de clock) e o valor de reload (recarregamento) podem ser configurados para se obter um tempo máximo de reset com precisão.
  • Note que o clock usado pelo IWDG vem de um oscilador RC interno de 40 kHz, o que pode ser visto em “Clock Configuration”.

O IWDG pode ser recarregado a qualquer momento, independente do valor do seu contador. Ele vai causar um reset quando seu contador chegar até zero.

Com um clock de 40 kHz, prescaler igual a 16 e valor de recarregamento 4095, o IWDG causará um reset em de 1,6 segundos.

T = 16*(4095+1)/40000

Para evitar isso, chamamos a função que reseta o IWDG no fim do laço while(1){…}, o qual demora 1.0 segundo para ser executado:

int main(void) {
  // ...
  while (1)
  {
    // ...

    // Recarrega o IWDG
    HAL_IWDG_Refresh(&hiwdg);

    // ...
  }
   // ...
}

Note que, para poder debugar o microcontrolador com o IWDG ativo, é necessário configurá-lo para que pare a contagem quando o processador pára em um breakpoint.

Na função MX_IWDG_Init() adicione as linhas a seguir:

static void MX_IWDG_Init(void)
{
  // ...

  // Necessário para parar o IWDG quando
  // o programa para em um breakpoint
  __HAL_DBGMCU_FREEZE_IWDG();

  // ...
}

WWDG – Window Watchdog

O WWDG (Watchdog de Janela) é chamado assim porque com ele é possível configurar uma janela de tempo onde ele deve ser recarregado, de forma a não gerar um reset do microcontrolador. Se recarregar antes do tempo ou depois do tempo o reset ocorre.

Em outras palavras, o WWDG pode ser configurado para exigir um tempo mínimo e máximo entre os recarregamentos, causando um reset caso seja recarregado antes do tempo mínimo ou caso não seja recarregado no tempo máximo.

Este Watchdog funciona de forma um pouco diferente:

  • Você configura um valor de recarregamento, por exemplo 127 (0x7F) a partir do qual o contador é decrementado. Se o valor do contador é reduzido a 63 (0x3F) ocorre o reset.
  • Você também configura um valor de janela, o valor a partir do qual é permitido recarregar o WWDG. Se, quando recarregado, o contador é maior que este valor, o WWDG causa um reset. Se é menor ou igual, o WWDG é recarregado com sucesso, sem gerar um reset.
    • Se você configurar este valor como sendo igual ao valor de recarregamento, o WWDG funciona como um Watchgod normal, sem o tempo mínimo.
  • Você pode habilitar a interrução do WWDG, que ocorre quando o o valor do contador é reduzido a 64 (0x40).

Para habilitar o WWDG:

  • Abra o arquivo IOC do projeto, entrar em “Pinout & Configuration > WWDG” e então habilitá-lo em “Activated”.
  • Configure em “prescaler” o valor do divisor de clock.
  • Configure em “window value” o valor da janela (início da janela).
  • Configure em “down-counter” o valor do recarregamento (início da contagem).
  • Habilite a interrupção do WWDG e, na aba “NVIC Settings” habilite a interrupção.

Com um clock de 72 MHz, portanto 36 MHz em APB1, prescaler igual a 8 e valor de recarregamento igual a 127, o WWDG causará um reset em de 58,2 milissegundos após o o recarregamento anterior.

T1 = 8*4096*(127-63)/36000000

Com o valor da janela igual a 64, a janela de recarregamento inicia em 57,3 milissegundos após o recarregamento anterior.

T2 = 8*4096*(127-64)/36000000

Dessa forma há uma janela de tempo de 0,091 milissegundos para que o recarregamento ocorra: depois de T2 e antes de T1.

ΔT = T1-T2 = 8*4096*(64-63)/36000000

+--------------------------+
| Recarrega          Reset |
| |-------------|----|     |
| T0            T2   T1    |
|                <-->      |
|                Janela    |
+--------------------------+

Para evitar isso, no arquivo main.c (ou em qualquer arquivo) criamos a função HAL_WWDG_EarlyWakeupCallback(), a qual chama a função de reset do WWDG.

Essa função criada é automaticamente chamada pelo tratamento da interrupção do WWDG.

void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg) {
  // Recarrega o WWDG
  HAL_WWDG_Refresh(hwwdg);
}

De forma semelhante ao IWDG, para que seja possível debugar o microcontrolador com o WWDG ativo, é necessário configurá-lo para que pare a contagem quando a execução é pausada em um breakpoint.

Na função MX_WWDG_Init() adicione as linhas a seguir:

static void MX_WWDG_Init(void)
{
  // ...

  // Necessário para parar o WWDG quando
  // o programa para em um breakpoint
  __HAL_DBGMCU_FREEZE_WWDG();

  // ...
}

Por que dois Watchdogs?

Você pode se perguntar porque seriam necessários dois Watchdogs?

Caso o clock principal do sistema falhe, o que pode acontecer por exemplo escrevendo indevidamente em certos registradores, o WWDG vai parar de contar e, portanto, não causará reset. Nesse caso o IWDG entrará em ação, reiniciando o microcontrolador.

Além disso, como foi feito neste exemplo, ambos podem cuidar de dois escopos diferentes:

  • IWDG pode ser recarregado a cada 1 segundo, garantindo que o laço de execução principal está sendo executado; e
  • WWDG pode ser recarregado pela sua interrupção, garantindo que as interrupções não ficam desabilitadas por períodos muito longos.

Conclusão

Assim, com o uso de ambos os Watchdogs do STM32F, podemos obter uma garantia de que o programa está operando de forma correta: executando todas as suas tarefas e mantendo interrupções habilitadas.

Autor: Djones Boni

Engenheiro Eletricista.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *