Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement bootloader #44

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
26 changes: 17 additions & 9 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,22 @@
"charge_mode.h": "c",
"http_rest.h": "c",
"motors.h": "c",
"eeprom.h": "c",
"stdbool.h": "c",
"configuration.h": "c",
"uart.h": "c",
"common.h": "c",
"clocks.h": "c",
"pwm.h": "c",
"servo_gate.h": "c",
"semphr.h": "c"
"defs.h": "c",
"code.h": "c",
"binary_info.h": "c",
"structure.h": "c",
"stepper.pio.h": "c",
"app_header.h": "c",
"pico.h": "c",
"critical_section.h": "c",
"*.in": "c",
"vreg.h": "c",
"resets.h": "c",
"address_mapped.h": "c",
"m0plus.h": "c",
"stdint.h": "c",
"rp2040_config.h": "c",
"rp2040.h": "c",
"core_cm0plus.h": "c"
}
}
135 changes: 98 additions & 37 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.25)

# Set project data
set(PROJECT_NAME "OpenTricklerController")
set(TARGET_NAME "app")

message("CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")

Expand Down Expand Up @@ -41,14 +40,10 @@ set(PICO_BOARD_HEADER_DIRS "${CMAKE_SOURCE_DIR}/targets")
# Append compiler flags
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdata-sections -ffunction-sections -Wall -Werror")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -Wall -Werror")
# SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")


# Application
add_executable("${TARGET_NAME}")

# Include source
include_directories(${SRC_DIRECTORY})
# Add definitions
add_definitions(-DPICO_NO_BINARY_INFO) # remove binary info from pico-sdk. We will implement our own

# Pull in FreeRTOS
include(${FREERTOS_SRC_DIRECTORY}/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake)
Expand All @@ -67,8 +62,6 @@ target_sources(trinamic INTERFACE
)
target_include_directories(trinamic INTERFACE ${TMC_SRC_DIRECTORY})



# Pull in u8g2 mui
add_library(u8g2_mui
${U8G2_MUI_DIRECTORY}/mui_u8g2.c
Expand All @@ -78,47 +71,115 @@ add_library(u8g2_mui
)
target_link_libraries(u8g2_mui u8g2)

# Pull in src
add_subdirectory(${SRC_DIRECTORY})

# Collect all source files
file(GLOB SRC ${SRC_DIRECTORY}/*.c
${SRC_DIRECTORY}/*.cpp)

# Include application source file
target_sources("${TARGET_NAME}" PUBLIC
${SRC}
)

# Include additional headers
target_include_directories("${TARGET_NAME}" PUBLIC ${CMAKE_SOURCE_DIR}/targets)

# Include libraries1
target_link_libraries("${TARGET_NAME}"
pico_stdlib
hardware_pio
hardware_spi
hardware_i2c
hardware_pwm
# Pull in source code as library
add_library(app_base
# ${SRC}
"${SRC_DIRECTORY}/app.cpp"
"${SRC_DIRECTORY}/freertos_hooks.c"
)
target_include_directories(app_base PUBLIC
${SRC_DIRECTORY}
${SRC_DIRECTORY}/generated
${PICO_BOARD_HEADER_DIRS}
)
target_link_libraries(app_base
FreeRTOS-Kernel
FreeRTOS-Kernel-Heap4
u8g2
u8g2_mui
trinamic
app_version
pico_stdlib
hardware_pio
hardware_spi
hardware_i2c
hardware_pwm
pico_cyw43_arch_lwip_sys_freertos
pico_lwip_freertos
cmsis_core

# Source libraries
access_point_mode
button
charge_mode
cleanup_mode
common
http_server
rest_server
eeprom
menu
display
motors
neopixel
wireless
profile
and_scale
steinberg_scale
gng_scale
ussolid_scale
scale
servo_gate
)

if (PICO_BOARD STREQUAL "pico_w" )
message("Using PICO_W board, link cyw43")
target_link_libraries("${TARGET_NAME}"
pico_cyw43_arch_lwip_sys_freertos
pico_lwip_freertos
# pico_lwip_http
)
endif()
# Pull in src to generate extra files
add_subdirectory(${SRC_DIRECTORY})

# ####################################################
# Build Deployment Application #
######################################################
add_executable(initial_deployment)

target_link_options("${TARGET_NAME}" PUBLIC -Wl,--gc-sections -Wl,--print-memory-usage)
# Include libraries1
target_link_libraries(initial_deployment
app_base
app_header_0
)

target_link_options(initial_deployment PUBLIC -Wl,--gc-sections -Wl,--print-memory-usage)
set_target_properties(initial_deployment PROPERTIES PICO_TARGET_LINKER_SCRIPT ${SCRIPTS_DIRECTORY}/linker_scripts/initial_deployment.ld)
# set( CMAKE_VERBOSE_MAKEFILE on )

# Generate extra outputs
pico_add_extra_outputs("${TARGET_NAME}")
pico_add_extra_outputs(initial_deployment)


# ####################################################
# Build Bank0 Application #
######################################################
add_executable(fw_bank0)

# Include libraries1
target_link_libraries(fw_bank0
app_base
app_header_0
)

target_link_options(fw_bank0 PUBLIC -Wl,--gc-sections -Wl,--print-memory-usage)
set_target_properties(fw_bank0 PROPERTIES PICO_TARGET_LINKER_SCRIPT ${SCRIPTS_DIRECTORY}/linker_scripts/bank0.ld)
# set( CMAKE_VERBOSE_MAKEFILE on )

# Generate extra outputs
pico_add_extra_outputs(fw_bank0)


# ####################################################
# Build Bank1 Application #
######################################################
add_executable(fw_bank1)

# Include libraries1
target_link_libraries(fw_bank1
app_base
app_header_1
)

target_link_options(fw_bank1 PUBLIC -Wl,--gc-sections -Wl,--print-memory-usage)
set_target_properties(fw_bank1 PROPERTIES PICO_TARGET_LINKER_SCRIPT ${SCRIPTS_DIRECTORY}/linker_scripts/bank1.ld)


# Generate extra outputs
pico_add_extra_outputs(fw_bank1)
108 changes: 108 additions & 0 deletions scripts/gen_app_header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import argparse
import logging
import subprocess
import sys
import re
import os


GIT_VERSION_COMMAND = ["git", "describe", "--tags", "--long", "--dirty", "--always"]

GIT_VERSION_PATTERN_REGEX = r'v(?P<major>\d+)\.(?P<minor>\d+)-(?P<patch>\d+)-g(?P<short_hash>[a-f0-9]+)(?P<dirty>-dirty)?'


C_SOURCE_TEMPLATE = """// ---------------------------------------------------------------------- //
// This file is auto-generated by gen_application_header.py; do not edit! //
// ---------------------------------------------------------------------- //
#include "app_header.h"

#ifdef __cplusplus
extern "C"
{{
#endif

__attribute__ ((section (".app_header")))
__attribute__ ((used))
const app_header_t __app_header = {{
.app_header_rev = {app_header_rev},
.flash_partition_idx = {flash_partition_idx},
.crc = 0,
.vcs_hash = "{vcs_hash}",
.build_type = "{build_type}",
.firmware_version = "{firmware_version}",
}};


const app_header_t * get_app_header(void)
{{
return &__app_header;
}}


#ifdef __cplusplus
}}
#endif
"""


def main(output_path, build_type, flash_partition_idx):
output = subprocess.check_output(GIT_VERSION_COMMAND, text=True)

logging.debug(f'Raw output: {output}')
match = re.match(GIT_VERSION_PATTERN_REGEX, output)

version_string = "unknown"
hash_string = ""

if match:
groupdict = match.groupdict()

major = groupdict['major']
minor = groupdict['minor']
patch = groupdict['patch']
short_hash = groupdict['short_hash']
dirty = groupdict['dirty']

dirty_string = ""
if dirty: # In case the dirty is None
dirty_string = dirty

version_string = f"{major}.{minor}.{patch}{dirty_string}"
hash_string = short_hash

c_source_string = C_SOURCE_TEMPLATE.format(
app_header_rev=1,
flash_partition_idx=flash_partition_idx,
vcs_hash=hash_string,
build_type=build_type,
firmware_version=version_string,
)

c_source_filepath = os.path.join(output_path, f"app_header_{flash_partition_idx}.c")
with open(c_source_filepath, "w") as fp:
logging.debug(f"Write to {c_source_filepath}")
fp.write(c_source_string)


if __name__ == "__main__":
parser = argparse.ArgumentParser()

parser.add_argument('-o', '--output_filepath', help="The output filepath that the C source will be written to", required=True)
parser.add_argument('--build-type', help="CMake build type", required=True)
parser.add_argument('--flash-partition-idx', help="Flash partition index, it could be either 0 or 1", required=True)

parser.add_argument('-v', '--verbose', action='count', default=0)


args = parser.parse_args()

logging_levels = {0: logging.ERROR,
1: logging.DEBUG,
2: logging.INFO,
3: logging.WARNING,
4: logging.ERROR,
5: logging.CRITICAL}

logging.basicConfig(stream=sys.stdout, level=logging_levels[args.verbose])

main(args.output_filepath, args.build_type, args.flash_partition_idx)
Loading