bootloader docs
This commit is contained in:
parent
501d1c973e
commit
784a6d7146
@ -13,6 +13,7 @@ panic-rtt-target = { version = "0.1.3" }
|
|||||||
panic-halt = { version = "0.2" }
|
panic-halt = { version = "0.2" }
|
||||||
rtt-target = { version = "0.5" }
|
rtt-target = { version = "0.5" }
|
||||||
crc = "3"
|
crc = "3"
|
||||||
|
static_assertions = "1"
|
||||||
|
|
||||||
[dependencies.va108xx-hal]
|
[dependencies.va108xx-hal]
|
||||||
path = "../va108xx-hal"
|
path = "../va108xx-hal"
|
||||||
|
46
bootloader/README.md
Normal file
46
bootloader/README.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
VA416xx Bootloader Application
|
||||||
|
=======
|
||||||
|
|
||||||
|
This is the Rust version of the bootloader supplied by Vorago.
|
||||||
|
|
||||||
|
## Memory Map
|
||||||
|
|
||||||
|
The bootloader uses the following memory map:
|
||||||
|
|
||||||
|
| Address | Notes | Size |
|
||||||
|
| ------ | ---- | ---- |
|
||||||
|
| 0x0 | Bootloader start | code up to 0x3FFC bytes |
|
||||||
|
| 0x2FFE | Bootloader CRC | word |
|
||||||
|
| 0x3000 | App image A start | code up to 0x1DFFC (~120K) bytes |
|
||||||
|
| 0x117F8 | App image A CRC check length | word |
|
||||||
|
| 0x117FC | App image A CRC check value | word |
|
||||||
|
| 0x11800 | App image B start | code up to 0x1DFFC (~120K) bytes |
|
||||||
|
| 0x1FFF8 | App image B CRC check length | word |
|
||||||
|
| 0x1FFFC | App image B CRC check value | word |
|
||||||
|
| 0x20000 | End of NVM | end |
|
||||||
|
|
||||||
|
## Additional Information
|
||||||
|
|
||||||
|
This bootloader was specifically written for the REB1 board, so it assumes a M95M01 ST EEPROM
|
||||||
|
is used to load the application code.
|
||||||
|
|
||||||
|
This bootloader does not provide tools to flash the NVM memory by itself. Instead, you can use
|
||||||
|
the [flashloader](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/flashloader)
|
||||||
|
application to perform this task using a CCSDS interface via a UART.
|
||||||
|
|
||||||
|
The bootloader performs the following steps:
|
||||||
|
|
||||||
|
1. The application will calculate the checksum of itself if the bootloader CRC is blank (all zeroes
|
||||||
|
or all ones). If the CRC is not blank and the checksum check fails, it will immediately boot
|
||||||
|
application image A. Otherwise, it proceeds to the next step.
|
||||||
|
2. Check the checksum of App A. If that checksum is valid, it will boot App A. If not, it will
|
||||||
|
proceed to the next step.
|
||||||
|
3. Check the checksum of App B. If that checksum is valid, it will boot App B. If not, it will
|
||||||
|
boot App A as the fallback image.
|
||||||
|
|
||||||
|
You could adapt and combine this bootloader with a non-volatile memory to select a prefered app
|
||||||
|
image, which would be a first step towards an updatable flight software.
|
||||||
|
|
||||||
|
Please note that you *MUST* compile the application at slot A and slot B with an appropriate
|
||||||
|
`memory.x` file where the base address of the `FLASH` was adapted according to the base address
|
||||||
|
shown in the memory map above. The memory files to do this were provided in the `scripts` folder.
|
@ -39,19 +39,21 @@ const BOOTLOADER_START_ADDR: u32 = 0x0;
|
|||||||
const BOOTLOADER_CRC_ADDR: u32 = BOOTLOADER_END_ADDR - 2;
|
const BOOTLOADER_CRC_ADDR: u32 = BOOTLOADER_END_ADDR - 2;
|
||||||
// This is also the maximum size of the bootloader.
|
// This is also the maximum size of the bootloader.
|
||||||
const BOOTLOADER_END_ADDR: u32 = 0x3000;
|
const BOOTLOADER_END_ADDR: u32 = 0x3000;
|
||||||
const APP_A_START_ADDR: u32 = 0x3000;
|
const APP_A_START_ADDR: u32 = BOOTLOADER_END_ADDR;
|
||||||
const APP_A_SIZE_ADDR: u32 = APP_A_END_ADDR - 8;
|
const APP_A_SIZE_ADDR: u32 = APP_A_END_ADDR - 8; // 0x117F8
|
||||||
// Four bytes reserved, even when only 2 byte CRC is used. Leaves flexibility to switch to CRC32.
|
// Four bytes reserved, even when only 2 byte CRC is used. Leaves flexibility to switch to CRC32.
|
||||||
const APP_A_CRC_ADDR: u32 = APP_A_END_ADDR - 4;
|
const APP_A_CRC_ADDR: u32 = APP_A_END_ADDR - 4; // 0x117FC
|
||||||
pub const APP_A_END_ADDR: u32 = 0x11000;
|
pub const APP_A_END_ADDR: u32 = APP_B_END_ADDR - BOOTLOADER_END_ADDR / 2; // 0x11800
|
||||||
|
// The actual size of the image which is relevant for CRC calculation.
|
||||||
|
const APP_B_START_ADDR: u32 = APP_A_END_ADDR;
|
||||||
// The actual size of the image which is relevant for CRC calculation.
|
// The actual size of the image which is relevant for CRC calculation.
|
||||||
const APP_B_START_ADDR: u32 = 0x11000;
|
const APP_B_SIZE_ADDR: u32 = APP_B_END_ADDR - 8; // 0x1FFF8
|
||||||
// The actual size of the image which is relevant for CRC calculation.
|
// Four bytes reserved, even when only 2 byte CRC is used. Leaves flexibility to switch to CRC32.
|
||||||
const APP_B_SIZE_ADDR: u32 = APP_B_END_ADDR - 8;
|
const APP_B_CRC_ADDR: u32 = APP_B_END_ADDR - 4; // 0x1FFFC
|
||||||
// Four bytes reserved, even when only 2 byte CRC is used. Leaves flexibility to switch to CRC32.
|
|
||||||
const APP_B_CRC_ADDR: u32 = APP_B_END_ADDR - 4;
|
|
||||||
pub const APP_B_END_ADDR: u32 = 0x20000;
|
pub const APP_B_END_ADDR: u32 = 0x20000;
|
||||||
pub const APP_IMG_SZ: u32 = 0xE800;
|
pub const APP_IMG_SZ: u32 = APP_B_END_ADDR - APP_A_END_ADDR / 2;
|
||||||
|
|
||||||
|
static_assertions::const_assert!((APP_B_END_ADDR - BOOTLOADER_END_ADDR) % 2 == 0);
|
||||||
|
|
||||||
pub const VECTOR_TABLE_OFFSET: u32 = 0x0;
|
pub const VECTOR_TABLE_OFFSET: u32 = 0x0;
|
||||||
pub const VECTOR_TABLE_LEN: u32 = 0xC0;
|
pub const VECTOR_TABLE_LEN: u32 = 0xC0;
|
||||||
|
10
scripts/memory_app_a.x
Normal file
10
scripts/memory_app_a.x
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH : ORIGIN = 0x00003000, LENGTH = 0x20000 /* 128K */
|
||||||
|
RAM : ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is where the call stack will be allocated. */
|
||||||
|
/* The stack is of the full descending type. */
|
||||||
|
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
|
||||||
|
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
|
10
scripts/memory_app_b.x
Normal file
10
scripts/memory_app_b.x
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH : ORIGIN = 0x00011800, LENGTH = 0x20000 /* 128K */
|
||||||
|
RAM : ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is where the call stack will be allocated. */
|
||||||
|
/* The stack is of the full descending type. */
|
||||||
|
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
|
||||||
|
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
|
Loading…
Reference in New Issue
Block a user