Este artigo tem o objetivo de demonstrar técnicas para realizar o reset de microcontroladores HCS08 sob o controle do firmware.

Background

Efetuar a reinicialização do código em execução num microcontrolador é uma tarefa bastante simples: tudo o que é necessário é provocar um desvio para o vetor de reset ou para o endereço indicado pelo mesmo.
No entanto, apesar de aparentemente provocar uma reinicialização completa do microcontrolador, esta abordagem não provoca os mesmos efeitos que um reset real. Isto porque um reset tem normalmente outras implicações tais como: reinicialização da máquina de estados interna da CPU, reinicialização dos registradores da CPU e dos periféricos.

Implementação 1

Esta implementação é baseada na utilização de um pino de I/O comum conectado ao pino de reset do microcontrolador. O pino é normalmente configurado como entrada após um reset. Sob o comando do firmware podemos reconfigurar o pino como uma saída e escrever um valor "0" no mesmo, o que provoca o reset do MCU.

O exemplo a seguir demonstra como implementar este sistema de reset em linguagem C:
1 - Na inicialização do chip, configure o pino PTA3 como entrada e habilite o pino de reset:

 PTADD = 0;    // todos os pinos como entradas
 SOPT1 = 1;    // pino PTA5 na função reset

2 - O código de reset poderia ser encapsulado em uma função:

 void reset(void)
 {
   PTAD = 0;    // armazena 0 no registrador de saída da porta A
   PTADD |= 8;    // configura pino PTA3 como saída (resseta o chip)
 }

3 - Para provocar o reset, basta chamar a função:

 reset();

Ps.: após o reset, o bit PIN no registrador SRS será setado indicando que a origem do reset foi o pino!

Implementação 2

Esta outra implementação de um reset controlado por software é baseada na funcionalidade de reset causado por execução de um opcode ilegal. Este reset acontece sempre que a CPU tenta executar um opcode que não esteja mapeado no conjunto de opcodes válidos.
Para selecionar o opcode adequado, consultamos a tabela de opcodes dos HCS08. A figura abaixo retrata a primeira página de opcodes válidos para as CPUs HCS08 sem gerenciador de memória (MMU).

Apesar de existirem opcodes não implementados nesta página, optamos por utilizar um opcode de dois bytes (portanto localizado na página 2). Este opcode é 0x9E00.
A implementação da função de reset por software é a seguinte:

void reset(void)
{
  unsigned int temp;
  temp = 0x9E00;
  #asm
   LDHX  @temp      // carrega o endereço de temp em H:X
   JMP   ,X   // desvia para o endereço de temp
  #endasm
}

Para realizar um reset, basta uma chamada a função reset():

 reset();

Outra forma mais simples de implementar o reset por software consiste em incluir a seguinte linha de código no ponto onde se deseja realizar o reset:
asm{DCW 0x9E00};
Ps.: após um reset deste tipo, o bit ILOP localizado no registrador SRS, estará setado, indicando que a origem do último reset foi a execução de um opcode ilegal!