|
| 1 | + |
| 2 | +cmake_minimum_required(VERSION 3.13) |
| 3 | + |
| 4 | +# Dynamically set project name from directory name |
| 5 | +get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) |
| 6 | +project(${PROJECT_NAME} C) |
| 7 | + |
| 8 | +add_executable(${PROJECT_NAME}_bootloader.elf bootloader/main.c ../simple_uart_protocol/sup.c) |
| 9 | +add_executable(${PROJECT_NAME}_user_app.elf user_app/main.c ../simple_uart_protocol/sup.c) |
| 10 | + |
| 11 | +# Use target_link_options to apply linker flags ONLY to the bootloader. |
| 12 | +# This is the correct, modern CMake way to handle this. |
| 13 | +target_link_options(${PROJECT_NAME}_bootloader.elf PRIVATE |
| 14 | + "-Wl,-section-start=.text=${BOOTLOADER_START_ADDRESS}" |
| 15 | +) |
| 16 | + |
| 17 | +# Place a small dedicated section ".bootflag" at a fixed SRAM address so that |
| 18 | +# both bootloader and user application can reliably share a RAM-resident flag |
| 19 | +# across software resets without using EEPROM. Address chosen near top of SRAM |
| 20 | +# for ATmega328P; adjust if you use a different MCU. |
| 21 | +target_link_options(${PROJECT_NAME}_bootloader.elf PRIVATE |
| 22 | + "-Wl,--section-start=.bootflag=0x08F8" |
| 23 | +) |
| 24 | + |
| 25 | +target_link_options(${PROJECT_NAME}_user_app.elf PRIVATE |
| 26 | + "-Wl,--section-start=.bootflag=0x08F8" |
| 27 | +) |
| 28 | + |
| 29 | +# Generate a linker map file next to each ELF. Use the output file name derived from |
| 30 | +# the target name so the map is easy to find (e.g. final_bootloader.elf -> final_bootloader.map) |
| 31 | +target_link_options(${PROJECT_NAME}_bootloader.elf PRIVATE |
| 32 | + "-Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_bootloader.map" |
| 33 | +) |
| 34 | + |
| 35 | +target_link_options(${PROJECT_NAME}_user_app.elf PRIVATE |
| 36 | + "-Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_user_app.map" |
| 37 | +) |
| 38 | + |
| 39 | +# Build the hex and bin files |
| 40 | +# which are needed for flashing the bootloader |
| 41 | +add_custom_target( |
| 42 | + ${PROJECT_NAME}_build_bootloader ALL |
| 43 | + COMMAND avr-objcopy -j .text -j .data -O ihex ${PROJECT_NAME}_bootloader.elf ${PROJECT_NAME}_bootloader.hex |
| 44 | + COMMAND avr-objcopy -j .text -j .data -O binary ${PROJECT_NAME}_bootloader.elf ${PROJECT_NAME}_bootloader.bin |
| 45 | + COMMAND avr-size --format=avr --mcu=${MCU} ${PROJECT_NAME}_bootloader.elf |
| 46 | + DEPENDS ${PROJECT_NAME}_bootloader.elf |
| 47 | + COMMENT "[[${PROJECT_NAME}]] Building bootloader .hex and .bin files for \"${MCU}\"" |
| 48 | +) |
| 49 | + |
| 50 | +add_custom_target( |
| 51 | + ${PROJECT_NAME}_build_user_app ALL |
| 52 | + COMMAND avr-objcopy -j .text -j .data -O ihex ${PROJECT_NAME}_user_app.elf ${PROJECT_NAME}_user_app.hex |
| 53 | + COMMAND avr-objcopy -j .text -j .data -O binary ${PROJECT_NAME}_user_app.elf ${PROJECT_NAME}_user_app.bin |
| 54 | + COMMAND avr-size --format=avr --mcu=${MCU} ${PROJECT_NAME}_user_app.elf |
| 55 | + DEPENDS ${PROJECT_NAME}_user_app.elf |
| 56 | + COMMENT "[[${PROJECT_NAME}]] Building user application .hex and .bin files for \"${MCU}\"" |
| 57 | +) |
| 58 | + |
| 59 | +add_custom_target( |
| 60 | + ${PROJECT_NAME}_build_all ALL |
| 61 | + DEPENDS ${PROJECT_NAME}_build_bootloader ${PROJECT_NAME}_build_user_app |
| 62 | + COMMENT "[[${PROJECT_NAME}]] Building all .hex and .bin files for \"${MCU}\"" |
| 63 | +) |
| 64 | + |
| 65 | +# Flash the bootloader to the microcontroller |
| 66 | +add_custom_target( |
| 67 | + ${PROJECT_NAME}_flash_bootloader |
| 68 | + COMMAND avrdude -c ${AVRDUDE_PROGRAMMER} -p ${MCU} -U flash:w:${PROJECT_NAME}_bootloader.hex:i |
| 69 | + DEPENDS ${PROJECT_NAME}_build_bootloader |
| 70 | + COMMENT "[[${PROJECT_NAME}]] Flashing the bootloader to \"${MCU}\" using \"${AVRDUDE_PROGRAMMER}\"" |
| 71 | + COMMENT "[[${PROJECT_NAME}]] Bootloader start address: 0x${BOOTLOADER_START_ADDRESS}" |
| 72 | +) |
| 73 | + |
| 74 | +# Flash the user application to the microcontroller |
| 75 | +add_custom_target( |
| 76 | + ${PROJECT_NAME}_flash_user_app |
| 77 | + COMMAND avrdude -c ${AVRDUDE_PROGRAMMER} -p ${MCU} -U flash:w:${PROJECT_NAME}_user_app.hex:i |
| 78 | + DEPENDS ${PROJECT_NAME}_build_user_app |
| 79 | + COMMENT "[[${PROJECT_NAME}]] Flashing user application to \"${MCU}\" using \"${AVRDUDE_PROGRAMMER}\"" |
| 80 | +) |
| 81 | + |
| 82 | +# Flash both the bootloader and user application to the microcontroller |
| 83 | +add_custom_target( |
| 84 | + ${PROJECT_NAME}_flash_all |
| 85 | + COMMAND avrdude -c ${AVRDUDE_PROGRAMMER} -p ${MCU} -U flash:w:${PROJECT_NAME}_user_app.hex:i -U flash:w:${PROJECT_NAME}_bootloader.hex:i |
| 86 | + DEPENDS ${PROJECT_NAME}_build_all |
| 87 | + COMMENT "[[${PROJECT_NAME}]] Flashing both bootloader and user application to \"${MCU}\" using \"${AVRDUDE_PROGRAMMER}\"" |
| 88 | +) |
0 commit comments