Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
PonomarevDA committed Dec 19, 2024
1 parent ddc3ef1 commit 92d6274
Show file tree
Hide file tree
Showing 14 changed files with 608 additions and 3 deletions.
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(DOC_PATH ${ROOT_DIR}/docs/${CAN_PROTOCOL}/README.md)
option(USE_PLATFORM_UBUNTU "Build for SITL (Software In The Loop)" OFF)
option(USE_PLATFORM_NODE_V2 "Build for stm32f103xB (128 KBytes)" OFF)
option(USE_PLATFORM_NODE_V3 "Build for stm32g0b1 (512 KBytes)" OFF)
option(USE_PLATFORM_BOOTLOADER_NODE_V3 "Build for stm32g0b1 (512 KBytes)" OFF)

if(USE_PLATFORM_UBUNTU)
set(LIBPARAMS_PLATFORM ubuntu)
Expand All @@ -32,6 +33,13 @@ elseif(USE_PLATFORM_NODE_V3)
set(PLATFORM_NAME v3)
include(${CMAKE_DIR}/stm32g0b1.cmake)
add_compile_definitions(CYPHAL_NUM_OF_CAN_BUSES=2)
elseif(USE_PLATFORM_BOOTLOADER_NODE_V3)
set(LIBPARAMS_PLATFORM stm32g0b1)
set(CAN_PLATFORM fdcan)
set(APP_PLATFORM stm32g0b1)
set(PLATFORM_NAME v3)
include(${CMAKE_DIR}/stm32g0b1_bootloader.cmake)
add_compile_definitions(CYPHAL_NUM_OF_CAN_BUSES=1)
else()
message(SEND_ERROR "Platform Error: Either v2 (stm32f103), v3 (stm32g0) or SITL (Linux) should be specified.")
endif()
Expand Down Expand Up @@ -69,7 +77,7 @@ list(APPEND APPLICATION_HEADERS ${ROOT_DIR}/Src ${APPLICATION_DIR})
include(${APPLICATION_DIR}/CMakeLists.txt)

# Set compile options
set(WARNING_FLAGS "-Wall -Wextra -Wfloat-equal -Werror -Wundef -Wshadow -Wpointer-arith -Wunreachable-code -Wstrict-overflow=5 -Wwrite-strings -Wswitch-default")
set(WARNING_FLAGS "-Wall -Wextra -Wfloat-equal -Werror -Wundef -Wno-error=attributes -Wshadow -Wpointer-arith -Wunreachable-code -Wstrict-overflow=5 -Wwrite-strings -Wswitch-default")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -Wno-volatile")
set(CMAKE_CXX_STANDARD 20)
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ bootloader_v3: generate_dsdl
./scripts/install_bootloader.sh

mkdir -p ${BUILD_DIR}/bootloader_v3/obj
cd ${BUILD_DIR}/bootloader_v3/obj && cmake -DCAN_PROTOCOL=both -DUSE_PLATFORM_NODE_V3=ON -DBUILD_OBJ_DIR=${BUILD_DIR}/bootloader_v3/obj -G "Unix Makefiles" ../../.. && make
cd ${BUILD_DIR}/bootloader_v3/obj && cmake -DCAN_PROTOCOL=bootloader -DUSE_PLATFORM_BOOTLOADER_NODE_V3=ON -DBUILD_OBJ_DIR=${BUILD_DIR}/bootloader_v3/obj -G "Unix Makefiles" ../../.. && make

# Common:
checks:
Expand Down
27 changes: 27 additions & 0 deletions Src/applications/bootloader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright (C) 2023 Dmitry Ponomarev <[email protected]>
# Distributed under the terms of the GPL v3 license, available in the file LICENSE.

set(APPLICATION_DIR ${CMAKE_CURRENT_LIST_DIR})
cmake_path(GET CMAKE_CURRENT_LIST_DIR PARENT_PATH APPLICATIONS_DIR)
cmake_path(GET APPLICATIONS_DIR PARENT_PATH SRC_DIR)

add_definitions(-DRELEASE_BUILD=1)


include(${SRC_DIR}/modules/bootloader/CMakeLists.txt)
# include(${SRC_DIR}/modules/cyphal/core/CMakeLists.txt)
include(${SRC_DIR}/modules/system/CMakeLists.txt)

list(APPEND APPLICATION_SOURCES
${libparamsSrc}
${ROOT_DIR}/Libs/Cyphal/Libs/o1heap/o1heap/o1heap.c
${ROOT_DIR}/Libs/Cyphal/platform_specific/fdcan/cyphal_transport_can.cpp
)

list(APPEND APPLICATION_HEADERS
${libparamsHeaders}
${ROOT_DIR}/Libs/Cyphal/include
${ROOT_DIR}/Libs/Cyphal/Libs/libcanard/libcanard
${ROOT_DIR}/build/nunavut_out
${ROOT_DIR}/Libs/Cyphal/Libs/o1heap/o1heap
)
26 changes: 26 additions & 0 deletions Src/modules/bootloader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (C) 2023 Dmitry Ponomarev <[email protected]>
# Distributed under the terms of the GPL v3 license, available in the file LICENSE.

# Include guard
if(BOOTLOADER_MODULE_DIR)
return()
endif()
set(BOOTLOADER_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR})

list(APPEND APPLICATION_HEADERS
${CMAKE_CURRENT_LIST_DIR}
${ROOT_DIR}/build/bootloader_v3/libs/kocherga/kocherga/
)

list(APPEND APPLICATION_SOURCES
${CMAKE_CURRENT_LIST_DIR}/application.cpp
${CMAKE_CURRENT_LIST_DIR}/bootloader_interface.cpp
${CMAKE_CURRENT_LIST_DIR}/main.cpp
${CMAKE_CURRENT_LIST_DIR}/my_can_driver.cpp
)

list(APPEND LIBPARAMS_PARAMS
${CMAKE_CURRENT_LIST_DIR}/params.yaml
)

include(${ROOT_DIR}/Src/peripheral/led/CMakeLists.txt)
262 changes: 262 additions & 0 deletions Src/modules/bootloader/application.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
/// This software is distributed under the terms of the MIT License.
/// Copyright (c) 2022 Dmitry Ponomarev.
/// Author: Dmitry Ponomarev <[email protected]>

#include "application.hpp"
#include <cstdlib>
#include "kocherga.hpp"
#include "my_can_driver.hpp"
#include "kocherga_can.hpp"
#include "main.h"
#include "cyphalNode/cyphal.hpp"
#include "libparams_error_codes.h"
#include "params.hpp"
#include "flash_driver.h"
#include "rom.h"

// Please, specify config here:
#define BOOTLOADER_SIZE_PAGES 32

// Automatically calculated:
#define RESERVED_PAGES 3
#define BOOTLOADER_SIZE_BYTES (flashGetPageSize() * BOOTLOADER_SIZE_PAGES)
#define APP_FIRST_PAGE_IDX BOOTLOADER_SIZE_PAGES
#define APP_START_ADDRESS (FLASH_START_ADDR + BOOTLOADER_SIZE_BYTES)
#define APP_MAX_SIZE_PAGES (flashGetNumberOfPages() - BOOTLOADER_SIZE_PAGES - RESERVED_PAGES)
#define APP_MAX_SIZE_BYTES (APP_MAX_SIZE_PAGES * flashGetPageSize())

#define PARAMS_SECTION_REL_ADDR (APP_MAX_SIZE_PAGES + 2) * flashGetPageSize()
#define RESERVED_SECTION_REL_ADDR (APP_MAX_SIZE_PAGES + 1) * flashGetPageSize()

class MyROMBackend final : public kocherga::IROMBackend {
public:
MyROMBackend()
{
rom = romInit(APP_FIRST_PAGE_IDX, APP_MAX_SIZE_PAGES + RESERVED_PAGES);
}

private:
auto write(const std::size_t offset, const std::byte* const data, const std::size_t size)
-> std::optional<std::size_t> override
{
if (romWrite(&rom, offset, (const uint8_t*)data, size)) {
return size;
}
return {};
}

auto read(const std::size_t offset, std::byte* const out_data, const std::size_t size) const
-> std::size_t override
{
return romRead(&rom, offset, (uint8_t*)out_data, size);
}

void beginWrite() override
{
romBeginWrite(&rom);
}

void endWrite() override
{
romEndWrite(&rom);
}

static inline RomDriverInstance rom;
};


#define RED_PORT INTERNAL_LED_RED_GPIO_Port
#define RED_PIN INTERNAL_LED_RED_Pin
#define GREEN_PORT INTERNAL_LED_GREEN_GPIO_Port
#define GREEN_PIN INTERNAL_LED_GREEN_Pin
#define BLUE_PORT INTERNAL_LED_BLUE_GPIO_Port
#define BLUE_PIN INTERNAL_LED_BLUE_Pin

enum class BootloaderCommand {
UNKNOWN_BOOT = 0,
FORCE_RUN_CYPHAL_APPLICATION = 1,
FORCE_RUN_DRONECAN_APPLICATION = 2,
};

void boot_app() {
typedef void (*pFunction)(void);
__disable_irq();
uint32_t app_jump_address = *( uint32_t*) (APP_START_ADDRESS + 4);
pFunction Jump_To_Application = (pFunction)app_jump_address;
SCB->VTOR = APP_START_ADDRESS;
__set_MSP(*(__IO uint32_t*) APP_START_ADDRESS);
Jump_To_Application();
}

void reboot() {
HAL_NVIC_SystemReset();
}

void ledsTurnOffAll() {
HAL_GPIO_WritePin(RED_PORT, RED_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(GREEN_PORT, GREEN_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(BLUE_PORT, BLUE_PIN, GPIO_PIN_SET);
}

GPIO_PinState timeToPinState(uint32_t period) {
return (HAL_GetTick() % period) > (period / 2) ? GPIO_PIN_SET : GPIO_PIN_RESET;
}

void ledsToggleBlue(uint32_t period = 0) {
if (period == 0) {
HAL_GPIO_TogglePin(BLUE_PORT, BLUE_PIN);
} else {
HAL_GPIO_WritePin(BLUE_PORT, BLUE_PIN, timeToPinState(period));
}
}

void ledsToggleRed(uint32_t period = 0) {
if (period == 0) {
HAL_GPIO_TogglePin(RED_PORT, RED_PIN);
} else {
HAL_GPIO_WritePin(RED_PORT, RED_PIN, timeToPinState(period));
}
}

void ledsToggleGreen(uint32_t period = 0) {
if (period == 0) {
HAL_GPIO_TogglePin(GREEN_PORT, GREEN_PIN);
} else {
HAL_GPIO_WritePin(GREEN_PORT, GREEN_PIN, timeToPinState(period));
}
}

void ledsTogglePurple(uint32_t period = 0) {
if (period == 0) {
HAL_GPIO_TogglePin(BLUE_PORT, BLUE_PIN);
HAL_GPIO_TogglePin(RED_PORT, RED_PIN);
} else {
auto pin_state = timeToPinState(period);
HAL_GPIO_WritePin(BLUE_PORT, BLUE_PIN, pin_state);
HAL_GPIO_WritePin(RED_PORT, RED_PIN, pin_state);
}
}

void catch_error(uint32_t period_ms) {
ledsTurnOffAll();

uint32_t next_toggle_led_ts_ms = 500;
uint32_t crnt_ts_ms = 0;
while (true) {
crnt_ts_ms = HAL_GetTick();
if (crnt_ts_ms > next_toggle_led_ts_ms) {
next_toggle_led_ts_ms += period_ms;
ledsToggleRed();
}
}
}

void assert_true(bool is_true) {
if (!is_true) {
catch_error(100);
}
}

uint8_t determine_node_id() {
auto node_id = 42; // paramsGetIntegerValue(PARAM_NODE_ID);

if (node_id < 1 || node_id >= 127) {
node_id = 42;
}

return node_id;
}

uint8_t determine_protocol_version(MyCANDriver& can_driver) {
ledsTurnOffAll();
uint8_t protocol_version;

auto cmd = static_cast<BootloaderCommand>(paramsGetIntegerValue(PARAM_BOOTLOADER_INTERNAL));
kocherga::can::ICANDriver::PayloadBuffer payload_buffer;
if (cmd == BootloaderCommand::UNKNOWN_BOOT) {
while (true) {
auto frame = can_driver.pop(payload_buffer);
ledsToggleBlue(500);
if (frame == std::nullopt || frame->second == 0) {
continue;
}
ledsToggleGreen();

uint8_t last_byte_idx = frame->second - 1;
uint8_t tail_byte_without_transfer_id = payload_buffer[last_byte_idx] & 0b11100000;
if (tail_byte_without_transfer_id == 0b11000000) {
protocol_version = 0;
break;
} else if (tail_byte_without_transfer_id == 0b11100000) {
protocol_version = 1;
break;
}
}
} else if (cmd == BootloaderCommand::FORCE_RUN_DRONECAN_APPLICATION) {
protocol_version = 1;
} else if (cmd == BootloaderCommand::FORCE_RUN_CYPHAL_APPLICATION) {
protocol_version = 1;
} else {
protocol_version = 0;
}

return protocol_version;
}

void bootloader_entry_point() {
ledsTurnOffAll();

paramsInit(2, 1, -1, 1);
paramsLoad();

MyROMBackend rom_backend;

kocherga::SystemInfo system_info = {
.node_name = "Bootloader"
};

MyCANDriver can_driver;
can_driver.init();
kocherga::can::CANNode can_node(
can_driver,
system_info.unique_id,
kocherga::can::ICANDriver::Bitrate{1000000, 1000000},
determine_protocol_version(can_driver),
determine_node_id()
);

kocherga::Bootloader bootloader(
rom_backend,
system_info,
APP_MAX_SIZE_BYTES, ///< max_app_size
false, ///< linger
std::chrono::seconds(10)
);
assert_true(bootloader.addNode(&can_node));

ledsTurnOffAll();
while (true) {
const auto uptime = GET_TIME_SINCE_BOOT();
const auto fin = bootloader.poll(
std::chrono::duration_cast<std::chrono::microseconds>(uptime)
);

auto state = bootloader.getState();
if (state == kocherga::State::NoAppToBoot) {
ledsTogglePurple(100);
} else if (state == kocherga::State::BootDelay) {
ledsToggleGreen(100);
} else if (state == kocherga::State::BootCanceled) {
ledsToggleBlue(100);
} else if (state == kocherga::State::AppUpdateInProgress) {
ledsToggleRed(100);
}

uint32_t crnt_time_ms = HAL_GetTick();
if (crnt_time_ms > 10000 && *fin == kocherga::Final::BootApp) {
boot_app();
} else if (*fin == kocherga::Final::Restart) {
reboot();
}
}
}
18 changes: 18 additions & 0 deletions Src/modules/bootloader/application.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/// This software is distributed under the terms of the MIT License.
/// Copyright (c) 2022 Dmitry Ponomarev.
/// Author: Dmitry Ponomarev <[email protected]>

#ifndef SRC_APPLICATION_HPP_
#define SRC_APPLICATION_HPP_

#ifdef __cplusplus
extern "C" {
#endif

void bootloader_entry_point();

#ifdef __cplusplus
}
#endif

#endif // SRC_APPLICATION_HPP_
Loading

0 comments on commit 92d6274

Please sign in to comment.