Last active
May 9, 2025 23:36
-
-
Save JuanM04/dc843ba1e2ac0e29775aff6701dc7c1e to your computer and use it in GitHub Desktop.
Configuración de CMake para AVR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################## | |
# Configuración de CMake para proyectos de AVR | |
# Intenta emular el comportamiento de Microchip Studio | |
# | |
# Referencias: | |
# https://www.kuon.ch/post/2018-07-11-avr-cmake/ | |
# https://github.com/mkleemann/cmake-avr/tree/642828d406e76a875ed2227309f3bf962fa7feaf | |
# | |
# Inicialzación de CMake: | |
# - Para crear una salida de debug: | |
# mkdir Debug && cd Debug | |
# cmake -DCMAKE_BUILD_TYPE=Debug -DAVR_PATH=ruta/a/avr -DAVRDUDE_PATH=ruta/a/avrdude .. | |
# - Para crear una salida de release: | |
# mkdir Release && cd Release | |
# cmake -DCMAKE_BUILD_TYPE=Release -DAVR_PATH=ruta/a/avr -DAVRDUDE_PATH=ruta/a/avrdude .. | |
# | |
# Luego, dentro de la carpeta Debug o Release: | |
# - Para compilar el proyecto: | |
# cmake --build . --target all | |
# - Para limpiar la salida: | |
# cmake --build . --target clean | |
# - Para subir el programa al microcontrolador: | |
# cmake -DAVRDUDE_PORT=COM4 .. # setear el puerto de conexión | |
# cmake --build . --target upload # o upload_eeprom | |
# | |
################################################################################## | |
cmake_minimum_required(VERSION 3.30) | |
### TOOLCHAIN SETUP ###################################################### | |
# Configuración de la toolchain para AVR. | |
# Se puede descargar desde la página de Microchip o utilizar la que viene | |
# con Microchip Studio. | |
# | |
# https://www.microchip.com/en-us/tools-resources/develop/microchip-studio/gcc-compilers | |
# | |
# Importante: esto debe ser configurado antes de ejecutar `project()` | |
# https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#method-3-avoid-use-set | |
########################################################################## | |
if(NOT DEFINED AVR_PATH) | |
message(FATAL_ERROR "Definí la ubicación de la toolchain de AVR en AVR_PATH.") | |
endif() | |
set(CMAKE_FIND_ROOT_PATH ${AVR_PATH}) | |
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | |
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) | |
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) | |
# No se agregan automáticamente, ya que más adelante | |
# se configura CMAKE_SYSTEM_NAME como Generic | |
set(CMAKE_SYSTEM_INCLUDE_PATH "${CMAKE_FIND_ROOT_PATH}/include") | |
set(CMAKE_SYSTEM_LIBRARY_PATH "${CMAKE_FIND_ROOT_PATH}/lib") | |
find_program(AVR_CC "${AVR_PATH}/bin/avr-gcc" REQUIRED) | |
find_program(AVR_CXX "${AVR_PATH}/bin/avr-g++" REQUIRED) | |
find_program(AVR_OBJCOPY "${AVR_PATH}/bin/avr-objcopy" REQUIRED) | |
find_program(AVR_SIZE_TOOL "${AVR_PATH}/bin/avr-size" REQUIRED) | |
find_program(AVR_OBJDUMP "${AVR_PATH}/bin/avr-objdump" REQUIRED) | |
########################################################################## | |
# También se recomienda instalar avrdude | |
# Se puede descargar desde https://github.com/avrdudes/avrdude/releases | |
########################################################################## | |
find_program(AVRDUDE avrdude PATHS "${AVRDUDE_PATH}") | |
########################################################################## | |
# Indicarle a CMake que va a compilar para AVR | |
########################################################################## | |
set(CMAKE_SYSTEM_NAME Generic) | |
set(CMAKE_SYSTEM_PROCESSOR avr) | |
set(CMAKE_C_COMPILER ${AVR_CC}) | |
set(CMAKE_CXX_COMPILER ${AVR_CXX}) | |
### CONFIGURACIÓN GENERAL ################################################ | |
# Configuración del proyecto, variables externas y otras opciones | |
# genéricas para cambiar de proyecto a proyecto. | |
########################################################################## | |
project(nombre-del-proyecto) | |
set(MCU atmega328p) # Microcontrolador utilizado | |
# Por defecto, CMAKE_BUILD_TYPE es Debug | |
if(NOT CMAKE_BUILD_TYPE) | |
set(CMAKE_BUILD_TYPE Debug) | |
endif() | |
### MENSAJES DE INFORMACIÓN ############################################## | |
# Mensajes sobre la configuración de CMake | |
########################################################################## | |
execute_process(COMMAND ${AVR_CC} -dumpversion | |
OUTPUT_VARIABLE AVR_CC_VERSION | |
OUTPUT_STRIP_TRAILING_WHITESPACE) | |
message(STATUS "====================================================") | |
message(STATUS "${PROJECT_NAME} (${CMAKE_BUILD_TYPE})") | |
message(STATUS "Versión de CMake : ${CMAKE_VERSION}") | |
message(STATUS "Versión de avr-gcc : ${AVR_CC_VERSION}") | |
message(STATUS "====================================================") | |
### CONFIGURACIÓN DE SALIDA ############################################## | |
# Opciones de compilación y enlazado, emulando el comportamiento de | |
# Microchip Studio. | |
########################################################################## | |
## Opciones de compilación | |
add_compile_options( | |
-x c # tratar todos los archivos como código C | |
-std=gnu99 # usar el estándar GNU99 | |
-Wall # mostrar todas las advertencias | |
) | |
## Usar tipos de datos cortos (8 bits) | |
add_compile_options( | |
-funsigned-char # tratar char como sin signo | |
-funsigned-bitfields # tratar los bitfields como sin signo | |
-fpack-struct # empaquetar estructuras | |
-fshort-enums # crear enums con la menor cantidad de bytes posible | |
) | |
## Separar los archivos objeto por función | |
add_compile_options( | |
-ffunction-sections # separar las funciones en secciones | |
-fdata-sections # separar los datos en secciones | |
) | |
if(CMAKE_BUILD_TYPE MATCHES Release) | |
add_definitions(-DNDEBUG) | |
add_compile_options(-Os) # optimizar para tamaño (no velocidad) | |
else() | |
add_definitions(-DEBUG) | |
add_compile_options(-Og) # optimizar para debugging | |
add_compile_options(-g2) # incluir información de depuración nivel 2 | |
endif() | |
## Opciones de enlazado | |
add_link_options( | |
-Wl,--start-group # declarar librerías a enlazar | |
-Wl,-lm # enlazar math | |
-Wl,--end-group # fin de la declaración | |
-Wl,--gc-sections # eliminar secciones no utilizadas | |
) | |
### SALIDAS ############################################################## | |
# Declaración de archivos fuente y de salida | |
########################################################################## | |
file(GLOB SRC_FILES "*.c") | |
## .map | |
set(map_file "${PROJECT_NAME}.map") | |
set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES "${map_file}") | |
## .elf | |
set(elf_file "${PROJECT_NAME}.elf") | |
add_executable(${elf_file} ${SRC_FILES}) | |
set_target_properties( | |
${elf_file} PROPERTIES | |
COMPILE_FLAGS "-mmcu=${MCU}" | |
LINK_FLAGS "-mmcu=${MCU} -Wl,-Map=${map_file}" | |
) | |
## .hex | |
set(hex_file "${PROJECT_NAME}.hex") | |
add_custom_command( | |
OUTPUT ${hex_file} | |
COMMAND ${AVR_OBJCOPY} -R.eeprom -R.fuse -R.lock -R.signature -R.user_signatures -Oihex ${elf_file} ${hex_file} | |
COMMAND ${AVR_SIZE_TOOL} -C --mcu=${MCU} ${elf_file} | |
DEPENDS ${elf_file} | |
) | |
## .eep | |
set(eeprom_image "${PROJECT_NAME}.eep") | |
add_custom_command( | |
OUTPUT ${eeprom_image} | |
COMMAND ${AVR_OBJCOPY} -j.eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma=.eeprom=0 --no-change-warnings -Oihex ${elf_file} ${eeprom_image} | |
DEPENDS ${elf_file} | |
) | |
## .lss | |
set(listing_file "${PROJECT_NAME}.lss") | |
add_custom_command( | |
OUTPUT ${listing_file} | |
COMMAND ${AVR_OBJDUMP} -h -S ${elf_file} > ${listing_file} | |
DEPENDS ${elf_file} | |
) | |
## Generar .hex, .eep y .lss al compilar por defecto | |
add_custom_target( | |
"${PROJECT_NAME}" ALL | |
DEPENDS ${hex_file} ${eeprom_image} ${listing_file} | |
) | |
set_target_properties( | |
"${PROJECT_NAME}" PROPERTIES | |
OUTPUT_NAME "${elf_file}" | |
) | |
### AVRDUDE ############################################################# | |
# Targets para subir el programa al microcontrolador | |
########################################################################## | |
if(DEFINED AVRDUDE) | |
## Tipo de programador | |
if(NOT AVRDUDE_PROGRAMMER) | |
set(AVRDUDE_PROGRAMMER arduino CACHE STRING "Programador de avrdude: arduino") | |
endif() | |
## Puerto de conexión | |
if(NOT AVRDUDE_PORT) | |
set(AVRDUDE_PORT usb CACHE STRING "Puerto de conexión: usb") | |
endif() | |
## Baud rate | |
if(NOT AVRDUDE_BAUD) | |
set(AVRDUDE_BAUD 115200 CACHE STRING "Baud rate: 115200") | |
endif() | |
## Subir .hex | |
add_custom_target( | |
upload | |
${AVRDUDE} -p ${MCU} -c ${AVRDUDE_PROGRAMMER} -P ${AVRDUDE_PORT} -b ${AVRDUDE_BAUD} -U flash:w:"${hex_file}":i | |
DEPENDS ${hex_file} | |
COMMENT "Subierndo ${hex_file} a ${MCU} utilizando ${AVRDUDE_PROGRAMMER}" | |
) | |
## Subir .eep | |
add_custom_target( | |
upload_eeprom | |
${AVRDUDE} -p ${MCU} -c ${AVRDUDE_PROGRAMMER} -P ${AVRDUDE_PORT} -b ${AVRDUDE_BAUD} -U eeprom:w:"${eeprom_image}":i | |
DEPENDS ${eeprom_image} | |
COMMENT "Subierndo ${eeprom_image} a ${MCU} utilizando ${AVRDUDE_PROGRAMMER}" | |
) | |
endif() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment