Electronic – It appears that I need two main() functions

avrbootloader

I am putting together a simple bootloader for the atmega8, mostly using code examples form libc's documentation. The bootloader is supposed to be located in the bootloader section of the flash. An application at the lower address needs to call the bootloader.

makefile:

LDFLAGS   += -Wl,--section-start=.text=$(BOOTLOAD)
LDFLAGS   += -Wl,--section-start=.test=0

test.c:

__attribute__ ((section (".test"))) int main(int argc, char **argv)
{
    usart_init();

    char msg[] = "Loading bootloader in 3 seconds.";
    send_block(sizeof(msg), msg);
    _delay_ms(3000);

    typedef void (* fn_ptr_t) (void);
    fn_ptr_t my_ptr = (void *)0x1800;
    my_ptr();
}

But I wouldn't be able to link bootloader.o and test.o into a single .hex file, because main() is duplicated.

Where should actually main() be located? And how would the other program (because, logically, those are two separate programs – application and bootloader) run?

Once more, the idea is that a small application 'test' is installed at flash address 0, together with the bootloader in the higher flash. On power-up, the application jumps to the bootloader, the user uploads his actual application, which in turn must take care to call the bootloader at appropriate times.

Actually, the very document that I link under my question is described how what I describe cannot be called a bootloader. Here is my use case. This is a small home-brew application – I doubt I will ever distribute the device to anyone. For my PCB, I can either add an ISP header (5 additional messy wires) or program the device via the same channel that I use for debugging – serial connection. I don't even have a jtag and am debugging entirely via printf() calls. This being said, if the need arises someday, it should be easy to call the well tested "bootloader" in some other way

Best Answer

Well, unless you are trying to do something really weird, generally the bootloader and application will be two entirely separate programs, each compiled to its own bin/hex file. The application would be compiled with .text=0, and the bootloader would be compiled with .text set to the beginning of the boot section. Note that this information must be passed to the linker, not the compiler. You can combine the hex files later for ease of flashing, but this is not required. If you need communication between the two, then you will have to implement a jump table or similar. You really don't have much space on an atmega8, though.