diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index dd3bcb2b8d4..71511714ad1 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -1637,24 +1637,48 @@ public void setCompilingProgress(int percent) { protected void size(String buildPath, String suggestedClassName) throws RunnerException { - long size = 0; - String maxsizeString = Base.getBoardPreferences().get("upload.maximum_size"); - if (maxsizeString == null) return; - long maxsize = Integer.parseInt(maxsizeString); + long textSize = 0; + long dataSize = 0; + String maxTextSizeString = Base.getBoardPreferences().get("upload.maximum_size"); + String maxDataSizeString = Base.getBoardPreferences().get("upload.maximum_data_size"); + if (maxTextSizeString == null) return; + long maxTextSize = Integer.parseInt(maxTextSizeString); + long maxDataSize = -1; + if(maxDataSizeString != null) + maxDataSize = Integer.parseInt(maxDataSizeString); Sizer sizer = new Sizer(buildPath, suggestedClassName); try { - size = sizer.computeSize(); + long[] sizes = sizer.computeSize(); + textSize = sizes[0]; + dataSize = sizes[1]; System.out.println( I18n.format( _("Binary sketch size: {0} bytes (of a {1} byte maximum)"), - size, maxsize + textSize, maxTextSize ) ); + if(maxDataSize > 0) { + System.out.println( + I18n.format( + _("Memory usage: {0} bytes (of a {1} byte maximum)"), + dataSize, maxDataSize + ) + ); + } else { + System.out.println( + I18n.format( + _("Memory usage: {0} bytes"), + dataSize + ) + ); + } } catch (RunnerException e) { System.err.println(I18n.format(_("Couldn't determine program size: {0}"), e.getMessage())); } - if (size > maxsize) + /* At least 10% of RAM should be reserved for stack/heap usage */ + if (textSize > maxTextSize || + (maxDataSize > 0 && dataSize > maxDataSize*9/10)) throw new RunnerException( _("Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.")); } diff --git a/app/src/processing/app/debug/Sizer.java b/app/src/processing/app/debug/Sizer.java index 67ce2080ca7..1522b6ec659 100644 --- a/app/src/processing/app/debug/Sizer.java +++ b/app/src/processing/app/debug/Sizer.java @@ -33,7 +33,9 @@ public class Sizer implements MessageConsumer { private String buildPath, sketchName; private String firstLine; - private long size; + private long textSize; + private long dataSize; + private long eepromSize; private RunnerException exception; public Sizer(String buildPath, String sketchName) { @@ -41,19 +43,22 @@ public Sizer(String buildPath, String sketchName) { this.sketchName = sketchName; } - public long computeSize() throws RunnerException { + public long[] computeSize() throws RunnerException { String avrBasePath = Base.getAvrBasePath(); String commandSize[] = new String[] { avrBasePath + "avr-size", + "-A", " " }; - commandSize[1] = buildPath + File.separator + sketchName + ".hex"; + commandSize[2] = buildPath + File.separator + sketchName + ".elf"; int r = 0; try { exception = null; - size = -1; + textSize = -1; + dataSize = -1; + eepromSize = -1; firstLine = null; Process process = Runtime.getRuntime().exec(commandSize); MessageSiphon in = new MessageSiphon(process.getInputStream(), this); @@ -80,10 +85,10 @@ public long computeSize() throws RunnerException { if (exception != null) throw exception; - if (size == -1) + if (textSize == -1) throw new RunnerException(firstLine); - return size; + return new long[] { textSize, dataSize, eepromSize }; } public void message(String s) { @@ -92,10 +97,27 @@ public void message(String s) { else { StringTokenizer st = new StringTokenizer(s, " "); try { - st.nextToken(); - st.nextToken(); - st.nextToken(); - size = (new Integer(st.nextToken().trim())).longValue(); + String section = st.nextToken(); + if(!section.startsWith(".")) + return; + long bytes = (new Integer(st.nextToken().trim())).longValue(); + //long addr = (new Integer(st.nextToken().trim())).longValue(); + //System.out.println("Section: " + section + " with " + bytes + " bytes at address " + addr); + if(section.equals(".text") || section.equals(".data") || section.equals(".bootloader")) { + if(textSize < 0) + textSize = 0; + textSize += bytes; + } + if(section.equals(".data") || section.equals(".bss") || section.equals(".noinit")) { + if(dataSize < 0) + dataSize = 0; + dataSize += bytes; + } + if(section.equals(".eeprom")) { + if(eepromSize < 0) + eepromSize = 0; + eepromSize += bytes; + } } catch (NoSuchElementException e) { exception = new RunnerException(e.toString()); } catch (NumberFormatException e) { @@ -103,4 +125,4 @@ public void message(String s) { } } } -} \ No newline at end of file +} diff --git a/hardware/arduino/boards.txt b/hardware/arduino/boards.txt index 145d551c095..2d2ffe07507 100644 --- a/hardware/arduino/boards.txt +++ b/hardware/arduino/boards.txt @@ -5,6 +5,7 @@ uno.name=Arduino Uno uno.upload.protocol=arduino uno.upload.maximum_size=32256 +uno.upload.maximum_data_size=2048 uno.upload.speed=115200 uno.bootloader.low_fuses=0xff uno.bootloader.high_fuses=0xde @@ -24,6 +25,7 @@ atmega328.name=Arduino Duemilanove w/ ATmega328 atmega328.upload.protocol=arduino atmega328.upload.maximum_size=30720 +atmega328.upload.maximum_data_size=2048 atmega328.upload.speed=57600 atmega328.bootloader.low_fuses=0xFF @@ -45,6 +47,7 @@ diecimila.name=Arduino Diecimila or Duemilanove w/ ATmega168 diecimila.upload.protocol=arduino diecimila.upload.maximum_size=14336 +diecimila.upload.maximum_data_size=1024 diecimila.upload.speed=19200 diecimila.bootloader.low_fuses=0xff @@ -66,6 +69,7 @@ nano328.name=Arduino Nano w/ ATmega328 nano328.upload.protocol=arduino nano328.upload.maximum_size=30720 +nano328.upload.maximum_data_size=2048 nano328.upload.speed=57600 nano328.bootloader.low_fuses=0xFF @@ -87,6 +91,7 @@ nano.name=Arduino Nano w/ ATmega168 nano.upload.protocol=arduino nano.upload.maximum_size=14336 +nano.upload.maximum_data_size=1024 nano.upload.speed=19200 nano.bootloader.low_fuses=0xff @@ -213,6 +218,7 @@ mini328.name=Arduino Mini w/ ATmega328 mini328.upload.protocol=arduino mini328.upload.maximum_size=28672 +mini328.upload.maximum_data_size=2048 mini328.upload.speed=115200 mini328.bootloader.low_fuses=0xff @@ -234,6 +240,7 @@ mini.name=Arduino Mini w/ ATmega168 mini.upload.protocol=arduino mini.upload.maximum_size=14336 +mini.upload.maximum_data_size=1024 mini.upload.speed=19200 mini.bootloader.low_fuses=0xff @@ -255,6 +262,7 @@ ethernet.name=Arduino Ethernet ethernet.upload.protocol=arduino ethernet.upload.maximum_size=32256 +ethernet.upload.maximum_data_size=2048 ethernet.upload.speed=115200 ethernet.bootloader.low_fuses=0xff @@ -276,6 +284,7 @@ fio.name=Arduino Fio fio.upload.protocol=arduino fio.upload.maximum_size=30720 +fio.upload.maximum_data_size=2048 fio.upload.speed=57600 fio.bootloader.low_fuses=0xFF @@ -297,6 +306,7 @@ bt328.name=Arduino BT w/ ATmega328 bt328.upload.protocol=arduino bt328.upload.maximum_size=28672 +bt328.upload.maximum_data_size=2048 bt328.upload.speed=19200 bt328.upload.disable_flushing=true @@ -319,6 +329,7 @@ bt.name=Arduino BT w/ ATmega168 bt.upload.protocol=arduino bt.upload.maximum_size=14336 +bt.upload.maximum_data_size=1024 bt.upload.speed=19200 bt.upload.disable_flushing=true @@ -362,6 +373,7 @@ lilypad328.name=LilyPad Arduino w/ ATmega328 lilypad328.upload.protocol=arduino lilypad328.upload.maximum_size=30720 +lilypad328.upload.maximum_data_size=2048 lilypad328.upload.speed=57600 lilypad328.bootloader.low_fuses=0xFF @@ -383,6 +395,7 @@ lilypad.name=LilyPad Arduino w/ ATmega168 lilypad.upload.protocol=arduino lilypad.upload.maximum_size=14336 +lilypad.upload.maximum_data_size=1024 lilypad.upload.speed=19200 lilypad.bootloader.low_fuses=0xe2 @@ -404,6 +417,7 @@ pro5v328.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328 pro5v328.upload.protocol=arduino pro5v328.upload.maximum_size=30720 +pro5v328.upload.maximum_data_size=2048 pro5v328.upload.speed=57600 pro5v328.bootloader.low_fuses=0xFF @@ -425,6 +439,7 @@ pro5v.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168 pro5v.upload.protocol=arduino pro5v.upload.maximum_size=14336 +pro5v.upload.maximum_data_size=1024 pro5v.upload.speed=19200 pro5v.bootloader.low_fuses=0xff @@ -446,6 +461,7 @@ pro328.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328 pro328.upload.protocol=arduino pro328.upload.maximum_size=30720 +pro328.upload.maximum_data_size=2048 pro328.upload.speed=57600 pro328.bootloader.low_fuses=0xFF @@ -467,6 +483,7 @@ pro.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168 pro.upload.protocol=arduino pro.upload.maximum_size=14336 +pro.upload.maximum_data_size=1024 pro.upload.speed=19200 pro.bootloader.low_fuses=0xc6 @@ -488,6 +505,7 @@ atmega168.name=Arduino NG or older w/ ATmega168 atmega168.upload.protocol=arduino atmega168.upload.maximum_size=14336 +atmega168.upload.maximum_data_size=1024 atmega168.upload.speed=19200 atmega168.bootloader.low_fuses=0xff diff --git a/hardware/arduino/cores/arduino/HardwareSerial.cpp b/hardware/arduino/cores/arduino/HardwareSerial.cpp index eb2365f3337..5829b8f49e9 100644 --- a/hardware/arduino/cores/arduino/HardwareSerial.cpp +++ b/hardware/arduino/cores/arduino/HardwareSerial.cpp @@ -54,9 +54,9 @@ // to which to write the next incoming character and tail is the index of the // location from which to read. #if (RAMEND < 1000) - #define SERIAL_BUFFER_SIZE 16 + #define SERIAL_BUFFER_SIZE 16U #else - #define SERIAL_BUFFER_SIZE 64 + #define SERIAL_BUFFER_SIZE 64U #endif struct ring_buffer @@ -89,7 +89,7 @@ struct ring_buffer inline void store_char(unsigned char c, ring_buffer *buffer) { - int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE; + unsigned int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE; // if we should be storing the received character into the location // just before the tail (meaning that the head would advance to the @@ -120,18 +120,20 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #endif { #if defined(UDR0) + unsigned char c; if (bit_is_clear(UCSR0A, UPE0)) { - unsigned char c = UDR0; + c = UDR0; store_char(c, &rx_buffer); } else { - unsigned char c = UDR0; + c = UDR0; }; #elif defined(UDR) + unsigned char c; if (bit_is_clear(UCSRA, PE)) { - unsigned char c = UDR; + c = UDR; store_char(c, &rx_buffer); } else { - unsigned char c = UDR; + c = UDR; }; #else #error UDR not defined @@ -146,11 +148,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #define serialEvent1_implemented ISR(USART1_RX_vect) { + unsigned char c; if (bit_is_clear(UCSR1A, UPE1)) { - unsigned char c = UDR1; + c = UDR1; store_char(c, &rx_buffer1); } else { - unsigned char c = UDR1; + c = UDR1; }; } #endif @@ -161,11 +164,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #define serialEvent2_implemented ISR(USART2_RX_vect) { + unsigned char c; if (bit_is_clear(UCSR2A, UPE2)) { - unsigned char c = UDR2; + c = UDR2; store_char(c, &rx_buffer2); } else { - unsigned char c = UDR2; + c = UDR2; }; } #endif @@ -176,11 +180,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #define serialEvent3_implemented ISR(USART3_RX_vect) { + unsigned char c; if (bit_is_clear(UCSR3A, UPE3)) { - unsigned char c = UDR3; + c = UDR3; store_char(c, &rx_buffer3); } else { - unsigned char c = UDR3; + c = UDR3; }; } #endif @@ -365,7 +370,6 @@ void HardwareSerial::begin(unsigned long baud) void HardwareSerial::begin(unsigned long baud, byte config) { uint16_t baud_setting; - uint8_t current_config; bool use_u2x = true; #if F_CPU == 16000000UL @@ -453,13 +457,14 @@ int HardwareSerial::read(void) void HardwareSerial::flush() { // UDR is kept full while the buffer is not empty, so TXC triggers when EMPTY && SENT - while (transmitting && ! (*_ucsra & _BV(TXC0))); + while (transmitting && ! (*_ucsra & _BV(TXC0))) + ; transmitting = false; } size_t HardwareSerial::write(uint8_t c) { - int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; + unsigned int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; // If the output buffer is full, there's nothing for it other than to // wait for the interrupt handler to empty it a bit diff --git a/hardware/arduino/cores/arduino/IPAddress.h b/hardware/arduino/cores/arduino/IPAddress.h index 2585aec0e48..cb49ff42d69 100644 --- a/hardware/arduino/cores/arduino/IPAddress.h +++ b/hardware/arduino/cores/arduino/IPAddress.h @@ -48,8 +48,14 @@ class IPAddress : public Printable { // Overloaded cast operator to allow IPAddress objects to be used where a pointer // to a four-byte uint8_t array is expected - operator uint32_t() { return *((uint32_t*)_address); }; - bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); }; + operator uint32_t() { return ((uint32_t)_address[0] << 0 | + (uint32_t)_address[1] << 8 | + (uint32_t)_address[2] << 16 | + (uint32_t)_address[3] << 24); } + bool operator==(const IPAddress& addr) { return (_address[0] == addr._address[0] && + _address[1] == addr._address[1] && + _address[2] == addr._address[2] && + _address[3] == addr._address[3]); } bool operator==(const uint8_t* addr); // Overloaded index operator to allow getting and setting individual octets of the address diff --git a/hardware/arduino/cores/arduino/Print.cpp b/hardware/arduino/cores/arduino/Print.cpp index 53961ec478c..00b83d98d2b 100755 --- a/hardware/arduino/cores/arduino/Print.cpp +++ b/hardware/arduino/cores/arduino/Print.cpp @@ -41,7 +41,7 @@ size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::print(const __FlashStringHelper *ifsh) { - const char PROGMEM *p = (const char PROGMEM *)ifsh; + const char *p = (const char *)ifsh; size_t n = 0; while (1) { unsigned char c = pgm_read_byte(p++); diff --git a/hardware/arduino/cores/arduino/Stream.cpp b/hardware/arduino/cores/arduino/Stream.cpp index aafb7fcf97d..c1f9686360b 100644 --- a/hardware/arduino/cores/arduino/Stream.cpp +++ b/hardware/arduino/cores/arduino/Stream.cpp @@ -176,7 +176,7 @@ float Stream::parseFloat(char skipChar){ boolean isNegative = false; boolean isFraction = false; long value = 0; - char c; + signed char c; float fraction = 1.0; c = peekNextDigit(); diff --git a/hardware/arduino/cores/arduino/wiring_private.h b/hardware/arduino/cores/arduino/wiring_private.h index f678265679e..b1d6b178502 100755 --- a/hardware/arduino/cores/arduino/wiring_private.h +++ b/hardware/arduino/cores/arduino/wiring_private.h @@ -52,7 +52,8 @@ extern "C"{ #define EXTERNAL_INT_6 6 #define EXTERNAL_INT_7 7 -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || \ + defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) #define EXTERNAL_NUM_INTERRUPTS 8 #elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) #define EXTERNAL_NUM_INTERRUPTS 3