diff --git a/Makefile b/Makefile index 667a8a8..3613287 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,7 @@ endif CFLAGS = -pipe -g -Os -mmcu=$(MCU) -Wall -fdata-sections -ffunction-sections CFLAGS += -Wa,-adhlns=$(*F).lst -DBOOTLOADER_START=$(BOOTLOADER_START) LDFLAGS = -Wl,-Map,$(@:.elf=.map),--cref,--relax,--gc-sections,--section-start=.text=$(BOOTLOADER_START) +LDFLAGS += -nostartfiles # --------------------------------------------------------------------------- diff --git a/README.md b/README.md index 16a870a..ba09435 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,10 @@ Currently the following AVR MCUs are supported: AVR MCU | Flash bytes used (.text + .data) | Bootloader region size --- | --- | --- -atmega8 | 872 (0x368) | 512 words -atmega88 | 918 (0x396) | 512 words -atmega168 | 970 (0x3CA) | 512 words -atmega328p | 970 (0x3CA) | 512 words +atmega8 | 724 (0x2D4) | 512 words +atmega88 | 744 (0x2E8) | 512 words +atmega168 | 744 (0x2E8) | 512 words +atmega328p | 744 (0x2E8) | 512 words (Compiled on Ubuntu 18.04 LTS (gcc 5.4.0 / avr-libc 2.0.0) with EEPROM and LED support) @@ -91,6 +91,5 @@ Issue reports, feature requests, patches or simply success stories are much appr ## Roadmap ## Some ideas that I want to investigate / implement in twiboot: -- [ ] do not use interrupts and remove vector table to save flash space -- [ ] find a way to not rely on TWI clock stretching during write access -- [ ] support AVR TINYs (USI peripheral, no bootloader fuse, no Read-While-Write flash) +- find a way to not rely on TWI clock stretching during write access +- support AVR TINYs (USI peripheral, no bootloader fuse, no Read-While-Write flash) diff --git a/main.c b/main.c index 8ee42ed..aff73ef 100644 --- a/main.c +++ b/main.c @@ -132,7 +132,7 @@ const static uint8_t chipinfo[8] = { /* wait 40 * 25ms = 1s */ static uint8_t boot_timeout = TIMEOUT; -volatile static uint8_t cmd = CMD_WAIT; +static uint8_t cmd = CMD_WAIT; /* flash buffer */ static uint8_t buf[SPM_PAGESIZE]; @@ -355,7 +355,7 @@ static uint8_t TWI_data_read(uint8_t bcnt) /* ************************************************************************* * TWI_vect * ************************************************************************* */ -ISR(TWI_vect) +static void TWI_vect(void) { static uint8_t bcnt; uint8_t control = TWCR; @@ -410,7 +410,7 @@ ISR(TWI_vect) /* ************************************************************************* * TIMER0_OVF_vect * ************************************************************************* */ -ISR(TIMER0_OVF_vect) +static void TIMER0_OVF_vect(void) { /* restart timer */ TCNT0 = TIMER_RELOAD; @@ -433,6 +433,26 @@ ISR(TIMER0_OVF_vect) static void (*jump_to_app)(void) __attribute__ ((noreturn)) = 0x0000; + +/* ************************************************************************* + * init1 + * ************************************************************************* */ +void init1(void) __attribute__((naked, section(".init1"))); +void init1(void) +{ + /* make sure r1 is 0x00 */ + asm volatile ("clr __zero_reg__"); + + /* on some MCUs the stack pointer defaults NOT to RAMEND */ +#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8515__) || \ + defined(__AVR_ATmega8535__) || defined (__AVR_ATmega16__) || \ + defined (__AVR_ATmega32__) || defined (__AVR_ATmega64__) || \ + defined (__AVR_ATmega128__) || defined (__AVR_ATmega162__) + SP = RAMEND; +#endif +} /* init1 */ + + /* * For newer devices the watchdog timer remains active even after a * system reset. So disable it as soon as possible. @@ -456,55 +476,56 @@ void disable_wdt_timer(void) /* ************************************************************************* * main * ************************************************************************* */ -int main(void) __attribute__ ((noreturn)); +int main(void) __attribute__ ((OS_main, section (".init9"))); int main(void) { LED_INIT(); LED_GN_ON(); - /* move interrupt-vectors to bootloader */ - /* timer0: running with F_CPU/1024, OVF interrupt */ + /* timer0: running with F_CPU/1024 */ #if defined (__AVR_ATmega8__) - GICR = (1<