avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] re-initialising an ATMega128 as much as possible (sta


From: Mudiaga Obada
Subject: Re: [avr-gcc-list] re-initialising an ATMega128 as much as possible (start a bootloader)
Date: Sun, 14 Aug 2005 14:14:44 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.11) Gecko/20050728

If I may ask, why go through such trouble? Instead of trying to
"un-initialise as much of the micro as possible", why not reset and
initial as little of the micro as needed?

On 29.07.2005 I posted a response to you on this list about how you
could pass information between the application and bootloader after
reseting with the WDT. I wonder if you read it...

I am attaching my bootloader entry/exit code with the hope that you
could use it to solve your bootloader issues. The trick is the magic
number thing - which you could extend for other things.

Here's how to use the code:

First you set your fuses so that the microcontroller starts with the
bootloader after each reset.

In your bootloader's main() you do

        if (bootloader_disabled()) {
                /* run application */                   
                __asm__ volatile("ijmp": : "z" (0));
                
        }

        /* switch to bootloader interrupt vector */
        MCUCR = _BV(IVCE);
        MCUCR = _BV(IVSEL);

        /* run bootloader */

To exit your bootloader (after timeout or programmer command), you do
        
        cli();

        /* switch to application interrupt vector */

        MCUCR = _BV(IVCE);
        MCUCR = 0;

        bootloader_disable();

        reset_now();

To go from application to bootloader

        bootloader_start();




Regards,

Mudiaga Obada


Torsten Mohr wrote:
> i program an ATMega128, there's a bootloader at 0x1e000
> and a normal application at 0x00000.
> 
> When the application starts the bootloader, it does that
> by directly jumping into it.
> 
> In the bootloader i'd like to un-initialise as much of
> the micro as possible, i think it is not possible to
> initialise everything the same way as after a real reset.
> 
#include <avr/io.h>
#include <avr/interrupt.h>

#include <stdint.h>

#include "clock.h"
#include "reset.h"
#include "bootloader.h"
#include "leds.h"

#define BOOTLOADER_MAGIC_NUMBER  0xB00D10AD

/* 
 * use start of ram as noteblock for bootloader state 
 */

#define BOOTLOADER_MAGIC_NUMBER_SCRATCHPAD_PTR  ((uint32_t *)0x0100)    

/*
 * used by init0_bootloader() 
 */

static uint32_t bootloader_magic_number __attribute__((section(".noinit")));



/*
 * enable bootloader for next reset by writing to scratchpad
 * happends if magic number not found at magic location
 */
void bootloader_enable()
{
        *(BOOTLOADER_MAGIC_NUMBER_SCRATCHPAD_PTR) = 0; 
}

/*
 * make sure bootloader is not invoked on next reset
 */
void bootloader_disable()
{
        *(BOOTLOADER_MAGIC_NUMBER_SCRATCHPAD_PTR) = BOOTLOADER_MAGIC_NUMBER; 
}

/*
 * was bootloader enaabled before reset?
 */
char bootloader_disabled()
{
        return (bootloader_magic_number == BOOTLOADER_MAGIC_NUMBER); 
}

/*
 * we want complete hardware when we enter bootloader and leave
 * bootloader so "ijmp" will not cut it.
 */
 
void bootloader_start() 
{
        leds_set(0); 
        cli(); 
        bootloader_enable();
        reset_now(); 
}

/*
 * this detects if magic number was set before the last reset
 * this must come after init.c (destructive ramtest)
 */
void init0_bootloader()  __attribute__ ((section (".init3")))  __attribute__ 
((naked));

void init0_bootloader()
{

        /* 
     * transfer bootloader magic number from scratchpad to .noinit
     * before crt0 initializes .data section
     */

        if (*(BOOTLOADER_MAGIC_NUMBER_SCRATCHPAD_PTR) == 
BOOTLOADER_MAGIC_NUMBER) {
                bootloader_magic_number = BOOTLOADER_MAGIC_NUMBER;
        } else {
                bootloader_magic_number = 0;
        }

}



/*
 * AVR hardare reset using Watchdog Timer
 * (c) 2005, VSI, CS, Universitaet Frankfurt
 * Authors: Mudiaga Obada
 */

#include <avr/io.h>
#include <avr/interrupt.h>

/*
 * provokes a hardware reset by enabling the watchdog timer
 */

void reset_now() __attribute__((noreturn));

void reset_now()
{
        /* say bye-bye to texas... */

        cli();

        WDTCR = _BV(WDCE) | _BV(WDE);

        WDTCR = _BV(WDE);

        for (;;);

}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]