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

Soft 468 jumping back to bootloader #459

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
cab2401
Replaced old NTC curve with new experimental curve
vaaranan-y Aug 25, 2021
f1ce7d0
modified appropriate test(s)
vaaranan-y Aug 25, 2021
6d48397
implemented jump to bootloader, follow comments
vaaranan-y Oct 2, 2021
b0a8848
updated main in bootloader
vaaranan-y Oct 2, 2021
069f19b
Fixed macro typecast error
vaaranan-y Oct 2, 2021
d52dd55
Merge branch 'master' into soft_468_jumping_back_to_bootloader
vaaranan-y Oct 2, 2021
2f6df6a
[SOFT-468] Merge branch 'soft_468_jumping_back_to_bootloader' of http…
vaaranan-y Oct 2, 2021
d7782c6
[SOFT-468] Fixed memory configuration to flash, not SRAM
vaaranan-y Oct 9, 2021
4ec7d10
[SOFT-468] Modularized jump function
vaaranan-y Oct 9, 2021
8b21f0d
[SOFT-468] Added ms-bootloader library
vaaranan-y Oct 9, 2021
0687368
[SOFT-468] Implemented preprocessorconditional upon compilation for a…
vaaranan-y Oct 10, 2021
b582454
[SOFT-468] fixed jump function implementation
vaaranan-y Oct 10, 2021
3be0a3a
Merge branch 'master' into soft_468_jumping_back_to_bootloader
vaaranan-y Oct 10, 2021
a91053c
[SOFT-468] moved jump.c
vaaranan-y Oct 10, 2021
3837dd3
[SOFT-468] made perform_jump non-static/public
vaaranan-y Oct 10, 2021
adf3c2c
[SOFT-468] fixing merge issues
vaaranan-y Oct 10, 2021
718f7f8
[SOFT-468] included string library to jump header
vaaranan-y Oct 10, 2021
d3d5bd5
[SOFT-468] Removed naked attribute from jump function
vaaranan-y Oct 13, 2021
8289d59
Merge branch 'master' into soft_468_jumping_back_to_bootloader
vaaranan-y Oct 13, 2021
ad43709
[SOFT-468] Removed naked attribute from jump function in project itself
vaaranan-y Oct 13, 2021
6b5dbae
[SOFT-468] Merge branch 'soft_468_jumping_back_to_bootloader' of http…
vaaranan-y Oct 13, 2021
f3a9b4b
[SOFT-468] Moved implementation to STM32F0XX
vaaranan-y Nov 11, 2021
4be0005
[SOFT-468] removed noreturn from perform jump
vaaranan-y Nov 11, 2021
b502b92
Merge branch 'master' into soft_468_jumping_back_to_bootloader
vaaranan-y Nov 11, 2021
f379df3
[SOFT-468] moved implementation from bootloader project to ms-bootloader
vaaranan-y Nov 13, 2021
450b243
[SOFT-468] changes APP_COMP_ON_BOOT to BOOTLOADER_APPLICATION
vaaranan-y Nov 13, 2021
426d9e3
[SOFT-468] changed BOOTLOADER_DEFAULT_LOCATION to BOOTLOADER_START
vaaranan-y Nov 13, 2021
d75fa56
[SOFT-468] Added description for ms-bootloader
vaaranan-y Nov 13, 2021
eaf6cd0
[SOFT-468] Merge branch 'soft_468_jumping_back_to_bootloader' of http…
vaaranan-y Nov 13, 2021
3a84088
Merge branch 'master' into soft_468_jumping_back_to_bootloader
vaaranan-y Jan 22, 2022
47f14b9
[SOFT-468] changed APP_ON_COMP to BOOTLOADER_APPLICATION
vaaranan-y Mar 10, 2022
fa7f236
[SOFT-468] merged
vaaranan-y Mar 10, 2022
f0c9869
[SOFT-468] Fix bootloader_mcu include issues
ryandancy Mar 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions libraries/ms-bootloader/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!--
General guidelines
These are just guidelines, not strict rules - document however seems best.
A README for a firmware-only project (e.g. Babydriver, MU, bootloader, CAN explorer) should answer the following questions:
- What is it?
- What problem does it solve?
- How do I use it? (with usage examples / example commands, etc)
- How does it work? (architectural overview)
A README for a board project (powering a hardware board, e.g. power distribution, centre console, charger, BMS carrier) should answer the following questions:
- What is the purpose of the board?
- What are all the things that the firmware needs to do?
- How does it fit into the overall system?
- How does it work? (architectural overview, e.g. what each module's purpose is or how data flows through the firmware)
-->
# ms-bootloader
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should write a brief description of what goes in ms-bootloader here.


8 changes: 8 additions & 0 deletions libraries/ms-bootloader/inc/jump.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: add a comment here saying what the library is used for, i.e. it lets you jump to an arbitrary memory address.

#include <stdint.h>
#include <stdnoreturn.h>
#include <string.h>

// Reset main stack pointer to main stack pointer, and jump to program counter
noreturn void perform_jump(uint32_t sp, uint32_t pc);
4 changes: 4 additions & 0 deletions libraries/ms-bootloader/inc/jump_to_bootloader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

// Jump to the bootloade at the beginning of flash memory
void jump_to_bootloader(void);
9 changes: 9 additions & 0 deletions libraries/ms-bootloader/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Defines $(T)_SRC, $(T)_INC, $(T)_DEPS, and $(T)_CFLAGS for the build makefile.
# Tests can be excluded by defining $(T)_EXCLUDE_TESTS.
# Pre-defined:
# $(T)_SRC_ROOT: $(T)_DIR/src
# $(T)_INC_DIRS: $(T)_DIR/inc{/$(PLATFORM)}
# $(T)_SRC: $(T)_DIR/src{/$(PLATFORM)}/*.{c,s}

# Specify the libraries you want to include
$(T)_DEPS :=
12 changes: 12 additions & 0 deletions libraries/ms-bootloader/src/jump.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "jump.h"

noreturn void prv_perform_jump(uint32_t sp, uint32_t pc) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to add back the __attribute__((naked)) here - it tells the compiler not to generate the standard entry/exit code for functions and just to use the raw assembly. It also will stop CI from complaining about noreturn.

Also, this is STM32-specific - you'll need to move it to an stm32f0xx folder and add a (no-op) x86 implementation.

__asm(
"msr msp, %[sp] \n" // reset the main stack pointer (msp) to sp
"bx %[pc] \n" // jump to pc

// this bizarre syntax associates the "sp" and "pc" in asm with the sp and pc parameters
// see http://www.ethernut.de/en/documents/arm-inline-asm.html
:
: [sp] "r"(sp), [pc] "r"(pc));
}
30 changes: 30 additions & 0 deletions libraries/ms-bootloader/src/jump_to_bootloader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "jump_to_bootloader.h"

#include <stdint.h>
#include <stdnoreturn.h>
#include <string.h>

#include "bootloader_mcu.h"
#include "jump.h"
#include "stm32f0xx_misc.h"
#include "stm32f0xx_syscfg.h"

void jump_to_bootloader(void) {
// Disable all interrupts so their is no interference when working with vector tables
__disable_irq();

// Reset the vector table to bootloader's vector table
SYSCFG_MemoryRemapConfig(
SYSCFG_MemoryRemap_Flash); // change where the vector table is stored to beginning of flash

// story memory location of bootloader starting point at the beginning of flash?
uint32_t *bootloader_in_flash = BOOTLOADER_DEFAULT_LOCATION;
// setting the stack pointer to the bootloader location now
uint32_t initial_sp = bootloader_in_flash[0];
uint32_t reset_handler_pc = bootloader_in_flash[1];

// re-enable interrupts
__enable_irq();
// jump to bootloader
perform_jump(initial_sp, reset_handler_pc);
}
5 changes: 5 additions & 0 deletions libraries/ms-common/src/can_fsm.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "can_fsm.h"

#include "bootloader_can.h"
#include "can.h"
#include "can_hw.h"
#include "can_msg_defs.h"
#include "can_rx.h"
#include "jump_to_bootloader.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll get a linker error here when the jump_to_bootloader call actually gets compiled - you'll need to add ms-bootloader to the $(T)_DEPS list in ms-common's rules.mk to tell the build system to link the ms-bootloader object files along with the ms-common ones.


FSM_DECLARE_STATE(can_rx_fsm_handle);
FSM_DECLARE_STATE(can_tx_fsm_handle);
Expand Down Expand Up @@ -57,6 +59,9 @@ static void prv_handle_rx(Fsm *fsm, const Event *e, void *context) {

// Process bootloader messages
if (rx_msg.source_id == SYSTEM_CAN_DEVICE_BOOTLOADER) {
#ifdef APP_COMP_ON_BOOT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to change this to BOOTLOADER_APPLICATION too.

jump_to_bootloader();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: you'll want to add a comment saying that jump_to_bootloader doesn't return since that's important for anyone reading the code. You also might want to add a return; afterwards even though it technically doesn't do anything, just so it doesn't read like you're then going to call bootloader_can_receive.

#endif
result = bootloader_can_receive(&rx_msg);
return;
}
Expand Down
1 change: 1 addition & 0 deletions platform/stm32f0xx/platform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ endif
DEFAULT_LINKER_SCRIPT ?= stm32f0_default.ld
ifeq ($(MAKECMDGOALS),temp-bootloader-write)
DEFAULT_LINKER_SCRIPT := stm32f0_application.ld
CFLAGS += -DAPP_COMP_ON_BOOT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does APP_COMP_ON_BOOT stand for? BOOTLOADER_APPLICATION might be clearer.

endif

# Device openocd config file
Expand Down
8 changes: 8 additions & 0 deletions projects/bootloader/inc/jump.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <stdint.h>
#include <stdnoreturn.h>
#include <string.h>

// Reset main stack pointer to main stack pointer, and jump to program counter
noreturn void perform_jump(uint32_t sp, uint32_t pc);
4 changes: 4 additions & 0 deletions projects/bootloader/inc/jump_to_bootloader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

// Jump to the bootloade at the beginning of flash memory
void jump_to_bootloader(void);
4 changes: 4 additions & 0 deletions projects/bootloader/inc/stm32f0xx/bootloader_mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ extern uint32_t _application_size;
extern uint32_t _ram_start;
extern uint32_t _ram_size;
extern uint32_t _vector_table_size;
extern uint32_t _bootloader_start;
extern uint32_t _bootloader_size;

#define BOOTLOADER_CONFIG_PAGE_1_START ((void *)&_config_page1_start)
#define BOOTLOADER_CONFIG_PAGE_2_START ((void *)&_config_page2_start)
Expand All @@ -23,3 +25,5 @@ extern uint32_t _vector_table_size;
#define BOOTLOADER_RAM_START ((void *)&_ram_start)
#define BOOTLOADER_RAM_SIZE ((size_t)&_ram_size)
#define BOOTLOADER_VECTOR_TABLE_SIZE ((size_t)&_vector_table_size)
#define BOOTLOADER_DEFAULT_LOCATION ((void *)&_bootloader_start)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think BOOTLOADER_START might be a clearer name for this, especially since we'll likely never have the bootloader at a different location (so not "default").

#define BOOTLOADER_SIZE ((size_t)&_bootloader_size)
1 change: 1 addition & 0 deletions projects/bootloader/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "flash.h"
#include "interrupt.h"
#include "jump_to_application.h"
#include "jump_to_bootloader.h"
Copy link
Collaborator

@ryandancy ryandancy Oct 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the next steps for this module is that we want to jump from the bootloader to the application when we receive a datagram message while in an application. This will be in can_fsm.c, in the if (rx_msg.source_id == SYSTEM_CAN_DEVICE_BOOTLOADER) if statement. Essentially, when that if statement is reached:

  • if we're in an application running on the bootloader, in which case we should jump to the bootloader so that the bootloader can receive subsequent datagram messages
  • oherwise, we should call bootloader_can_receive there like we do now so that the bootloader can process the message (if necessary)

So there are a couple of parts to doing this:

  1. We'll need to move jump_to_bootloader to a library, perhaps called ms-bootloader, so can_fsm.c can reach it. Perhaps move bootloader_mcu.h to that library too.
  2. We'll need a way to determine which of the three scenarios above we're in. This is a bit tricky: we'll need a preprocessor symbol that's defined when we're compiling for an application running on the bootloader. You can do this by adding a -D<symbolname> argument to the C compiler flags when compiling for the application, which currently you can do in platform/stm32f0xx/platform.mk by adding CFLAGS += -D<symbolname> to the ifeq ($(MAKECMDGOALS),temp-bootloader-write) if statement (replace <symbolname> with the symbol you want defined when on the application only). Then you can test with #ifdef in can_fsm.c.

#include "log.h"
#include "ping.h"
#include "query.h"
Expand Down
12 changes: 12 additions & 0 deletions projects/bootloader/src/stm32f0xx/jump.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "jump.h"

void perform_jump(uint32_t sp, uint32_t pc) {
__asm(
"msr msp, %[sp] \n" // reset the main stack pointer (msp) to sp
"bx %[pc] \n" // jump to pc

// this bizarre syntax associates the "sp" and "pc" in asm with the sp and pc parameters
// see http://www.ethernut.de/en/documents/arm-inline-asm.html
:
: [sp] "r"(sp), [pc] "r"(pc));
}
30 changes: 30 additions & 0 deletions projects/bootloader/src/stm32f0xx/jump_to_bootloader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "jump_to_bootloader.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jump_to_application, jump_to_bootloader, and jump shouldn't be duplicated between the bootloader project and the ms-bootloader libraries, they should only appear in ms-bootloader. So remove the copies in the bootloader project / move all the functionality to ms-bootloader.


#include <stdint.h>
#include <stdnoreturn.h>
#include <string.h>

#include "bootloader_mcu.h"
#include "jump.h"
#include "stm32f0xx_misc.h"
#include "stm32f0xx_syscfg.h"

void jump_to_bootloader(void) {
// Disable all interrupts so their is no interference when working with vector tables
__disable_irq();

// Reset the vector table to bootloader's vector table
SYSCFG_MemoryRemapConfig(
SYSCFG_MemoryRemap_Flash); // change where the vector table is stored to beginning of flash

// story memory location of bootloader starting point at the beginning of flash?
uint32_t *bootloader_in_flash = BOOTLOADER_DEFAULT_LOCATION;
// setting the stack pointer to the bootloader location now
uint32_t initial_sp = bootloader_in_flash[0];
uint32_t reset_handler_pc = bootloader_in_flash[1];

// re-enable interrupts
__enable_irq();
// jump to bootloader
perform_jump(initial_sp, reset_handler_pc);
}