380540635c
* Refactored BACnetShedLevel encoding, decoding, and printing into separate file. Added unit testing. * Added API to load control object for shed-level, start-time, duty-window, full-duty-baseline, and enable. * Fixed bacapp sprintf for shed level and host-n-port found in scan build.
367 lines
12 KiB
CMake
367 lines
12 KiB
CMake
# This is a CMake example for STM32F429ZI hardware on Nucleof429zi board
|
|
# using the ARM GCC compiler and STM32F4xx_StdPeriph_Driver library.
|
|
#
|
|
# Board Nucleof429zi
|
|
# MCU STM32F429ZI
|
|
# CPU Cortex-M4
|
|
# Clock 180MHz
|
|
# RAM 256Kb
|
|
# Flash 2Mb
|
|
#
|
|
# To build this project you need to install:
|
|
# - ARM GCC compiler
|
|
# - CMake
|
|
#
|
|
# To build this project you need to run:
|
|
# - cmake -S . -B build
|
|
# - cmake --build build
|
|
#
|
|
# To flash this project you need to run:
|
|
# - st-flash write build/bacnet-mstp.hex 0x8000000
|
|
#
|
|
# To debug this project you need to run:
|
|
# - arm-none-eabi-gdb -q build/bacnet-mstp.out
|
|
# - (gdb) target extended-remote localhost:3333
|
|
# - (gdb) monitor reset halt
|
|
# - (gdb) load
|
|
# - (gdb) monitor reset halt
|
|
# - (gdb) monitor reset init
|
|
# - (gdb) monitor reset run
|
|
# - (gdb) monitor reset exit
|
|
# - (gdb) quit
|
|
#
|
|
# You can also use VSCode with Cortex-Debug extension
|
|
#
|
|
# This example was tested with:
|
|
# - ARM GCC 10.3.1
|
|
# - CMake 3.22.1
|
|
# - STM32F4xx_StdPeriph_Driver V1.0.0
|
|
# - BACnet Stack V1.3.2
|
|
#
|
|
cmake_minimum_required(VERSION 3.20)
|
|
|
|
# Cross compilers and tools
|
|
set(CMAKE_SYSTEM_NAME Generic)
|
|
set(CMAKE_SYSTEM_VERSION 1)
|
|
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
|
|
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
|
|
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
|
|
set(CMAKE_AR arm-none-eabi-ar)
|
|
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
|
|
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
|
|
set(CMAKE_SIZE arm-none-eabi-size)
|
|
set(CMAKE_NM arm-none-eabi-nm)
|
|
set(CMAKE_GDB gdb-multiarch)
|
|
set(CMAKE_OPENOCD openocd)
|
|
set(CMAKE_CSTACK "${CMAKE_SOURCE_DIR}/../../tools/check-stack-usage/checkStackUsage.py")
|
|
set(CMAKE_MEMAP "${CMAKE_SOURCE_DIR}/../../tools/memap/memap.py")
|
|
|
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
|
set(EXECUTABLE ${PROJECT_NAME}.elf)
|
|
|
|
project(bacnet-mstp)
|
|
|
|
enable_language(C ASM)
|
|
set(CMAKE_C_STANDARD 11)
|
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
|
set(CMAKE_C_EXTENSIONS ON)
|
|
|
|
# Specific ARM microcontroller compiler and linker settings
|
|
add_compile_options(-mcpu=cortex-m4)
|
|
add_compile_options(-mthumb -mthumb-interwork)
|
|
add_compile_options(-ffunction-sections -fdata-sections)
|
|
add_compile_options(-fno-common -fmessage-length=0)
|
|
add_compile_options(-fstack-usage -fdump-rtl-dfinish)
|
|
add_link_options(-mcpu=cortex-m4)
|
|
add_link_options(-mthumb -mthumb-interwork)
|
|
add_link_options(-Wl,-gc-sections,--print-memory-usage)
|
|
|
|
# Enable hardware FPU
|
|
add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
|
|
add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
|
|
add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING)
|
|
|
|
# Build types
|
|
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
|
message(STATUS "Maximum optimization for speed")
|
|
add_compile_options(-Ofast)
|
|
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
|
|
message(STATUS "Maximum optimization for speed, debug info included")
|
|
add_compile_options(-Ofast -g)
|
|
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
|
|
message(STATUS "Maximum optimization for size")
|
|
add_compile_options(-Os)
|
|
else ()
|
|
message(STATUS "Minimal optimization, debug info included")
|
|
add_compile_definitions(DEBUG)
|
|
add_compile_options(-Og -g3)
|
|
endif ()
|
|
|
|
# eliminate the deprecated function warnings
|
|
option(BACNET_STACK_DEPRECATED_DISABLE "Disable deprecation compile warnings" ON)
|
|
if(BACNET_STACK_DEPRECATED_DISABLE)
|
|
add_definitions(-DBACNET_STACK_DEPRECATED_DISABLE)
|
|
endif()
|
|
|
|
set(LIBRARY_BACNET_INC "${CMAKE_SOURCE_DIR}/../../src")
|
|
set(LIBRARY_BACNET_CORE "${CMAKE_SOURCE_DIR}/../../src/bacnet")
|
|
set(LIBRARY_BACNET_BASIC "${CMAKE_SOURCE_DIR}/../../src/bacnet/basic")
|
|
set(LIBRARY_STM32_SRC "${CMAKE_SOURCE_DIR}/external/STM32F4xx_StdPeriph_Driver/src")
|
|
set(LIBRARY_STM32_INC "${CMAKE_SOURCE_DIR}/external/STM32F4xx_StdPeriph_Driver/inc")
|
|
set(LIBRARY_CMSIS_INC "${CMAKE_SOURCE_DIR}/external/CMSIS")
|
|
set(LIBRARY_CMSIS_GCC_INC "${CMAKE_SOURCE_DIR}/external/CMSIS/gcc_ride7")
|
|
|
|
set(BACNET_PROJECT_SOURCE
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_adc.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_can.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_crc.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_dac.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_dbgmcu.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_dcmi.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_dma.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_exti.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_flash.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_fsmc.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_gpio.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_i2c.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_iwdg.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_misc.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_pwr.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_rcc.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_rng.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_rtc.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_sdio.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_spi.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_syscfg.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_tim.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_usart.c
|
|
${LIBRARY_STM32_SRC}/stm32f4xx_wwdg.c
|
|
${LIBRARY_STM32_SRC}/syscalls.c
|
|
|
|
${CMAKE_SOURCE_DIR}/stm32f4xx_conf.h
|
|
|
|
${CMAKE_SOURCE_DIR}/main.c
|
|
${CMAKE_SOURCE_DIR}/stm32f4xx_it.c
|
|
${CMAKE_SOURCE_DIR}/stm32f4xx_it.h
|
|
${CMAKE_SOURCE_DIR}/system_stm32f4xx.c
|
|
${CMAKE_SOURCE_DIR}/system_stm32f4xx.h
|
|
|
|
${CMAKE_SOURCE_DIR}/bacnet.c
|
|
${CMAKE_SOURCE_DIR}/led.c
|
|
${CMAKE_SOURCE_DIR}/mstimer-init.c
|
|
${CMAKE_SOURCE_DIR}/rs485.c
|
|
|
|
${CMAKE_SOURCE_DIR}/program-ubasic.c
|
|
${CMAKE_SOURCE_DIR}/ubasic-port.c
|
|
|
|
${CMAKE_SOURCE_DIR}/device.c
|
|
${CMAKE_SOURCE_DIR}/netport.c
|
|
|
|
${LIBRARY_BACNET_BASIC}/object/ai.c
|
|
${LIBRARY_BACNET_BASIC}/object/ao.c
|
|
${LIBRARY_BACNET_BASIC}/object/av.c
|
|
${LIBRARY_BACNET_BASIC}/object/bi.c
|
|
${LIBRARY_BACNET_BASIC}/object/bo.c
|
|
${LIBRARY_BACNET_BASIC}/object/bv.c
|
|
${LIBRARY_BACNET_BASIC}/object/ms-input.c
|
|
${LIBRARY_BACNET_BASIC}/object/mso.c
|
|
${LIBRARY_BACNET_BASIC}/object/msv.c
|
|
${LIBRARY_BACNET_BASIC}/object/bacfile.c
|
|
${LIBRARY_BACNET_BASIC}/object/program.c
|
|
${LIBRARY_BACNET_BASIC}/program/ubasic/ubasic.c
|
|
${LIBRARY_BACNET_BASIC}/program/ubasic/tokenizer.c
|
|
|
|
${LIBRARY_BACNET_BASIC}/service/h_dcc.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_apdu.c
|
|
${LIBRARY_BACNET_BASIC}/npdu/h_npdu.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_rd.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_rp.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_rpm.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_ts.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_whohas.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_whois.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_wp.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_noserv.c
|
|
${LIBRARY_BACNET_BASIC}/service/s_iam.c
|
|
${LIBRARY_BACNET_BASIC}/service/s_ihave.c
|
|
${LIBRARY_BACNET_BASIC}/service/h_arf.c
|
|
${LIBRARY_BACNET_BASIC}/tsm/tsm.c
|
|
${LIBRARY_BACNET_BASIC}/sys/bsramfs.c
|
|
${LIBRARY_BACNET_BASIC}/sys/debug.c
|
|
${LIBRARY_BACNET_BASIC}/sys/datetime_mstimer.c
|
|
${LIBRARY_BACNET_BASIC}/sys/days.c
|
|
${LIBRARY_BACNET_BASIC}/sys/dst.c
|
|
${LIBRARY_BACNET_BASIC}/sys/ringbuf.c
|
|
${LIBRARY_BACNET_BASIC}/sys/fifo.c
|
|
${LIBRARY_BACNET_BASIC}/sys/keylist.c
|
|
${LIBRARY_BACNET_BASIC}/sys/mstimer.c
|
|
|
|
${LIBRARY_BACNET_CORE}/abort.c
|
|
${LIBRARY_BACNET_CORE}/arf.c
|
|
${LIBRARY_BACNET_CORE}/bacaction.c
|
|
${LIBRARY_BACNET_CORE}/bacaddr.c
|
|
${LIBRARY_BACNET_CORE}/bacapp.c
|
|
${LIBRARY_BACNET_CORE}/bacdcode.c
|
|
${LIBRARY_BACNET_CORE}/bacdest.c
|
|
${LIBRARY_BACNET_CORE}/bacdevobjpropref.c
|
|
${LIBRARY_BACNET_CORE}/bacerror.c
|
|
${LIBRARY_BACNET_CORE}/bacint.c
|
|
${LIBRARY_BACNET_CORE}/bacreal.c
|
|
${LIBRARY_BACNET_CORE}/bacstr.c
|
|
${LIBRARY_BACNET_CORE}/datalink/cobs.c
|
|
${LIBRARY_BACNET_CORE}/datalink/crc.c
|
|
${LIBRARY_BACNET_CORE}/datalink/dlmstp.c
|
|
${LIBRARY_BACNET_CORE}/datalink/mstp.c
|
|
${LIBRARY_BACNET_CORE}/datalink/mstptext.c
|
|
${LIBRARY_BACNET_CORE}/datetime.c
|
|
${LIBRARY_BACNET_CORE}/dcc.c
|
|
${LIBRARY_BACNET_CORE}/indtext.c
|
|
${LIBRARY_BACNET_CORE}/iam.c
|
|
${LIBRARY_BACNET_CORE}/ihave.c
|
|
${LIBRARY_BACNET_CORE}/hostnport.c
|
|
${LIBRARY_BACNET_CORE}/lighting.c
|
|
${LIBRARY_BACNET_CORE}/memcopy.c
|
|
${LIBRARY_BACNET_CORE}/npdu.c
|
|
${LIBRARY_BACNET_CORE}/proplist.c
|
|
${LIBRARY_BACNET_CORE}/rd.c
|
|
${LIBRARY_BACNET_CORE}/reject.c
|
|
${LIBRARY_BACNET_CORE}/rp.c
|
|
${LIBRARY_BACNET_CORE}/rpm.c
|
|
${LIBRARY_BACNET_CORE}/shed_level.c
|
|
${LIBRARY_BACNET_CORE}/timer_value.c
|
|
${LIBRARY_BACNET_CORE}/timestamp.c
|
|
${LIBRARY_BACNET_CORE}/timesync.c
|
|
${LIBRARY_BACNET_CORE}/weeklyschedule.c
|
|
${LIBRARY_BACNET_CORE}/dailyschedule.c
|
|
${LIBRARY_BACNET_CORE}/calendar_entry.c
|
|
${LIBRARY_BACNET_CORE}/special_event.c
|
|
${LIBRARY_BACNET_CORE}/bactimevalue.c
|
|
${LIBRARY_BACNET_CORE}/whohas.c
|
|
${LIBRARY_BACNET_CORE}/whois.c
|
|
${LIBRARY_BACNET_CORE}/wp.c
|
|
|
|
${LIBRARY_CMSIS_GCC_INC}/startup_stm32f4xx.s
|
|
${LIBRARY_CMSIS_INC}/stm32f4xx.h
|
|
)
|
|
|
|
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/stm32f4xx.ld)
|
|
|
|
set(EXECUTABLE ${PROJECT_NAME}.elf)
|
|
|
|
add_executable(${EXECUTABLE} ${BACNET_PROJECT_SOURCE})
|
|
|
|
target_compile_definitions(${EXECUTABLE} PRIVATE
|
|
-DNDEBUG
|
|
-DUSE_STDPERIPH_DRIVER
|
|
-DSTM32F4XX
|
|
-DBACDL_MSTP
|
|
-DMAX_APDU=480
|
|
-DBIG_ENDIAN=0
|
|
-DMAX_TSM_TRANSACTIONS=1
|
|
-DBACFILE
|
|
-DBACAPP_MINIMAL
|
|
)
|
|
|
|
# inhibit pedantic warnings
|
|
target_compile_options(${EXECUTABLE} PRIVATE
|
|
-Wall -Wextra -pedantic
|
|
-Wfloat-equal -Wconversion -Wredundant-decls
|
|
-Wswitch-default
|
|
# don't warn about conversion, sign, compares, long long and attributes
|
|
# since they are common in embedded
|
|
-Wno-sign-conversion
|
|
-Wno-conversion
|
|
-Wno-sign-compare
|
|
-Wno-long-long
|
|
-Wno-attributes
|
|
# don't warn about implicit fallthrough since it is common in network protocols
|
|
-Wno-implicit-fallthrough
|
|
# the SDK does not meet coding guidelines
|
|
-Wno-comment
|
|
-Wno-missing-braces
|
|
-Wno-unused-variable
|
|
# reference the linker file for CSTACK size
|
|
-Wstack-usage=16384
|
|
-Wno-unused-parameter
|
|
-Wno-char-subscripts
|
|
)
|
|
|
|
target_include_directories(${EXECUTABLE} PRIVATE
|
|
${CMAKE_SOURCE_DIR}
|
|
${LIBRARY_CMSIS_INC}
|
|
${LIBRARY_CMSIS_GCC_INC}
|
|
${LIBRARY_STM32_INC}
|
|
${LIBRARY_BACNET_INC}
|
|
)
|
|
|
|
target_link_options(${EXECUTABLE} PRIVATE
|
|
-T${LINKER_SCRIPT}
|
|
-specs=nano.specs
|
|
-lm
|
|
-lnosys
|
|
-Wl,-Map=${PROJECT_NAME}.map,--cref
|
|
-Wl,--gc-sections
|
|
)
|
|
|
|
# Create hex and bin files
|
|
add_custom_command(TARGET ${EXECUTABLE}
|
|
POST_BUILD
|
|
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin
|
|
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex
|
|
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.hex
|
|
)
|
|
|
|
# Print executable size
|
|
add_custom_command(TARGET ${EXECUTABLE}
|
|
POST_BUILD
|
|
COMMAND ${CMAKE_SIZE} ${EXECUTABLE}
|
|
)
|
|
|
|
# sort the RAM usage by size and place into a file
|
|
add_custom_target(symbols
|
|
DEPENDS ${EXECUTABLE}
|
|
COMMENT "Print memory symbols by size"
|
|
COMMAND ${CMAKE_NM} -t d -S --size-sort ${EXECUTABLE} 1> ${PROJECT_NAME}.nm
|
|
COMMAND echo "RAM usage by size analysis in ${PROJECT_NAME}.nm"
|
|
COMMAND echo "=ADDRESS= ==RAM=== = ==VARIABLE-NAME=="
|
|
COMMAND tail ${PROJECT_NAME}.nm
|
|
)
|
|
|
|
# calculate the worst case CSTACK memory usage by size and place into a file
|
|
add_custom_target(cstack
|
|
DEPENDS ${EXECUTABLE}
|
|
COMMENT "Print CSTACK memory depth by size"
|
|
COMMAND ${CMAKE_CSTACK} ${EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR} 1> ${PROJECT_NAME}.su
|
|
COMMAND echo "C-Stack maxium depth analysis in ${PROJECT_NAME}.su"
|
|
COMMAND echo "==DEPTH== : == Functions called =="
|
|
COMMAND tail ${PROJECT_NAME}.su
|
|
)
|
|
|
|
# Print file and library sizes
|
|
add_custom_target(memmap
|
|
DEPENDS ${PROJECT_NAME}.map
|
|
COMMENT "Print file and library memory usage by size"
|
|
COMMAND ${CMAKE_MEMAP} -t GCC_ARM ${PROJECT_NAME}.map
|
|
)
|
|
|
|
# Run OpenOCD with ST Link to debug
|
|
add_custom_target(openocd
|
|
DEPENDS ${EXECUTABLE}
|
|
COMMENT "OpenOCD GDB Server via ST Link"
|
|
COMMAND ${CMAKE_OPENOCD} -f interface/stlink.cfg -f target/stm32f4x.cfg
|
|
)
|
|
|
|
add_custom_target(gdb
|
|
DEPENDS ${EXECUTABLE}
|
|
COMMENT "GDB connection to GDB Server via ST Link"
|
|
COMMAND ${CMAKE_GDB} -q ${EXECUTABLE} -ex "target extended-remote localhost:3333"
|
|
)
|
|
|
|
# Run OpenOCD with ST Link to flash
|
|
set(OPENOCD_FLASH_CMD "program ${EXECUTABLE} verify reset exit")
|
|
add_custom_target(flash
|
|
DEPENDS ${EXECUTABLE}
|
|
COMMENT "OpenOCD flash and verify using elf."
|
|
COMMAND ${CMAKE_OPENOCD} -f interface/stlink.cfg -f target/stm32f4x.cfg -c ${OPENOCD_FLASH_CMD}
|
|
)
|