sudar / Arduino-Makefile

Makefile for Arduino sketches. It defines the workflows for compiling code, flashing it to Arduino and even communicating through Serial.
http://hardwarefun.com/tutorials/compiling-arduino-sketches-using-makefile
GNU Lesser General Public License v2.1
2.02k stars 449 forks source link

Add perl user docs to bin/ard-verify-size script #54

Closed sudar closed 11 years ago

sudar commented 11 years ago

The other two perl scripts have nice user docs/man pages. We might have to add them for bin/ard-verify-size script as well.

sej7278 commented 11 years ago

ard-verify-size is a bash script, but you could add input parameter checking and basic usage info with a simple if/fi statement:

#!/bin/bash
TARGET_HEX="$1"
MAX_SIZE="$2"

if [ $# -ne 2 ]
then
    echo "Usage: $0 <hex filename> <maximum size in bytes>" 1>&2
    exit 1
fi

HEX_SIZE="$(cut -c12- < $TARGET_HEX | tr -d \\n | tr -d \\r | wc -c | awk '{print $1/2}')"
if [ $HEX_SIZE -gt $MAX_SIZE ]
then
  echo "Sketch size is ${HEX_SIZE} bytes and maximum allowed is ${MAX_SIZE} bytes; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it." 1>&2
  exit 1
fi

What does this script do though, it seems a bit pointless, all its doing is telling you the size of the hex file (coz "ls -l" is sooo hard) and the maximum size that you passed in!

sudar commented 11 years ago

What does this script do though, it seems a bit pointless, all its doing is telling you the size of the hex file (coz "ls -l" is sooo hard) and the maximum size that you passed in!

The script tries to find the size that would be occupied by the hex file inside the microcontroller. I guess this information is present after the 12th byte or something. ls -l will just give only the size occupied by file in the filesystem.

But I agree with you that we don't need a separate script file to do this. I guess we can just do this inside the makefile itself. Less files to deal with.

sej7278 commented 11 years ago

it does seems like a separate script is overkill. ard-verify-size essentially does this:

$ cut -c12- < weather.hex | tr -d \\n | tr -d \\r | wc -c | awk '{print $1/2}'
13910

and then sees if that value is greater than this:

ard-parse-boards uno upload.maximum_size
32256

however "make size" does this:

$ avr-size --format=avr --mcu=atmega328p weather.elf 
AVR Memory Usage
----------------
Device: atmega328p

Program:   13910 bytes (42.4% Full)
(.text + .data + .bootloader)

Data:       1097 bytes (53.6% Full)
(.data + .bss + .noinit)

So it seems to me we can pull the 13910 value from avr-size by piping it to awk:

$ avr-size --format=avr --mcu=atmega328p weather.elf | grep Program | awk '{print $2}'
13910

the ard-verify-size script isn't pulling the size info from the hex, its just ignoring the first 12 chars, removing newlines, counting the bytes and diving by 2.

avr-size is probably more reliable, although what are the limitations if we only have the basic avr-size app (non-avr-aware)?

sudar commented 11 years ago

avr-size is probably more reliable, although what are the limitations if we only have the basic avr-size app (non-avr-aware)?

I checked both Mac and Linux distribution of Arduino and the avr-size binary that gets shipped in both of them is avr-aware. So I guess we can go ahead and replace the script with the output of avr-size command.

If someone is using a custom size binary, then we can assume that they would know its limitations as well. What are your thoughts?

sej7278 commented 11 years ago

yep, go for it, as we're already using avr-size for make size, we might as well use it for make verify-size too and get rid of another script (and no need to add helptext)

sej7278 commented 11 years ago

i tried to switch to avr-size within the Makefile for this, but it errors at the beginning of the build as the elf file (or build directory!) don't even exist at this point. i'm not sure how calling an external script works around it, unless its purely a lucky timing issue.

symbol_sizes: $(OBJDIR)/$(TARGET).sym
    @$(ECHO) A symbol listing sorted by their size have been dumped to $(OBJDIR)/$(TARGET).sym

$(TARGET_HEX).sizeok: $(TARGET_HEX)
ifneq ($(strip $(HEX_MAXIMUM_SIZE)),1)
ifeq ($(shell expr `$(call avr_size,$(TARGET_ELF),$(TARGET_HEX)) | grep Program | awk '{print $$2}'` '<' $(HEX_MAXIMUM_SIZE)), 1)
    touch $@
endif
else
    @$(ECHO) Maximum Hex size is not specified. Make sure the hex file that you are going to upload is less than microcontrollers flash memory
endif

verify_size:    $(TARGET_HEX) $(TARGET_HEX).sizeok
sudar commented 11 years ago

i tried to switch to avr-size within the Makefile for this, but it errors at the beginning of the build as the elf file (or build directory!) don't even exist at this point. i'm not sure how calling an external script works around it, unless its purely a lucky timing issue.

After spending a couple of hours debugging this issue, I finally found out the reason why the makefile is giving the error.

Make seems to do parse the file initially to find out which parts of the file should be included before executing any targets. At that time, the hex file is not yet generated and that's why we are getting this error.

The only way to fix this is to use dynamic conditions and I am not sure if there is a way by which we can do dynamic conditions in makefile.

sudar commented 11 years ago

After spending some more hours, I have finally managed to do this inside the makefile itself, without the need for the external shell script :)