Go Down

Topic: NEWER New Optiboot bootloader (Read 16810 times) previous topic - next topic

westfw

Quote
version of optiboot for the ATTiny 4313?
Not that I know of.  You might check the version mentioned in https://github.com/Optiboot/optiboot/issues/177; it apparently supports 110 chips (but I haven't gotten a chance to look at it at all.)


nebula83

@westfw Ah, that's why the version wasn't updated: the behavior is the same. Thanks!

Isaac96

@westFW
Thanks!
326 bytes... That is tiny.
Do not PM me for help. I will delete immediately.
CONNECT THE GROUNDS!

After Tuesday, even the calendar goes W T F

Budvar10

#78
Sep 05, 2016, 01:05 pm Last Edit: Sep 05, 2016, 01:15 pm by Budvar10
After some long period on Arduino IDE v1.0.6 with replaced toolchain to v3.4.2  (avr-gcc v4.7.2), I've decided to move to the Atmel AVR Toolchain v3.5.3.1700 with avr-gcc v4.9.2. I had to resolve two simple problems:
1. avr-gcc v4.9.2 doesn't support optimizing option -mshort-calls; there is -mrelax instead
2. problem with eeprom_write_byte and eeprom_read_byte (undefined reference); LIBS = -l$(MCU_TARGER) solves it.
As  I'm writting this I found in response #75 the same solution for my 2nd problem and also (partially - I'm not satisfied with) for my question.
The question is: "How to achieve at least the same size of image without modifying source code?"
I have modified optiboot and its size with 4.7.2 is 706B, with 4.9.2 it is 738B. Is there any option for another optimizing step (any switch) or the 4.9.2 simply produces bigger code and this possibility is closed?

EDIT: I tried BareMinimum sketch and the size is the same.

EDIT2: I'm currently working with ATmega1284P but as I see the optiboot for ATmega328P does not fit into 512B. It is 525B now.
Arduino clone with ATmega1284P   http://forum.arduino.cc/index.php?topic=277260.0

Budvar10

First partial success or nearly full success! Going throughout the ASM code I realised that the main harms are caused by optimizing the watchdogConfig(). So the attribute noinline produces smaller code, now it's 708B which is very close to 706B, but for the UNO it is 494B to previous 488B.
And as I see the original optiboot code on the GitHub it already has defined as noinline. :( :smiley-confuse: :) :D  8)
Arduino clone with ATmega1284P   http://forum.arduino.cc/index.php?topic=277260.0

westfw

Quote
I've decided to move to the Atmel AVR Toolchain v3.5.3.1700 with avr-gcc v4.9.2.
 I see the optiboot for ATmega328P does not fit into 512B.
I'm using Atmel 3.5.2_444 (which is also gcc 4.9.2), and the stock optiboot for 328 compiles to 464 bytes.
Are you using the latest source from the github repository at https://github.com/Optiboot/optiboot, the source from the IDE distribution, or something else?  (The change to -mrelax was made over two years ago.  The version distributed with the IDE hasn't been updated in forever, and isn't particularly expected to be updated...)


Budvar10

No, not latest source. I think, I started with 4.6 version and did several modifications. My version is probably little bit far from actual official optiboot. I missed the switch -mrelax because I'm using gcc 4.7.2 for the years, since Arduino IDE 1.0.6 was released. This version of IDE uses gcc 4.3.2 which was very old at this time. So, I replaced the whole AVR toolchain with gcc 4.7.2 to be same as Atmel Studio 6.1 has.
I don't want to critize the Arduino 1.6.x versions but the reason why I'm not using it is that there is a lot of bugs and the changes in SW don't offer me a benefit concerning to ATmega. I have modified core for my needs focused mainly to a size.
I know about the difference in size of UNO bootloader: official 464 vs mine 488. I cannot say why at now. I have a dozen genuine UNOs but never changed the bootloader and I would use original in case. Mainly I am interesting in 1284P. I have my own variant. My bootloader allows to upload into EEPROM and reads the fuses and lock etc. to utilize 1kB of boot space.

Here is a snippet for a fuses and lock.
Code: [Select]
/* STK500 Universal Command */
} else if(ch == STK_UNIVERSAL) { // universal command - fuse & lock bits
#if defined(BIGBOOT)
/* read fuse and lock bits; it takes additional 80 bytes */
uint8_t ucb1 = getch(); // universal command byte 1
uint8_t ucb2 = getch(); // universal command byte 2
getNch(2); // discard universal command byte 3-4
uint8_t ucr  = 0; // response

/* mapping algorithm for function parameter, optimized to save a space:
ucb1(0x50), ucb2(0x00) -> GET_LOW_FUSE_BITS     (0x0000)
ucb1(0x58), ucb2(0x00) -> GET_LOCK_BITS         (0x0001)
ucb1(0x50), ucb2(0x08) -> GET_EXTENDED_FUSE_BITS(0x0002)
ucb1(0x58), ucb2(0x08) -> GET_HIGH_FUSE_BITS    (0x0003)
*/
if((ucb1 & ~(0x08)) == 0x50 && (ucb2 & ~(0x08)) == 0x00) {
ucb1  = ((ucb1 & 0x08) ? 1 : 0) | (ucb2 >> 2);
ucr   = boot_lock_fuse_bits_get((uint16_t)ucb1);
}
putch(ucr);
#else // universal command is ignored
getNch(4); // 4 bytes of data/command
putch(0x00); // response
#endif


It should produce this:
Code: [Select]

/* STK500 Universal Command */
} else if(ch == STK_UNIVERSAL) { // universal command - fuse & lock bits
   1fcb8: 86 35       cpi r24, 0x56 ; 86
   1fcba: d1 f4       brne .+52     ; 0x1fcf0 <main+0xf0>
#if defined(BIGBOOT)
/* read fuse and lock bits; it takes additional 82 bytes */
uint8_t ucb1 = getch(); // universal command byte 1
   1fcbc: c5 d0       rcall .+394     ; 0x1fe48 <getch>
   1fcbe: c8 2e       mov r12, r24
uint8_t ucb2 = getch(); // universal command byte 2
   1fcc0: c3 d0       rcall .+390     ; 0x1fe48 <getch>
   1fcc2: d8 2e       mov r13, r24
getNch(2); // discard universal command byte 3-4
   1fcc4: 82 e0       ldi r24, 0x02 ; 2
   1fcc6: da d0       rcall .+436     ; 0x1fe7c <getNch>
ucb1(0x50), ucb2(0x00) -> GET_LOW_FUSE_BITS     (0x0000)
ucb1(0x58), ucb2(0x00) -> GET_LOCK_BITS         (0x0001)
ucb1(0x50), ucb2(0x08) -> GET_EXTENDED_FUSE_BITS(0x0002)
ucb1(0x58), ucb2(0x08) -> GET_HIGH_FUSE_BITS    (0x0003)
*/
if((ucb1 & ~(0x08)) == 0x50 && (ucb2 & ~(0x08)) == 0x00) {
   1fcc8: 8c 2d       mov r24, r12
   1fcca: 87 7f       andi r24, 0xF7 ; 247
   1fccc: 80 35       cpi r24, 0x50 ; 80
   1fcce: 71 f4       brne .+28     ; 0x1fcec <main+0xec>
   1fcd0: 8d 2d       mov r24, r13
   1fcd2: 87 7f       andi r24, 0xF7 ; 247
   1fcd4: 59 f4       brne .+22     ; 0x1fcec <main+0xec>
ucb1  = ((ucb1 & 0x08) ? 1 : 0) | (ucb2 >> 2);
   1fcd6: c3 fa       bst r12, 3
   1fcd8: ee 27       eor r30, r30
   1fcda: e0 f9       bld r30, 0
   1fcdc: d6 94       lsr r13
   1fcde: d6 94       lsr r13
   1fce0: ed 29       or r30, r13
ucr   = boot_lock_fuse_bits_get((uint16_t)ucb1);
   1fce2: f0 e0       ldi r31, 0x00 ; 0
   1fce4: 40 92 57 00 sts 0x0057, r4
   1fce8: 84 91       lpm r24, Z
   1fcea: cd cf       rjmp .-102     ; 0x1fc86 <main+0x86>
#if defined(BIGBOOT)
/* read fuse and lock bits; it takes additional 82 bytes */
uint8_t ucb1 = getch(); // universal command byte 1
uint8_t ucb2 = getch(); // universal command byte 2
getNch(2); // discard universal command byte 3-4
uint8_t ucr  = 0; // response
   1fcec: 80 e0       ldi r24, 0x00 ; 0
   1fcee: cb cf       rjmp .-106     ; 0x1fc86 <main+0x86>
getNch(4); // 4 bytes of data/command
putch(0x00); // response
#endif

 Feel free to use it.

Arduino clone with ATmega1284P   http://forum.arduino.cc/index.php?topic=277260.0

Budvar10

...forgot to mention the boot_lock_fuse_bits_get() have to be used the original one from avr/boot.h.

Arduino clone with ATmega1284P   http://forum.arduino.cc/index.php?topic=277260.0

westfw

Quote
My version is probably little bit far from actual official optiboot.
Keeping the optiboot code base "up-to-date" with respect to various avr-gcc "improvements" has been a pretty constant battle.  You might look at https://github.com/Optiboot/optiboot/issues/101 in particular
Also, the support for overlapping serial com with page erase (NRWWSTART/etc) was removed after measurements showed it to not be very useful, and that saved a relatively large amount of space.  https://github.com/Optiboot/optiboot/commit/6c06686902a04e4d4defe73a2f2981b299373844

Budvar10

Quote
My version is probably little bit far from actual official optiboot.
Just to clarify, I don't want to say my is better but it differs. I know it is hard work to keep the code up to date.
You have a K+ from me for that.

I remember, I'd read this https://github.com/Optiboot/optiboot/commit/6c06686902a04e4d4defe73a2f2981b299373844 but I was not paying attention to it up to now. Thank you.
Yes, it save the space. As I know, optiboot for UNO did not use it to fit into 512B.



Arduino clone with ATmega1284P   http://forum.arduino.cc/index.php?topic=277260.0

scrumfled

#85
Sep 14, 2016, 01:22 pm Last Edit: Sep 14, 2016, 03:56 pm by scrumfled
Silly question alert...

I've just grabbed a 1284 with optiboot on it, which seems to have a somewhat messy pin layout. I understand this is mapped from the base AVR ports (probably wrong terminology).

Anyway, Im trying to understand where things like the external interrupts are mapped, is this anything I could read myself to see where they are(eg from a config file somewhere)?

PS. pinout from top left:

D4--------A7/D21
D5--------A6/D20
D2--------A5/D19
D3--------A4/D18
D10-------A3/D17
D11-------A2/D16
D12-------A1/D15
D13-------A0/D14
RST--------Aref
Vcc--------GND
GND-------AVcc
XTAL2-----D29
XTAL1-----D28
D0/Rx0----D27
D1/Tx0----D26
D6/Rx1----D25
D7/Tx1----D24
D30-------D23
D8--------D22
D9--------D31

Budvar10

ATmega pins have several functions and they are hardwired to ATmega's pins. The external interrupts are alternative functions of I/O. The datasheet of ATmega describes the mapping. If you have known pin mapping to Arduino it is not a problem to find out where the ext. interrupt is. For an example: INT0 is on the PD2 of ATmega1284P (pin 16 on DIL package) . There are also RXD1 and PCINT26 functionality and according your map it is D6 on Arduino.
Arduino clone with ATmega1284P   http://forum.arduino.cc/index.php?topic=277260.0

RodSchmidt

I've had a mega2560 for a couple of years and reverse engineered an avrdude subset to upload sketches to it as part of a larger software project. It used stk500v2 programming. Just got a new UNO R3, which programs fine with Arduino 1.6.9. IT uses stk500/optiboot programming sequences. But my old uploader also sort of works, and there is no code in optiboot to recognize v2 sequences! I've added timing measurement to my own v2 uploader, and the first  packet (v2 logon) doesn't get picked up for about 100 ms. Then it loads fine, but every 8 packets (1024 bytes) there is a 6 sec delay before the next packet is accepted.

One of my goals in this is to be able to power on/off the board while debugging hardware w/o having to deal with the IDE and its concept of serial ports (moving USB target on Linux)..My own uploader pokes around and finds the new /dev/ttyACMx port without my intervention. So 2 issues:

1) why does my loader work at all? The IDE generates 2 hex files, one with bootloader(?) and one without. This is new - could the "bootloader" stuck in the sketch be a v2 loader that runs as an application after a timeout???  Or what?

2) I'm prepared to add stk500 (v1) code to my uploader - it's simpler than the v2. But is there a way to detect WHICH format to send - without the tables of magic numbers for each board/mcu/etc that seems to be how the current software is designed.

westfw

If there's a 6-second delay, that almost certainly means that the Uno is resetting and starting over.  What makes you think that it's "working" ?   Have you uploaded and successfully run a sketch larger than 1024 bytes?  (IMO, it SHOULDN'T work at all.  v2 wraps everything into "packets" so that the receiver can check CRC/etc.  v1 doesn't understand those...)

I think v2 sends a startup string at poweron, while v1 is quiet until the PC sends it commands...

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy