Problema de interrupción del cargador de arranque AVR

Durante bastante tiempo, he estado usando un controlador avr ATmega324PA y Atmel Studio para escribir los programas. escribimos un cargador de arranque TCP. Funciona bien sin ninguna interrupción. Más tarde agregamos una interrupción externa a ese programa y ahora el controlador siempre se reinicia cuando salta al ISR. Aquí está el código

void main()
{
  init_interrupt();
  init_uart();
  while(1);
}

void init_interrupt()
{
  /* PortA3 as input for external interrupt*/
 DDRB|=(0<<2);
  /*Pulll up disable*/
 PORTB &=~ (1<<PORTB2);
  /*Interrupt_vector change enable*/
 MCUCR|=(1<<IVCE);
  /*Interrupt vector change to boot section*/
 MCUCR|=(1<<IVSEL);
  /*Interrupt_vector change enable*/
 MCUCR&=~(1<<IVSEL);
 _delay_ms(5000);
  /* Enable external interrupt-2*/
 EIMSK |= (1<<INT2);
  /* Enable rising edge of the input signal as interrupt*/
 EICRA |= (1<<ISC21)|(1<<ISC20);
  /* Enable global interrupt*/
 sei();
}

ISR(INT2_vect)
{
    uart_send("Print on interrupt");
}

Aquí estoy tratando de cambiar el vector de interrupción a la sección de arranque.

NOTA: El fusible BOOTRST ya está configurado

EDITADO: después de cambiar el valor de MCUCR como se muestra a continuación, lo envié a través de UART en lugar de '01', la salida se muestra como "A0 2E 57 C9 D1 95 91 FF"

    MCUCR|=(1<<IVCE);

Debe ser un problema con el registro MCUCR

¿Está seguro de que no está saltando a un vector de interrupción que no está definido en su código, lo que hace que el procesador se reinicie?
Como ve, definí la rutina INT2_vect y habilité la configuración de interrupción externa en init_interrupt (). Esta misma interrupción sin la configuración de IVSEL, funciona bien con el código de la aplicación. Pero con el código de arranque, se reinicia
¿Tu cargador de arranque usa interrupciones? Personalmente, los he evitado en los cargadores de arranque, pero creo que hay un par de bits de registro que necesita para reubicar las interrupciones en la sección del cargador de arranque. Tal vez el gestor de arranque los haya dejado en un estado incorrecto.

Respuestas (1)

Atlast, esta es la forma de hacer que funcionen las interrupciones en el cargador de arranque, U debe configurar el bit Habilitar cambio de vector de interrupción (IVCE) como se muestra a continuación

   MCUCR|=(1<<IVCE); // or GICR|=(1<<IVCE) in some controllers

Y dentro de cuatro ciclos, debe configurar el IVSEL y desactivar el bit IVCE.

   MCUCR=0x02; // or GICR=0x02;  IVSEL=1, IVCE=0 at same time

Lo que salió mal en el código anterior está debajo

     /*Interrupt_vector change enable*/
    MCUCR|=(1<<IVCE);
    /*Interrupt vector change to boot section*/
    MCUCR|=(1<<IVSEL);
    /*Interrupt_vector change enable*/
    MCUCR&=~(1<<IVSEL);

Creo que el método anterior podría terminar dentro de cuatro ciclos. Sin embargo, ahora puedo usar el cargador de arranque TCP con interrupciones para cargar el código de la aplicación.