From 522fb41290d24ccc0f2e2ea6bc75ffc0aa1449e5 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Mon, 21 Aug 2023 20:06:30 -0400 Subject: [PATCH] Switch to CMake --- .gitignore | 1 + .vscode/c_cpp_properties.json | 18 +- CMakeLists.txt | 57 +++++ CMakePresets.json | 15 ++ cmake/avr-gcc-toolchain.cmake | 410 ++++++++++++++++++++++++++++++++++ 5 files changed, 484 insertions(+), 17 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 CMakePresets.json create mode 100644 cmake/avr-gcc-toolchain.cmake diff --git a/.gitignore b/.gitignore index a39790f..a968c23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o *.elf *.hex +build/ \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index cec5e40..fc21100 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,32 +1,16 @@ { "configurations": [ - { - "name": "Win32", - "includePath": [ - "${workspaceFolder}/**", - "${APPDATA}\\..\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\avr\\include\\**" - ], - "defines": [], - "windowsSdkVersion": "8.1", - "compilerPath": "${APPDATA}\\..\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\bin\\avr-gcc.exe", - "cStandard": "c17", - "cppStandard": "c++17", - "intelliSenseMode": "${default}", - "compilerArgs": [], - "configurationProvider": "ms-vscode.makefile-tools" - }, { "name": "Linux", "includePath": [ "${workspaceFolder}/**" ], "defines": [], - "compilerPath": "/usr/local/bin/avr-gcc", "cStandard": "c17", "cppStandard": "c++17", "intelliSenseMode": "${default}", "compilerArgs": [], - "configurationProvider": "ms-vscode.makefile-tools" + "configurationProvider": "ms-vscode.cmake-tools" } ], "version": 4 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..412bf5d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.24) + +set(WITH_MCU OFF) +set(AVR_MCU "attiny3216") + +set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/avr-gcc-toolchain.cmake") + +project(avr-avc-lan VERSION 1 LANGUAGES C ASM) + +include(FetchContent) +# attiny_atpack_SOURCE_DIR is downloaded/extracted location +FetchContent_Declare( + attiny_atpack + URL http://packs.download.atmel.com/Atmel.ATtiny_DFP.2.0.368.atpack + URL_HASH SHA512=ee16a8ebecb57bd998a9cd4373368e3d45982cbbc3825e18d1dcac58215db6b9d907ad1ba2020cba9187fed7ba8c6f255a4fa1214e40c7a17ab2d18474f4d079 + DOWNLOAD_NAME Atmel.ATtiny_DFP.2.0.368.atpack.zip +) +FetchContent_MakeAvailable(attiny_atpack) + +set(CMAKE_C_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +if(CMAKE_BUILD_TYPE MATCHES Release) + set(CMAKE_C_FLAGS_RELEASE "-Os") +endif(CMAKE_BUILD_TYPE MATCHES Release) + +if(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) + set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -save-temps -g -gdwarf-3 -gstrict-dwarf") +endif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) + +if(CMAKE_BUILD_TYPE MATCHES Debug) + set(CMAKE_C_FLAGS_DEBUG "-O0 -save-temps -g -gdwarf-3 -gstrict-dwarf") +endif(CMAKE_BUILD_TYPE MATCHES Debug) + +add_avr_executable(sniffer + src/sniffer.c + src/com232.c + src/avclandrv.c + src/GlobalDef.c) + +target_include_directories(sniffer SYSTEM PUBLIC "${attiny_atpack_SOURCE_DIR}/include") +target_link_options(sniffer PUBLIC + -B "${attiny_atpack_SOURCE_DIR}/gcc/dev/${AVR_MCU}" +) +target_compile_definitions(sniffer PRIVATE + F_CPU=16000000L +) +target_compile_options(sniffer PRIVATE + -B "${attiny_atpack_SOURCE_DIR}/gcc/dev/${AVR_MCU}" + --param=min-pagesize=0 + -ffunction-sections + -fdata-sections + -fshort-enums +) + + + diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..759f198 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,15 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "main", + "displayName": "Default", + "description": "Sets Ninja generator, build and install directory", + "generator": "Unix Makefiles", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + } + ] +} \ No newline at end of file diff --git a/cmake/avr-gcc-toolchain.cmake b/cmake/avr-gcc-toolchain.cmake new file mode 100644 index 0000000..aacf56e --- /dev/null +++ b/cmake/avr-gcc-toolchain.cmake @@ -0,0 +1,410 @@ +########################################################################## +# "THE ANY BEVERAGE-WARE LICENSE" (Revision 42 - based on beer-ware +# license): +# wrote this file. As long as you retain this notice +# you can do whatever you want with this stuff. If we meet some day, and +# you think this stuff is worth it, you can buy me a be(ve)er(age) in +# return. (I don't like beer much.) +# +# Matthias Kleemann +########################################################################## + +########################################################################## +# The toolchain requires some variables set. +# +# AVR_MCU (default: atmega8) +# the type of AVR the application is built for +# AVR_L_FUSE (NO DEFAULT) +# the LOW fuse value for the MCU used +# AVR_H_FUSE (NO DEFAULT) +# the HIGH fuse value for the MCU used +# AVR_UPLOADTOOL (default: avrdude) +# the application used to upload to the MCU +# NOTE: The toolchain is currently quite specific about +# the commands used, so it needs tweaking. +# AVR_UPLOADTOOL_PORT (default: usb) +# the port used for the upload tool, e.g. usb +# AVR_PROGRAMMER (default: avrispmkII) +# the programmer hardware used, e.g. avrispmkII +########################################################################## + +########################################################################## +# options +########################################################################## +option(WITH_MCU "Add the mCU type to the target file name." ON) + +########################################################################## +# executables in use +########################################################################## +find_program(AVR_CC avr-gcc REQUIRED) +find_program(AVR_CXX avr-g++ REQUIRED) +find_program(AVR_OBJCOPY avr-objcopy REQUIRED) +find_program(AVR_SIZE_TOOL avr-size REQUIRED) +find_program(AVR_OBJDUMP avr-objdump REQUIRED) + +########################################################################## +# toolchain starts with defining mandatory variables +########################################################################## +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR avr) +set(CMAKE_C_COMPILER ${AVR_CC}) +set(CMAKE_CXX_COMPILER ${AVR_CXX}) + +########################################################################## +# Identification +########################################################################## +set(AVR 1) + +########################################################################## +# some necessary tools and variables for AVR builds, which may not +# defined yet +# - AVR_UPLOADTOOL +# - AVR_UPLOADTOOL_PORT +# - AVR_PROGRAMMER +# - AVR_MCU +# - AVR_SIZE_ARGS +########################################################################## + +# default upload tool +if(NOT AVR_UPLOADTOOL) + set( + AVR_UPLOADTOOL avrdude + CACHE STRING "Set default upload tool: avrdude" + ) + find_program(AVR_UPLOADTOOL avrdude) +endif(NOT AVR_UPLOADTOOL) + +# default upload tool port +if(NOT AVR_UPLOADTOOL_PORT) + set( + AVR_UPLOADTOOL_PORT usb + CACHE STRING "Set default upload tool port: usb" + ) +endif(NOT AVR_UPLOADTOOL_PORT) + +# default programmer (hardware) +if(NOT AVR_PROGRAMMER) + set( + AVR_PROGRAMMER avrispmkII + CACHE STRING "Set default programmer hardware model: avrispmkII" + ) +endif(NOT AVR_PROGRAMMER) + +# default MCU (chip) +if(NOT AVR_MCU) + set( + AVR_MCU atmega8 + CACHE STRING "Set default MCU: atmega8 (see 'avr-gcc --target-help' for valid values)" + ) +endif(NOT AVR_MCU) + +#default avr-size args +if(NOT AVR_SIZE_ARGS) + if(APPLE) + set(AVR_SIZE_ARGS -B) + else(APPLE) + set(AVR_SIZE_ARGS -C;--mcu=${AVR_MCU}) + endif(APPLE) +endif(NOT AVR_SIZE_ARGS) + +# prepare base flags for upload tool +set(AVR_UPLOADTOOL_BASE_OPTIONS -p ${AVR_MCU} -c ${AVR_PROGRAMMER}) + +# use AVR_UPLOADTOOL_BAUDRATE as baudrate for upload tool (if defined) +if(AVR_UPLOADTOOL_BAUDRATE) + set(AVR_UPLOADTOOL_BASE_OPTIONS ${AVR_UPLOADTOOL_BASE_OPTIONS} -b ${AVR_UPLOADTOOL_BAUDRATE}) +endif() + +########################################################################## +# check build types: +# - Debug +# - Release +# - RelWithDebInfo +# +# Release is chosen, because of some optimized functions in the +# AVR toolchain, e.g. _delay_ms(). +########################################################################## +if(NOT ((CMAKE_BUILD_TYPE MATCHES Release) OR +(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) OR +(CMAKE_BUILD_TYPE MATCHES Debug) OR +(CMAKE_BUILD_TYPE MATCHES MinSizeRel))) + set( + CMAKE_BUILD_TYPE Release + CACHE STRING "Choose cmake build type: Debug Release RelWithDebInfo MinSizeRel" + FORCE + ) +endif(NOT ((CMAKE_BUILD_TYPE MATCHES Release) OR +(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) OR +(CMAKE_BUILD_TYPE MATCHES Debug) OR +(CMAKE_BUILD_TYPE MATCHES MinSizeRel))) + + + +########################################################################## + +########################################################################## +# target file name add-on +########################################################################## +if(WITH_MCU) + set(MCU_TYPE_FOR_FILENAME "-${AVR_MCU}") +else(WITH_MCU) + set(MCU_TYPE_FOR_FILENAME "") +endif(WITH_MCU) + +########################################################################## +# add_avr_executable +# - IN_VAR: EXECUTABLE_NAME +# +# Creates targets and dependencies for AVR toolchain, building an +# executable. Calls add_executable with ELF file as target name, so +# any link dependencies need to be using that target, e.g. for +# target_link_libraries(-${AVR_MCU}.elf ...). +########################################################################## +function(add_avr_executable EXECUTABLE_NAME) + + if(NOT ARGN) + message(FATAL_ERROR "No source files given for ${EXECUTABLE_NAME}.") + endif(NOT ARGN) + + # set file names + set(elf_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.elf) + set(hex_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.hex) + set(lst_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.lst) + set(map_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.map) + set(eeprom_image ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}-eeprom.hex) + + set (${EXECUTABLE_NAME}_ELF_TARGET ${elf_file} PARENT_SCOPE) + set (${EXECUTABLE_NAME}_HEX_TARGET ${hex_file} PARENT_SCOPE) + set (${EXECUTABLE_NAME}_LST_TARGET ${lst_file} PARENT_SCOPE) + set (${EXECUTABLE_NAME}_MAP_TARGET ${map_file} PARENT_SCOPE) + set (${EXECUTABLE_NAME}_EEPROM_TARGET ${eeprom_file} PARENT_SCOPE) + # elf file + add_executable(${EXECUTABLE_NAME} ${ARGN}) + + set_target_properties( + ${EXECUTABLE_NAME} + PROPERTIES + COMPILE_FLAGS "-mmcu=${AVR_MCU}" + LINK_FLAGS "-mmcu=${AVR_MCU} -Wl,--gc-sections -mrelax -Wl,-Map,${map_file}" + ) + + add_custom_command( + OUTPUT ${hex_file} + COMMAND + ${AVR_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file} + COMMAND + ${AVR_SIZE_TOOL} ${AVR_SIZE_ARGS} ${elf_file} + DEPENDS ${EXECUTABLE_NAME} + ) + + add_custom_command( + OUTPUT ${lst_file} + COMMAND + ${AVR_OBJDUMP} -d ${elf_file} > ${lst_file} + DEPENDS ${EXECUTABLE_NAME} + ) + + # eeprom + 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 + -O ihex ${elf_file} ${eeprom_image} + DEPENDS ${EXECUTABLE_NAME} + ) + + # clean + get_directory_property(clean_files ADDITIONAL_MAKE_CLEAN_FILES) + set_directory_properties( + PROPERTIES + ADDITIONAL_MAKE_CLEAN_FILES "${map_file}" + ) + + # upload - with avrdude + add_custom_target( + upload_${EXECUTABLE_NAME} + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} ${AVR_UPLOADTOOL_OPTIONS} + -U flash:w:${hex_file} + -P ${AVR_UPLOADTOOL_PORT} + DEPENDS ${hex_file} + COMMENT "Uploading ${hex_file} to ${AVR_MCU} using ${AVR_PROGRAMMER}" + ) + + # upload eeprom only - with avrdude + # see also bug http://savannah.nongnu.org/bugs/?40142 + add_custom_target( + upload_${EXECUTABLE_NAME}_eeprom + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} ${AVR_UPLOADTOOL_OPTIONS} + -U eeprom:w:${eeprom_image} + -P ${AVR_UPLOADTOOL_PORT} + DEPENDS ${eeprom_image} + COMMENT "Uploading ${eeprom_image} to ${AVR_MCU} using ${AVR_PROGRAMMER}" + ) + + # disassemble + add_custom_target( + disassemble_${EXECUTABLE_NAME} + ${AVR_OBJDUMP} -h -S ${elf_file} > ${EXECUTABLE_NAME}.lst + DEPENDS ${EXECUTABLE_NAME} + ) +endfunction(add_avr_executable) + + +########################################################################## +# add_avr_library +# - IN_VAR: LIBRARY_NAME +# +# Calls add_library with an optionally concatenated name +# ${MCU_TYPE_FOR_FILENAME}. +# This needs to be used for linking against the library, e.g. calling +# target_link_libraries(...). +########################################################################## +function(add_avr_library LIBRARY_NAME) + if(NOT ARGN) + message(FATAL_ERROR "No source files given for ${LIBRARY_NAME}.") + endif(NOT ARGN) + + set(lib_file ${LIBRARY_NAME}${MCU_TYPE_FOR_FILENAME}) + set (${LIBRARY_NAME}_LIB_TARGET ${elf_file} PARENT_SCOPE) + + add_library(${lib_file} STATIC ${ARGN}) + + set_target_properties( + ${lib_file} + PROPERTIES + COMPILE_FLAGS "-mmcu=${AVR_MCU}" + OUTPUT_NAME "${lib_file}" + ) + + if(NOT TARGET ${LIBRARY_NAME}) + add_custom_target( + ${LIBRARY_NAME} + ALL + DEPENDS ${lib_file} + ) + + set_target_properties( + ${LIBRARY_NAME} + PROPERTIES + OUTPUT_NAME "${lib_file}" + ) + endif(NOT TARGET ${LIBRARY_NAME}) + +endfunction(add_avr_library) + +########################################################################## +# avr_target_link_libraries +# - IN_VAR: EXECUTABLE_TARGET +# - ARGN : targets and files to link to +# +# Calls target_link_libraries with AVR target names (concatenation, +# extensions and so on. +########################################################################## +function(avr_target_link_libraries EXECUTABLE_TARGET) + if(NOT ARGN) + message(FATAL_ERROR "Nothing to link to ${EXECUTABLE_TARGET}.") + endif(NOT ARGN) + + get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME) + + foreach(TGT ${ARGN}) + if(TARGET ${TGT}) + get_target_property(ARG_NAME ${TGT} OUTPUT_NAME) + list(APPEND NON_TARGET_LIST ${ARG_NAME}) + else(TARGET ${TGT}) + list(APPEND NON_TARGET_LIST ${TGT}) + endif(TARGET ${TGT}) + endforeach(TGT ${ARGN}) + + target_link_libraries(${TARGET_LIST} ${NON_TARGET_LIST}) +endfunction(avr_target_link_libraries EXECUTABLE_TARGET) + +########################################################################## +# avr_target_include_directories +# +# Calls target_include_directories with AVR target names +########################################################################## + +function(avr_target_include_directories EXECUTABLE_TARGET) + if(NOT ARGN) + message(FATAL_ERROR "No include directories to add to ${EXECUTABLE_TARGET}.") + endif() + + get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME) + set(extra_args ${ARGN}) + + target_include_directories(${TARGET_LIST} ${extra_args}) +endfunction() + +########################################################################## +# avr_target_compile_definitions +# +# Calls target_compile_definitions with AVR target names +########################################################################## + +function(avr_target_compile_definitions EXECUTABLE_TARGET) + if(NOT ARGN) + message(FATAL_ERROR "No compile definitions to add to ${EXECUTABLE_TARGET}.") + endif() + + get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME) + set(extra_args ${ARGN}) + + target_compile_definitions(${TARGET_LIST} ${extra_args}) +endfunction() + +function(avr_generate_fixed_targets) + # get status + add_custom_target( + get_status + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} -n -v + COMMENT "Get status from ${AVR_MCU}" + ) + + # get fuses + add_custom_target( + get_fuses + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} -n + -U lfuse:r:-:b + -U hfuse:r:-:b + COMMENT "Get fuses from ${AVR_MCU}" + ) + + # set fuses + add_custom_target( + set_fuses + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} + -U lfuse:w:${AVR_L_FUSE}:m + -U hfuse:w:${AVR_H_FUSE}:m + COMMENT "Setup: High Fuse: ${AVR_H_FUSE} Low Fuse: ${AVR_L_FUSE}" + ) + + # get oscillator calibration + add_custom_target( + get_calibration + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} + -U calibration:r:${AVR_MCU}_calib.tmp:r + COMMENT "Write calibration status of internal oscillator to ${AVR_MCU}_calib.tmp." + ) + + # set oscillator calibration + add_custom_target( + set_calibration + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} + -U calibration:w:${AVR_MCU}_calib.hex + COMMENT "Program calibration status of internal oscillator from ${AVR_MCU}_calib.hex." + ) +endfunction() + +########################################################################## +# Bypass the link step in CMake's "compiler sanity test" check +# +# CMake throws in a try_compile() target test in some generators, but does +# not know that this is a cross compiler so the executable can't link. +# Change the target type: +# +# https://stackoverflow.com/q/53633705 +########################################################################## + +set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")