From 5cc82b476baf7467ed0a76da15d40f1534a58c5a Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Wed, 31 May 2006 14:30:05 +0200 Subject: [PATCH] Version 0.80beta3 (20060528) --- avrprog_boot.pnproj | 2 +- avrprog_boot.pnps | 1 + ldscripts_no_vector/avr4.x | 2 +- ldscripts_no_vector/avr5.x | 9 ++- main.c | 80 ++++++++++++++++++------ makefile | 53 ++++++++++++---- mega128.h | 9 ++- mega128can.h | 12 ++-- mega16.h | 9 ++- mega32.h | 9 ++- mega8.h | 10 +-- readme.txt | 123 ++++++++++++++++++++++++------------- 12 files changed, 221 insertions(+), 98 deletions(-) create mode 100644 avrprog_boot.pnps diff --git a/avrprog_boot.pnproj b/avrprog_boot.pnproj index 2acd2f5..03620e0 100644 --- a/avrprog_boot.pnproj +++ b/avrprog_boot.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/avrprog_boot.pnps b/avrprog_boot.pnps new file mode 100644 index 0000000..10c6d31 --- /dev/null +++ b/avrprog_boot.pnps @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ldscripts_no_vector/avr4.x b/ldscripts_no_vector/avr4.x index a80604c..6b371f4 100644 --- a/ldscripts_no_vector/avr4.x +++ b/ldscripts_no_vector/avr4.x @@ -1,4 +1,4 @@ -/* Default linker script, for normal executables */ +/* MODIFIED LINKER SCRIPT - BOOTLOADER: without .vectors */ OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr") OUTPUT_ARCH(avr:4) MEMORY diff --git a/ldscripts_no_vector/avr5.x b/ldscripts_no_vector/avr5.x index b0c9db0..a1a1fa2 100644 --- a/ldscripts_no_vector/avr5.x +++ b/ldscripts_no_vector/avr5.x @@ -1,4 +1,4 @@ -/* Default linker script, for normal executables */ +/* MODIFIED LINKER SCRIPT - BOOTLOADER: without .vectors */ OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr") OUTPUT_ARCH(avr:5) MEMORY @@ -66,11 +66,14 @@ SECTIONS .rela.bss : { *(.rela.bss) } .rel.plt : { *(.rel.plt) } .rela.plt : { *(.rela.plt) } + /* Internal text space or external memory */ -/DISCARD/ : { *(.vectors); } + +/* BOOTLOADER-MODIFICATION - not interrupt-vectors */ + /DISCARD/ : { *(.vectors) } .text : { -/* *(.vectors) */ +/* *(.vectors) */ /* BOOTLOADER-MODIFICATION ! */ __ctors_start = . ; *(.ctors) __ctors_end = . ; diff --git a/main.c b/main.c index 3b56f2b..e310102 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ /***************************************************************************** * * AVRPROG compatible boot-loader -* Version : 0.80beta2 (May 2006) +* Version : 0.80beta3 (May 2006) * Compiler : avr-gcc 3.4.6 / avr-libc 1.4.4 * size : depends on features and startup ( minmal features < 512 words) * by : Martin Thomas, Kaiserslautern, Germany @@ -23,7 +23,7 @@ * **************************************************************************** * -* See the makefile for information how to adopt the linker-settings to +* See the makefile for information how to adapt the linker-settings to * the selected Boot Size (BOOTSIZE=xxxx), the AVR clock-frequency and the * MCU-type in * @@ -36,21 +36,28 @@ * 0x34C - atmega128 * 0x352 - at90can128 * bytes size and should fit into a 512 word (0x400 byte) bootloader-section. +* The above values depend on the compiler-version and may differ from +* your results. * ****************************************************************************/ /* - Does not work reliably so far: - - lock bits set + TODOs: + - check lock-bits set + - __bad_interrupt still linked even with modified + linker-scripts which needs a default-handler, + "wasted": 3 words for AVR5 (>8kB), 2 words for AVR4 */ - -// programmers-notepad tabsize 4 -#define VERSION_HIGH '0' -#define VERSION_LOW '8' +// tabsize: 4 /* MCU frequency */ -#define F_CPU 7372800 +#ifndef F_CPU +// #define F_CPU 7372800 +#define F_CPU (7372800/2) +#endif /* UART Baudrate */ +// #define BAUDRATE 9600 +// #define BAUDRATE 19200 #define BAUDRATE 115200 /* use "Double Speed Operation" */ @@ -59,6 +66,13 @@ /* use second UART on mega128 / can128 */ //#define UART_USE_SECOND +/* Device-Type: + For AVRProg the BOOT-option is prefered + which is the "correct" value for a bootloader. + avrdude may only detect the part-code for ISP */ +#define DEVTYPE DEVTYPE_BOOT +//#define DEVTYPE DEVTYPE_ISP + /* * Pin "STARTPIN" on port "STARTPORT" in this port has to grounded * (active low) to start the bootloader @@ -72,8 +86,9 @@ * Select startup-mode * SIMPLE-Mode - Jump to bootloader main BL-loop if key is * pressed (Pin grounded) "during" reset or jump to the - * application if the pin is not grounded (=pulled up by - * internal pull-up-resistor) + * application if the pin is not grounded. The internal + * pull-up resistor is enabled during the startup and + * gets disabled before the application is started. * POWERSAVE-Mode - Startup is separated in two loops * which makes power-saving a little easier if no firmware * is on the chip. Needs more memory @@ -82,20 +97,24 @@ * parser-loop on reset * F_CPU in BOOTICEMODE must be 7372800 Hz to be compatible * with the org. JTAGICE-Firmware - * WAIT-mode waits 1 sec for the S command if nothing is recived - * then the user prog is started .. + * WAIT-mode waits 1 sec for the defined character if nothing + * is recived then the user prog is started. */ #define START_SIMPLE //#define START_WAIT //#define START_POWERSAVE //#define START_BOOTICE +/* character to start the bootloader in mode START_WAIT */ +#define START_WAIT_UARTCHAR 'S' + /* wait 1s in START_WAIT mode (10ms steps) */ #define WAIT_VALUE 100 /* * enable/disable readout of fuse and lock-bits - * (will not work for Mega169 since not supported by AVRPROG 1.37 + * (AVRPROG has to detect the AVR correctly by device-code + * to show the correct information). */ //#define ENABLEREADFUSELOCK @@ -108,17 +127,34 @@ */ //#define WRITELOCKBITS +#define VERSION_HIGH '0' +#define VERSION_LOW '8' + +#define GET_LOCK_BITS 0x0001 +#define GET_LOW_FUSE_BITS 0x0000 +#define GET_HIGH_FUSE_BITS 0x0003 +#define GET_EXTENDED_FUSE_BITS 0x0002 + + #include #include #include #include #include -#include +// #include +#include #include "chipdef.h" uint8_t gBuffer[SPM_PAGESIZE]; +#if defined(BOOTLOADERHASNOVECTORS) +#warning "This Bootloader does not link interrupt vectors - see makefile" +/* make the linker happy - it wants to see __vector_default */ +// void __vector_default(void) { ; } +void __vector_default(void) { ; } +#endif + static void sendchar(uint8_t data) { while (!(UART_STATUS & (1<= WAIT_VALUE) { @@ -484,11 +522,13 @@ int main(void) sendchar(VERSION_HIGH); sendchar(VERSION_LOW); - // Return Signature Byte + // Return Signature Bytes (it seems that + // AVRProg expects the "Atmel-byte" 0x1E last + // but shows it first in the dialog-window) } else if (val == 's') { - sendchar(SIG_BYTE1); - sendchar(SIG_BYTE2); sendchar(SIG_BYTE3); + sendchar(SIG_BYTE2); + sendchar(SIG_BYTE1); /* ESC */ } else if(val != 0x1b) { diff --git a/makefile b/makefile index a775d4a..1643ddc 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,8 @@ # Hey Emacs, this is a -*- makefile -*- # +# Makefile for the AVRProg-compatible Bootloader +# +# based on the # WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. # Released to the Public Domain # Please read the make user manual! @@ -34,18 +37,24 @@ # user defined values # MCU name +## MCU = atmega8 ## MCU = atmega16 -MCU = atmega8 -## MCU = atmega32 +MCU = atmega32 +## MCU = atmega128 ## MCU = at90can128 #/* Select Boot Size in Words (select one, comment out the others) */ ## NO! BOOTSIZE=128 ## NO! BOOTSIZE=256 -## MAYBE: BOOTSIZE=512 BOOTSIZE=512 -#BOOTSIZE=1024 -##BOOTSIZE=2048 +## BOOTSIZE=1024 +## BOOTSIZE=2048 + +# /* Select if bootloader should include the inverrupt-vectors +# when selecting 'no' here, the bootloader must not use +# any interrupts and the modified linker-scripts are used. */ +##BOOTINTVEC=yes +BOOTINTVEC=no ################## BOOTLOADER ###################### @@ -55,7 +64,9 @@ BOOTSIZE=512 # "word", gcc toolchain needs "byte"-address # (see LDFLAGS further down) +## ifeq ($(MCU), atmega8) +BFD_MACH=avr4 ifeq ($(BOOTSIZE), 128) MT_BOOTLOADER_ADDRESS = 0x1F00 endif @@ -68,9 +79,11 @@ endif ifeq ($(BOOTSIZE), 1024) MT_BOOTLOADER_ADDRESS = 0x1800 endif - endif + +## ifeq ($(MCU), atmega16) +BFD_MACH=avr5 ifeq ($(BOOTSIZE), 128) MT_BOOTLOADER_ADDRESS = 0x3F00 endif @@ -83,9 +96,11 @@ endif ifeq ($(BOOTSIZE), 1024) MT_BOOTLOADER_ADDRESS = 0x3800 endif - endif + +## ifeq ($(MCU), atmega169) +BFD_MACH=avr5 ifeq ($(BOOTSIZE), 128) MT_BOOTLOADER_ADDRESS = 0x3F00 endif @@ -98,9 +113,11 @@ endif ifeq ($(BOOTSIZE), 1024) MT_BOOTLOADER_ADDRESS = 0x3800 endif - endif + +## ifeq ($(MCU), atmega32) +BFD_MACH=avr5 ifeq ($(BOOTSIZE), 256) MT_BOOTLOADER_ADDRESS = 0x7E00 endif @@ -113,9 +130,11 @@ endif ifeq ($(BOOTSIZE), 2048) MT_BOOTLOADER_ADDRESS = 0x7000 endif - endif + +## ifeq ($(MCU), atmega128) +BFD_MACH=avr5 ifeq ($(BOOTSIZE), 512) MT_BOOTLOADER_ADDRESS = 0x1FC00 endif @@ -128,9 +147,11 @@ endif ifeq ($(BOOTSIZE), 4096) MT_BOOTLOADER_ADDRESS = 0x1E000 endif - endif + +## ifeq ($(MCU), at90can128) +BFD_MACH=avr5 ifeq ($(BOOTSIZE), 512) MT_BOOTLOADER_ADDRESS = 0x1FC00 endif @@ -269,9 +290,15 @@ LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) ################## BOOTLOADER ###################### # MT_BOOTLOADER_ADDRESS (=Start of Boot Loader section -# in bytes - not words) is defined above. +# in bytes - not words) as defined above. LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS) +# check if linker-scripts without interrupt-vectors should +# be used and set linker-option, announce to C-code by define +ifeq ($(BOOTINTVEC), no) +LDFLAGS += -T./ldscripts_no_vector/$(BFD_MACH).x +CFLAGS += -DBOOTLOADERHASNOVECTORS +endif # Programming support using avrdude. Settings and variables. @@ -285,8 +312,8 @@ LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS) AVRDUDE_PROGRAMMER = stk500v2 # com1 = serial port. Use lpt1 to connect to parallel port. -#AVRDUDE_PORT = com1 # programmer connected to serial device -AVRDUDE_PORT = /dev/ttyS0 # programmer connected to serial device +AVRDUDE_PORT = com1 # programmer connected to serial device +#AVRDUDE_PORT = /dev/ttyS0 # programmer connected to serial device AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep diff --git a/mega128.h b/mega128.h index 9379969..800501d 100644 --- a/mega128.h +++ b/mega128.h @@ -1,11 +1,14 @@ #ifndef _MEGA128_H_ #define _MEGA128_H_ -#define DEVTYPE 0x44 +/* Part-Code ISP */ +#define DEVTYPE_ISP 0x43 +/* Part-Code Boot */ +#define DEVTYPE_BOOT 0x44 -#define SIG_BYTE3 0x1E +#define SIG_BYTE1 0x1E #define SIG_BYTE2 0x97 -#define SIG_BYTE1 0x02 +#define SIG_BYTE3 0x02 #ifdef UART_DOUBLESPEED diff --git a/mega128can.h b/mega128can.h index 124099a..a57b73d 100644 --- a/mega128can.h +++ b/mega128can.h @@ -1,12 +1,16 @@ #ifndef _MEGA128CAN_H_ #define _MEGA128CAN_H_ -/* Dummy device code for now, must be same as used in avrdude.conf */ -#define DEVTYPE 0x43 +/* Dummy: use ATmega128 device-code for now, + must be same as used in avrdude.conf */ +/* Part-Code ISP */ +#define DEVTYPE_ISP 0x43 +/* Part-Code Boot */ +#define DEVTYPE_BOOT 0x44 -#define SIG_BYTE3 0x1E +#define SIG_BYTE1 0x1E #define SIG_BYTE2 0x97 -#define SIG_BYTE1 0x81 +#define SIG_BYTE3 0x81 #ifdef UART_DOUBLESPEED diff --git a/mega16.h b/mega16.h index 384ccd5..533d7a9 100644 --- a/mega16.h +++ b/mega16.h @@ -1,11 +1,14 @@ #ifndef _MEGA16_H_ #define _MEGA16_H_ -#define DEVTYPE 0x75 +/* Part-Code ISP */ +#define DEVTYPE_ISP 0x74 +/* Part-Code Boot */ +#define DEVTYPE_BOOT 0x75 -#define SIG_BYTE3 0x1E +#define SIG_BYTE1 0x1E #define SIG_BYTE2 0x94 -#define SIG_BYTE1 0x03 +#define SIG_BYTE3 0x03 #ifdef UART_DOUBLESPEED diff --git a/mega32.h b/mega32.h index 73474d1..5827e92 100644 --- a/mega32.h +++ b/mega32.h @@ -1,11 +1,14 @@ #ifndef _MEGA32_H_ #define _MEGA32_H_ -#define DEVTYPE 0x73 +/* Part-Code ISP */ +#define DEVTYPE_ISP 0x72 +/* Part-Code Boot */ +#define DEVTYPE_BOOT 0x73 -#define SIG_BYTE3 0x1E +#define SIG_BYTE1 0x1E #define SIG_BYTE2 0x95 -#define SIG_BYTE1 0x02 +#define SIG_BYTE3 0x02 #ifdef UART_DOUBLESPEED diff --git a/mega8.h b/mega8.h index 8654ddb..33420c8 100644 --- a/mega8.h +++ b/mega8.h @@ -1,12 +1,14 @@ #ifndef _MEGA8_H_ #define _MEGA8_H_ -#define DEVTYPE 0x76 -//#define DEVTYPE 0x77 +/* Part-Code ISP */ +#define DEVTYPE_ISP 0x76 +/* Part-Code BOOT */ +#define DEVTYPE_BOOT 0x77 -#define SIG_BYTE3 0x1E +#define SIG_BYTE1 0x1E #define SIG_BYTE2 0x93 -#define SIG_BYTE1 0x07 +#define SIG_BYTE3 0x07 #ifdef UART_DOUBLESPEED diff --git a/readme.txt b/readme.txt index a825fc5..8237922 100644 --- a/readme.txt +++ b/readme.txt @@ -2,17 +2,18 @@ ====================================================== ATMEL AVR UART Bootloader for AVR-GCC/avr-libc - based on the AVR Butterfly bootloader code by Martin Thomas, Kaiserslautern, Germany mthomas@rhrk.uni-kl.de eversmith@heizung-thomas.de - http://www.siwawi.arubi.uni-kl.de/avr_projects - Addtional code and improvements provided by - Uwe Bonnes, Bjoern Riemer and Olaf Rempel. - + ** Addtional code and improvements contributed ** + ** by Uwe Bonnes, Bjoern Riemer and Olaf Rempel. ** + + Eearly versions of this bootloader-code have been + based on the AVR Butterfly bootloader-source REV02 + which has been available from atmel.com. ====================================================== @@ -26,15 +27,54 @@ Programming-Software (on the "PC-Side"): * avrdude available at http://savannah.nongnu.org/projects/avrdude/ "Multiplattform" +* Installation instructions at the end of this file. + + + +28. May 2006 - Version 0.8beta3 + +* Support discarding of interrupt-vectors which saves some space + if no interrupts are needed in the bootloader. Added option + in makefile to enable this feature, modified LDFLAGS, + additional code in main.c for a pseudo default_interrupt ISR. + The modified linker-scripts have been contributed by + Olaf Rempel (basicly just the .vector-section is not linked). +* Reverted the order of signatur-byte-numbers in part- + configurations to the usual order in the datasheet, + also reverted in main.c for sending the signature. +* Definitions for lock/fuse-readout. +* Updated installation-instruction at the end of this file. +* Added DEVTYPE_ISP/DEVTYPE_BOOT to part-configurations, + added configuration-option for this in main.c. +* A remark about the DEVTYPE: Usualy there are two + Part-Codes/Device-Codes. One is for ISP: AVRProg shows + the type of the AVR. The other code is for bootloading: + AVRprog shows the type plus "BOOT". When a boot-device-code + gets detected by AVRprog it "knows" how do handle the + limited functionality of bootloaders. (When receiving the + ISP-code AVRProg expects an AVR910-type programmer.) + The offset between the codes is usualy 0x01 where the + ISP-code is the smaller value, i.e. ATmega32 ISP-code + is 0x72->"ATmega32" and boot-code is 0x73->"ATmega32 BOOT". + When using avrdude the bootloader's device-code must match + the device-code in the avrdude.conf. Check the avrdude- + code to see if both codes (AVR910 and AVR109) are supported. + -- I have got some e-mails from users which have been + confused by this. Hopefully this explanation is good enough. +* This bootloader lets the watchdog do a reset when the + user selects "Exit programmer" (i.e. in AVRProg) after an + update. Make sure to disable or reset the watchdog early in + you application. 27. May 2006 - Version 0.8beta2 -More improvements contributed by Olaf Rempel. +* More very well done improvements contributed by Olaf Rempel. +* Olaf Rempel also modified the STARTUP_WAIT method. 21. May 2006 - Version 0.8beta -Version contributed by Olaf Rempel. He has done a lot of modifications. --> "cleaner code", smaller binaries. +* Version contributed by Olaf Rempel. He has done a lot of modifications. + -> "cleaner code", smaller binaries. 09. Feb. 2006 - Version 0.75 @@ -50,13 +90,14 @@ Version contributed by Olaf Rempel. He has done a lot of modifications. * (Version 0.6 has never been available on the web-page) * ATmega128 support * code cleanup -* Tested with ATmega8, ATmega32 and ATmega128 +* This version has been tested with ATmega8, ATmega32 and + ATmega128 7. Apr. 2004 - Version 0.5 * added different startup-methods * compatible with ATmega8 now -* included makefile adopted to ATmega8 now +* included makefile adapted to ATmega8 now (ATmega16 options still available) * fixed jump to application which did not work reliably before @@ -127,61 +168,57 @@ not enabled (TODO). --------------- Installation ----------------- -- Change the MCU type in the makefile (so far - ATmega16 has been tested, ATmega169, ATmega8 - and ATmega32 should be o.k. too. +- Change the MCU type in the makefile. -- Change the boot(loader)-size in Makefile, this - bootloader is larger than 512 words (1024 bytes), - so select at least _B1024! +- Change the boot(loader)-size in Makefile. The needed + space depends on the features selected in main.c -- Change the XTAL in Makefile to the clock-frequency - of your board (keep BAUDRATE at 19200). See - the datasheet for frequencies with minimum - error at 19200bps and select Crystal/Oscillator - to get minimum errors. +- Set baudrate in main.c, a doublespeed configuration-option + is available too. -- Change the start-condition in Makefile. Default - is: enter bootloader if Pin A7 is connected to - GND during reset/startup +- Change the F_CPU in main.c to the clock-frequency + of your board. See the datasheet for frequencies + with minimum error at the selected baudrate. + +- Select the start-condition in main.c. - Please use at least avr-gcc 3.3.1/avr-libc 1.0 or WINAVR Sept. 2003 or later to compile and link - the bootloader. + this bootloader. -- upload the hex-File to the AVR (STK500, STK200, SP12 - etc.) +- Upload the hex-File to the AVR (STK500, STK200, SP12 + evertool, AVR910 etc.) -- program the "Boot Flash section size" (BOOTSZ fuses) - according to the boot-size selected in main.c +- Program the "Boot Flash section size" (BOOTSZ fuses) + according to the boot-size selected in the makefile i.e. BOOTSZ=00 for boot-size 1024 words on ATmega16 -- enable the BOOT Reset Vector (BOOTTRST=0) +- enable the BOOT Reset Vector fuse (BOOTTRST=0) - Set the lock bits to protect the bootloader from SPM-writes (Boot Loader Protection Mode 2 in STK500- - plugin) + plugin) so that it can not overwrite itself. - Connect the AVR UART Pins via level-shifter/inverter - (i.e. MAX232) to you PCs Com-Port. + (i.e. MAX232) to your PCs COM-Port. - Reset the AVR while fullfilling the bootloader start- - condition. Which means connect PA7 to GND in the default - config during reste/power-cycle. Keep the connection - or hold the key down until you see the AVRPROG dialog! + condition. (Default: selected pin connected to GND). + The condition must be "true" until you see the + AVRPROG dialog or avrdude connects. -- Start AVRPROG (AVRStuido/Tools or stand-alone) - - keep PA7 grounded! (avrdude is supported too, check - the avrdude manual for command-line options). +- Start AVRPROG (AVRStuido/Tools or stand-alone) + avrdude is supported too, check the avrdude manual + for command-line options. -- AVRPROG will detect the bootloader, you may release - PA7 now +- AVRPROG or avrdude should detect the bootloader. -- see AVRStuido online-help for more information how +- see AVRStudio online-help for more information how to use AVRPROG - make sure to EXIT from AVRPROG (button) to start - your main-application (or toogle power/reset) + your main-application or toogle power/reset. -good luck, feedback welcome. + +Feedback welcome, Good luck. Martin