xxxajk / PhysicaloidLibrary

Android Library for communicating with physical-computing boards (e.g.Arduino, mbed)
http://www.physicaloid.com/
21 stars 10 forks source link

writing large firmware #10

Closed hamidsani closed 6 years ago

hamidsani commented 6 years ago

With your code now I am able to write firmware in under 15 seconds where as it used to take 20 minutes. So Thanks. But I'm still having an upload issue.

Let's say I have Firmware A and B and C. C (Blink.hex) is a simple blink a LED code that's 8kb size. A (firmware.3.0.5.hex) and B (firmware.3.0.6.hex) are 250kb and very similar version of the firmware with just different version numbers. If I have firmware A already flashed on the PCB (using arduino IDE), then I can upload firmware C and A to it and still get responses back but I can't say the same when I upload B. The messages appears to say successful but I don't get any response back from arduino. If I rewrite Firmware A or C, everything is back to normal.

On the other hand, if I flash firmware B with Arduino IDE then I can write B and C but not A. It's odd. Any suggestions on why I am seeing this issue?

xxxajk commented 6 years ago

It may sound odd, but there is a slight chance that the AVR gets confused. I've seen this happen, and it is very rare.

Three things that you can try are:

  1. Try a different board, this could indicate a failing MCU if only one of them has problems.
  2. Power cycle the AVR board. This may be able to clear the problem that the bootloader can't recover from.
  3. Hold down the reset button and at the moment it tries to upload, release the button. If that works, then there is a possible bug in the bootloader.
hamidsani commented 6 years ago

I tried multiple boards (Arduino Mega), power cycle, or holding down the reset but that didn't change anything. But I started playing with the size of the hex file and looks like at 189kb or more the firmware is not able to flash correctly but anything below 179kb seems to work. I guess I need to give my code a diet but do you have any idea why this would be the case?

xxxajk commented 6 years ago

253952 bytes should be the maximum, in theory. There is a chance that you might not be able to reach the code, caused by a GCC bug. Try a different AVR support. I have found 1.6.11 to be very stable for everything I have used.

You can get a list of symbols and values by using avr-nm. This will allow you to see if any of the values are out of range.

For example:

<path to avr-gcc>/avr-nm -nlCS <path to elf file>/Blink.ino.elf
         w serialEventRun()
00000000 W __heap_end
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 W __vector_default     /home/xxxajk/.arduino15/packages/arduino/hardware/avr/1.6.11/cores/arduino/main.cpp:23
00000000 T __vectors    /home/xxxajk/.arduino15/packages/arduino/hardware/avr/1.6.11/cores/arduino/main.cpp:23
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
0000003b a __RAMPZ__
... and so on...

You should redirect the output to a file so that you can easily inspect it.

The second useful command is:

<path to avr-gcc>/avr-objdump -S <path to elf file>/Blink.ino.elf
Blink.ino.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
   0:   06 c1           rjmp    .+524           ; 0x20e <__ctors_end>
   2:   00 00           nop
   4:   23 c1           rjmp    .+582           ; 0x24c <__bad_interrupt>
   6:   00 00           nop
... and so on ...

At the end of the Blink sketch you will see something like:

int main(void)
{
        init();
 612:   db de           rcall   .-586           ; 0x3ca <init>
 614:   fd df           rcall   .-6             ; 0x610 <initVariant>

        initVariant();
 616:   1b de           rcall   .-970           ; 0x24e <setup>
 618:   c0 e0           ldi     r28, 0x00       ; 0

#if defined(USBCON)
        USBDevice.attach();
#endif

        setup();
 61a:   d0 e0           ldi     r29, 0x00       ; 0
 61c:   1c de           rcall   .-968           ; 0x256 <loop>

        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
 61e:   20 97           sbiw    r28, 0x00       ; 0
 620:   e9 f3           breq    .-6             ; 0x61c <main+0xa>
#endif

        setup();

        for (;;) {
                loop();
 622:   0e 94 00 00     call    0       ; 0x0 <__vectors>
                if (serialEventRun) serialEventRun();
 626:   fa cf           rjmp    .-12            ; 0x61c <main+0xa>

00000628 <yield>:
 * libraries or sketches that supports cooperative threads.
 *
 * Its defined as a weak symbol and it can be redefined to implement a
 * real cooperative scheduler.
 */
static void __empty() {
 628:   08 95           ret

0000062a <__tablejump2__>:
 62a:   ee 0f           add     r30, r30
 62c:   ff 1f           adc     r31, r31

0000062e <__tablejump__>:
 62e:   05 90           lpm     r0, Z+
 630:   f4 91           lpm     r31, Z
 632:   e0 2d           mov     r30, r0
 634:   19 94           eijmp

00000636 <_exit>:
 636:   f8 94           cli

00000638 <__stop_program>:
 638:   ff cf           rjmp    .-2             ; 0x638 <__stop_program>

This should be able to provide you with the clues if GCC is at fault.