void (*app_start)(void) = 0x0000;
This isn't a NULL pointer. This really is the address of the start of application code, which the bootloader jumps to. The linker arranges for your application code to start at address 0. See table 26-6 in the ATMEGA168 datasheet.
The bootloader code starts higher up in flash. Exactly where depends on the bootloader fuses.
Following is stated in page 615 of the reference manual, under section 23.3.2:
The new configuration takes effect only after all registers except
WDOG_CNTH:L are written once after reset. Otherwise, the WDOG uses the
reset values by default. If window mode is not used (WDOG_CS2[WIN] is
0), writing to WDOG_WINH:L is not required to make the new
configuration take effect.
Adding these lines in initialize_CPU()
function under file init.c
, I can configure the watchdog timer, and disable it:
WDOG_CS1 = 0x60;
WDOG_CS2 = 1;
WDOG_TOVAL = 0x04;
Also, it is good to note that watchdog timer registers are write-once only. So, individual bit changes are not going to have an effect after first write to the same watchdog timer register.
If user wants to configure any of the watchdog timer registers later on, updates should be enabled in the first configuration. After that following is used to configure watchdog timer the second time. For more information, please have a look at the reference manual.
/* Initialize watchdog with ~1-kHz clock source, ~1s time-out */
DisableInterrupts; // disable global interrupt
WDOG_CNT = 0xC520; // write the 1st unlock word
WDOG_CNT = 0xD928; // write the 2nd unlock word
WDOG_TOVAL = 1000; // setting timeout value
WDOG_CS2 = WDOG_CS2_CLK_MASK; // setting 1-kHz clock source
WDOG_CS1 = WDOG_CS1_EN_MASK; // enable counter running
EnableInterrupts; // enable global interrupt
Best Answer
That really depends on how complex a bootloader you want to write, and what you have in place in the way of communications options.
For example, if the bootloader is using a UART to take in the application code, you could include a minimal console (menu-driven, for simplicity) in the bootloader that allows you to issue various commands, e.g. erase the existing application, start the existing application, or load a new application. Include a startup timeout - if you don't press a key within 3 seconds of boot, it automatically starts the existing application, if there is one, otherwise it stays in the menu waiting for an application to be loaded.
If the bootloader implements a simple, well-documented and widely supported serial file transfer protocol e.g. Y-Modem (yes, Z-modem is far, far better, but it's complicated), then you can upload application binaries from just about any terminal program.