Go Down

Topic: New optiboot; beta testers welcome... (Read 115 times) previous topic - next topic

westfw

I've been working on the Arduino copy of optiboot, and have a new version that could use some testing.
It pretty much tries to fix all the optiboot-related issues open for Arduino:


  • 380 optiboot has problems uploading sketches bigger than about 30 KB

  • 517 Makefile in the /optiboot directory not functional with avrdude 5.10 / gnu make 3.8.1

  • 556 update optiboot to the point of the latest optiboot project sources.

  • 487 should be possible to compile optiboot using the Arduino-installed tools.

  • 526 optiboot can start sketchs with inconsistent regster configuration side-effects

  • 554 Optiboot source/binary should include a version number.

  • 555 Optiboot high-value watchdog timeouts are defined incorrectly.

  • Code space reduction (alas, more features show up to consume the saved space)

  • Additional platforms.  Notably atmega8.

  • 368 Optiboot does not support ArduinoasISP programmer

  • Return FW version numbers in response to appropriate commands.

  • The pre-built list of .hex and .lst files is reduced.



Although there are substantial numbers of changes, very little of the core logic of optiboot has changed.

Tested on m328, m168, m8, some with manual reset, and with ArdunioISP. Mostly on Mac, some on windows xp. Needs more linux testing.

Hex file (for m328) attached.  Source and stuff at https://github.com/WestfW/Arduino


madworm

Issue 517 seems fixed on my system, which is neither macos nor the unmentionable os.

Compiling using 'makeall' works as well. And the .hex file size is below 512 bytes. I'm using avr-gcc 4.4.3 + avr-libc 1.7.1 (from avrfreaks.net using Bingo's build script).
• Upload doesn't work? Do a loop-back test.
• There's absolutely NO excuse for not having an ISP!
• Your AVR needs a brain surgery? Use the online FUSE calculator.
My projects: RGB LED matrix, RGB LED ring, various ATtiny gadgets...
• Microsoft is not the answer. It is the question, and the answer is NO!

Mike T

#2
Jun 17, 2011, 09:50 am Last Edit: Jun 17, 2011, 09:56 am by Mike T Reason: 1
Hi westfw,


I've been working on the Arduino copy of optiboot, and have a new version that could use some testing.
Hex file (for m328) attached.  Source and stuff at https://github.com/WestfW/Arduino


Yesterday I started a new optiboot clone at google code which includes almost the same changes to the original optiboot you also mentioned  :smiley-mr-green:

My main focus was to integrate the BlueController board in the Arduino environment. The BlueController includes a Bluetooth module BTM-222 onboard (just like the Arduino-BT), but using my modified optiboot bootloader, the download of sketches works much more reliable as on the Arduino-BT!

Some additions were necessary for the BlueController which can be useful for any other boards which don't support auto-reset, even for the Arduino-BT. Currently I use the #define BLUECONTROLLER to distinguish between the BlueController board and other boards, but it makes sense to use multiple #defines for hardware specific code (like the LED pin number) and the support of the longer timeout for boards without auto-reset.

Is there a reason using GitHub instead of Google code? I wanted to merge back my changes to the original optiboot branch, therefore I used Google code. The most obvious advantage is that my project is directly linked together with the original project. Actually I wouldn't have started the new clone if I had seen yours before.

 Michael

Mike T

#3
Jun 17, 2011, 11:11 am Last Edit: Jun 17, 2011, 11:24 am by Mike T Reason: 1
Hi westfw,



  • Code space reduction (alas, more features show up to consume the saved space)

  • 380 optiboot has problems uploading sketches bigger than about 30 KB




the fix for issue 380 (see below) is consuming 32 additional bytes which I badly needed for my BlueController extensions. Therefore I could not use the overlapping boot_page_erase() and serial communication. For the Bluetooth communication this doesn't matter. Comparing the time with and without overlapping erase gave no difference. I haven't tested it with USB UART communication right now.

The code that could be saved is in bold:
+      // If we are in RWW section, immediately start page erase
+#if !defined(BLUECONTROLLER)
+      if (address < NRWWSTART)
+   1fcba:   80 e0          ldi   r24, 0x00   ; 0
+   1fcbc:   e8 16          cp   r14, r24
+   1fcbe:   80 ee          ldi   r24, 0xE0   ; 224
+   1fcc0:   f8 06          cpc   r15, r24
+   1fcc2:   20 f4          brcc   .+8         ; 0x1fccc <main+0xcc>
+        __boot_page_erase_short((uint16_t)(void*)address);
+   1fcc4:   83 e0          ldi   r24, 0x03   ; 3
+   1fcc6:   f7 01          movw   r30, r14
+   1fcc8:   87 bf          out   0x37, r24   ; 55
+   1fcca:   e8 95          spm
+   1fccc:   c2 e0          ldi   r28, 0x02   ; 2
+   1fcce:   d2 e0          ldi   r29, 0x02   ; 2
+#endif
[...]
+      // If we are in NRWW section, page erase has to be delayed until now.
+      // Todo: Take RAMPZ into account
+#if !defined(BLUECONTROLLER)
+      if (address >= NRWWSTART)
+   1fcd8:   f0 e0          ldi   r31, 0x00   ; 0
+   1fcda:   ef 16          cp   r14, r31
+   1fcdc:   f0 ee          ldi   r31, 0xE0   ; 224
+   1fcde:   ff 06          cpc   r15, r31
+   1fce0:   20 f0          brcs   .+8         ; 0x1fcea <main+0xea>
+#endif
+        __boot_page_erase_short((uint16_t)(void*)address);
+   1fce2:   83 e0          ldi   r24, 0x03   ; 3
+   1fce4:   f7 01          movw   r30, r14
+   1fce6:   87 bf          out   0x37, r24   ; 55
+   1fce8:   e8 95          spm
+      }
+#endif

Without loosing any performance or functionality, the code can be optimized to compare only the high-byte of the NRWWSTART, (because the low byte of NRWWSTART will always be zero) which saves 6 bytes:
Code: [Select]
     // If we are in RWW section, immediately start page erase
#if !defined(BLUECONTROLLER)
     if ((uint8_t)(address >> 8) < (uint8_t)(NRWWSTART >> 8))
   7eb0:       8d 2d           mov     r24, r13
   7eb2:       99 27           eor     r25, r25
   7eb4:       08 2f           mov     r16, r24
   7eb6:       80 37           cpi     r24, 0x70       ; 112
   7eb8:       20 f4           brcc    .+8             ; 0x7ec2 <main+0xc2>
       __boot_page_erase_short((uint16_t)(void*)address);
   7eba:       83 e0           ldi     r24, 0x03       ; 3
   7ebc:       f6 01           movw    r30, r12
   7ebe:       87 bf           out     0x37, r24       ; 55
   7ec0:       e8 95           spm
   7ec2:       c2 e0           ldi     r28, 0x02       ; 2
   7ec4:       d1 e0           ldi     r29, 0x01       ; 1
#endif      
[...]
     // If we are in NRWW section, page erase has to be delayed until now.
     // Todo: Take RAMPZ into account
#if !defined(BLUECONTROLLER)
     if (!((uint8_t)(address >> 8) < (uint8_t)(NRWWSTART >> 8)))
   7ece:       00 37           cpi     r16, 0x70       ; 112
   7ed0:       20 f0           brcs    .+8             ; 0x7eda <main+0xda>
#endif
       __boot_page_erase_short((uint16_t)(void*)address);
   7ed2:       83 e0           ldi     r24, 0x03       ; 3
   7ed4:       f6 01           movw    r30, r12
   7ed6:       87 bf           out     0x37, r24       ; 55
   7ed8:       e8 95           spm
     }
#endif


I don't understand why the compiler generates the mov+eor+mov instructions for the first compare, maybe you have an idea?

 Michael

westfw

Quote
Is there a reason using GitHub instead of Google code?


Yeah, the plan is to maintain the arduino-associated copy of optiboot separately as part of the arduino codebase (which is hosted on github.)  The tree I pointed to is forked off of the main arduino branch, and if all goes well it will be pulled back in and become the official code.

The NRWW section stuff is straight from the existing optiboot source tree (mercurial from google code); it (the optiboot google code repository) was 506 bytes to start with.  I got back some 28 bytes by moving address and length into registers, and used most of it up implementing the versioning, the ArduinoISP fix, and keeping the compiler happy (the new version is 502 bytes.)

I like your patch to only compare the high byte.

Does the extra code you were worried about go away if you simply define NRWWSTART to 0 ?   gcc is usually pretty good about optimizing away if clauses that are never true.  An attempt here says I get back 26 bytes, but I didn't look at the object code to see whether that was all that could be gotten...

Go Up