1

If I put this in my arduino program, in main.cpp, I suddenly run out of memory for flash program size:

 if(msgSize > 2) {
 //sr::sequentialRead(&serialRead, newTram.hash);
 uint8_t bytes[4];
 Serial.readBytes(&bytes[0], 2);
 }

Without that I see this:

avr-size -C --mcu=atmega328p connections_display.elf
AVR Memory Usage
----------------
Device: atmega328p
Program: 26348 bytes (80.4% Full)
(.text + .data + .bootloader)
Data: 598 bytes (29.2% Full)
(.data + .bss + .noinit)

But if I use Serial.readBytes, I get:

avr-size -C --mcu=atmega328p connections_display.elf
AVR Memory Usage
----------------
Device: atmega328p
Program: 36404 bytes (111.1% Full)
(.text + .data + .bootloader)
Data: 601 bytes (29.3% Full)
(.data + .bss + .noinit)

I have tried this in blank arduino sketch too, and it doesn't have that problem, so it is something in my build commands.

This is my CMake:

cmake_minimum_required(VERSION 3.11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_SYSTEM_NAME Generic)
# Project name
project("MyProject" VERSION 0.1 LANGUAGES CXX C)
# Product filename (name of the compiled file)
set(PRODUCT_NAME connections_display)
set(ARDUINO_BOARD "UNO")
## AVR Chip Configuration
# 8Mhz, this should match the crystal on your board,
# I use 8Mhz and 3.3V for the lowest power consumption
set(F_CPU 16000000L)
# CPU, you can find the list here:
# https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html
set(MCU atmega328p)
# The programmer to use, read avrdude manual for list
# avrispmkII
set(ARDUINO_PROGRAMMER_TYPE arduino)
set(ARDUINO_PROGRAMMER_COM_ID "COM6")
set(ARDUINO_PROGRAMMER_BAUD 115200)
# AVR Fuses, must be in concordance with your hardware and F_CPU
# http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega328p
set(E_FUSE 0xfd)
set(H_FUSE 0xda)
set(L_FUSE 0xfd)
set(LOCK_BIT 0xff)
# set(CMAKE_AVR_TOOL_COMPILERS "%APPDATA%\\..\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\7円.3.0-atmel3.6.1-arduino7\\bin")
set(ARDUINO_TOOLKIT "%APPDATA%/../Local/Arduino15/packages/arduino")
set(ARDUINO_COMPILERS "${ARDUINO_TOOLKIT}/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin")
set(ARDUINO_AVRDUDE "${ARDUINO_TOOLKIT}/tools/avrdude/6.3.0-arduino17/bin")
set(ARDUINO_AVR_DIRECTORY "${ARDUINO_TOOLKIT}/hardware/avr/1.8.6")
set(ARDUINO_LIBRARIES_HOME "${ARDUINO_AVR_DIRECTORY}/libraries")
set(ARDUINO_CORES_HOME "${ARDUINO_AVR_DIRECTORY}/cores")
get_filename_component(ARDUINO_COMPILER_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
set(AVR_STRIP_COMMAND ${ARDUINO_COMPILER_DIR}/avr-strip)
set(AVR_OBJCOPY_COMMAND ${ARDUINO_COMPILER_DIR}/avr-objcopy)
set(AVR_SIZE_COMMAND ${ARDUINO_COMPILER_DIR}/avr-size)
set(AVR_AVRDUDE_COMMAND ${ARDUINO_AVRDUDE}/avrdude)
set(AVR_AVRDUDE_CONFIG ${ARDUINO_AVRDUDE}/../etc/avrdude.conf)
# Pass defines to compiler
add_definitions(
 -DF_CPU=${F_CPU}
 -DBAUD=${BAUD}
 -DARDUINO=10607
 -DARDUINO_AVR_UNO
 -DARDUINO_ARCH_AVR
 # disable some extra display functions
 -DENA_SCR_DIA=0
 -DENA_MISC=0
 -DENA_OPNCLS=0
 -DENA_GROW=0
)
# mmcu MUST be passed to bot the compiler and linker, this handle the linker
set(CMAKE_EXE_LINKER_FLAGS
 -mmcu=${MCU}
)
add_compile_options(
 -mmcu=${MCU} # MCU
 -Os # optimize
 -Wall # enable warnings
 -Wno-main
 -Wundef
 -pedantic
 -Wno-error=expansion-to-defined
 -Wno-expansion-to-defined
 -Wno-error=cpp
 -Wno-cpp
 -Wl,--relax,--gc-sections
 -g
 -gdwarf-2
 -fno-threadsafe-statics
 -funsigned-char # a few optimizations
 -funsigned-bitfields
 #-fpack-struct
 -fshort-enums
 -ffunction-sections
 -fdata-sections
 #-fno-split-wide-types
 -fno-tree-scev-cprop
)
file(GLOB SRC_FILES "src/*.cpp" "src/*.c") # Load all files in src folder
# Create one target
add_executable(${PRODUCT_NAME} ${SRC_FILES})
target_include_directories(${PRODUCT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/display_controller)
target_include_directories(${PRODUCT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
# Rename the output to .elf as we will create multiple files
set_target_properties(${PRODUCT_NAME} PROPERTIES OUTPUT_NAME ${PRODUCT_NAME}.elf)
target_link_libraries(${PRODUCT_NAME} PRIVATE
 ArduinoCore
)
# Strip binary for upload
add_custom_target(avr_strip_hex ALL ${AVR_STRIP_COMMAND} ${PRODUCT_NAME}.elf DEPENDS ${PRODUCT_NAME})
# Transform binary into hex file, we ignore the eeprom segments in the step
add_custom_target(avr_create_hex ALL ${AVR_OBJCOPY_COMMAND} -O ihex -R .eeprom ${PRODUCT_NAME}.elf ${PRODUCT_NAME}.hex DEPENDS avr_strip_hex)
# Transform binary into hex file, this is the eeprom part (empty if you don't
# use eeprom static variables)
add_custom_target(eeprom ${AVR_OBJCOPY_COMMAND} -O ihex -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 ${PRODUCT_NAME}.elf ${PRODUCT_NAME}.eep DEPENDS avr_strip_hex)
add_custom_target(avr_calc_size_two ALL ${AVR_SIZE_COMMAND} -A --mcu=${MCU} ${PRODUCT_NAME}.elf DEPENDS avr_create_hex)
add_custom_target(avr_calc_size ALL ${AVR_SIZE_COMMAND} -C --mcu=${MCU} ${PRODUCT_NAME}.elf DEPENDS avr_calc_size_two)
# Upload the firmware with avrdude
add_custom_target(upload_to_arduino ${AVR_AVRDUDE_COMMAND} -v -V -C${AVR_AVRDUDE_CONFIG} -c${ARDUINO_PROGRAMMER_TYPE} -p${MCU} -P${ARDUINO_PROGRAMMER_COM_ID} -b${ARDUINO_PROGRAMMER_BAUD} -U flash:w:${PRODUCT_NAME}.hex DEPENDS avr_create_hex)
set_target_properties(upload_to_arduino PROPERTIES EXCLUDE_FROM_ALL TRUE)
# Clean extra files
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PRODUCT_NAME}.hex;${PRODUCT_NAME}.eeprom;${PRODUCT_NAME}.lst")
add_subdirectory("../lib/arduino_libs/ArduinoCore" "${CMAKE_BINARY_DIR}/lib/arduino_libs/ArduinoCore")

It depends on another one for the arduino core library:

ArduinoCore/CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(ArduinoCore VERSION 1.0 LANGUAGES CXX)
# Set the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(THIS_LIBRARY_HOME "${ARDUINO_CORES_HOME}/arduino/")
file(GLOB SRC_FILES "${THIS_LIBRARY_HOME}/*.cpp" "${THIS_LIBRARY_HOME}/*.c")
# Add the executable
add_library(${PROJECT_NAME} ${SRC_FILES})
# Include directories
target_include_directories(${PROJECT_NAME} PUBLIC ${THIS_LIBRARY_HOME})
# include pin definitions
if(ARDUINO_BOARD STREQUAL "UNO")
 set(PIN_HEADERS "${ARDUINO_AVR_DIRECTORY}/variants/standard/")
else()
 message(FATAL_ERROR "Unsupported ARDUINO_BOARD value: ${ARDUINO_BOARD}")
endif()
target_include_directories(${PROJECT_NAME} INTERFACE ${PIN_HEADERS})
target_include_directories(${PROJECT_NAME} PRIVATE ${PIN_HEADERS})
unset(THIS_LIBRARY_HOME)
unset(SRC_FILES)

I think I am using wrong compile flags and that somehow causes arduino core size to explode when this function is called. Even if I delete all of my code and leave this simple test main.cpp, the problem is there:

#include "Arduino.h"
void setup() {
 // initialize serial:
 Serial.begin(9600);
}
uint8_t bytes[10];
int i = 0;
void loop() {
 if (Serial.available() >= 10) {
 Serial.readBytes(&bytes[0], 10);
 i = 10;
 }
 if(i >= 10) {
 i = 0;
 for(int iout = 0; iout < 10; ++iout) {
 Serial.write(bytes[i]);
 }
 }
}

Output of the avr-size:

[3/5] avr-size -A --mcu=atmega328p connections_display.elf
connections_display.elf :
section size addr
.data 52 8388864
.text 15354 0
.bss 185 8388916
.comment 17 0
.note.gnu.avr.deviceinfo 64 0
Total 15672
[4/5] avr-size -C --mcu=atmega328p connections_display.elf
AVR Memory Usage
----------------
Device: atmega328p
Program: 15406 bytes (47.0% Full)
(.text + .data + .bootloader)
Data: 237 bytes (11.6% Full)
(.data + .bss + .noinit)
asked Mar 7 at 15:53

1 Answer 1

3

The problem was that this is not how to pass linker flags correctly. The -Wl part of add_compile_options was not passed to linker.

Instead, I had to expand the CMAKE_EXE_LINKER_FLAGS:

set(CMAKE_EXE_LINKER_FLAGS
 "-mmcu=${MCU} -Wl,--relax,--gc-sections,-Os,-g,--strip-discarded,--stats"
)

Now I got the same size as with Arduino IDE.

answered Mar 7 at 16:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.