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

Add flash metadata #308

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 17 additions & 1 deletion obc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ target_compile_definitions(${OUT_FILE_NAME} PRIVATE
OBC_UART_BAUD_RATE=${OBC_UART_BAUD_RATE}
CSDC_DEMO_ENABLED=${CSDC_DEMO_ENABLED}
ENABLE_TASK_STATS_COLLECTOR=${ENABLE_TASK_STATS_COLLECTOR}
ENABLE_BL_BYPASS=${ENABLE_BL_BYPASS}
${PERIPHERAL_CONFIG}
)

Expand All @@ -128,7 +129,6 @@ add_subdirectory(app/rtos)
add_subdirectory(app/sys)
add_subdirectory(app/drivers)
add_subdirectory(app/reliance_edge)

target_link_libraries(${OUT_FILE_NAME} PRIVATE
tiny-aes
lib-correct
Expand Down Expand Up @@ -231,3 +231,19 @@ target_link_libraries(debug-tool.out PRIVATE
${HAL_LIB_OPTIMIZE}
$<TARGET_OBJECTS:${HAL_LIB_NO_OPTIMIZE}>
)


if (${BOARD_TYPE} MATCHES RM46_LAUNCHPAD)
set(BOARD_TYPE_TO_INT_MAP 0)
elseif (${BOARD_TYPE} MATCHES OBC_REVISION_1)
set(BOARD_TYPE_TO_INT_MAP 1)
elseif (${BOARD_TYPE} MATCHES OBC_REVISION_2)
set(BOARD_TYPE_TO_INT_MAP 2)
# Add OBC_REVISION_3 or other boards above
else()
message (FATAL_ERROR "BOARD NOT YET ADDED TO INT MAP FOR METADATA")
endif()

# Generate file with CMake metadata
file(WRITE ${CMAKE_BINARY_DIR}/OBC-metadata.bin
${BOARD_TYPE_TO_INT_MAP} "\n" )
2 changes: 1 addition & 1 deletion obc/app/modules/logger/logger.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define LOG_FILE_NAME "log.log"

#define MAX_MSG_SIZE 128U
#define MAX_FNAME_LINENUM_SIZE 128U
#define MAX_FNAME_LINENUM_SIZE 150U
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure where this is from

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this was from one of Natvaj's logging prs

Copy link
Member

Choose a reason for hiding this comment

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

was the logging pr merged? if so, try pulling from main

Copy link
Contributor

Choose a reason for hiding this comment

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

shouldve been merged

// Extra 10 for the small extra pieces in "%s - %s\r\n"
#define MAX_LOG_SIZE (MAX_MSG_SIZE + MAX_FNAME_LINENUM_SIZE + 10U)

Expand Down
2 changes: 2 additions & 0 deletions obc/app/sys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ SET(INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/print
${CMAKE_CURRENT_SOURCE_DIR}/time
${CMAKE_CURRENT_SOURCE_DIR}/utils
${CMAKE_CURRENT_SOURCE_DIR}/metadata
)

SET(SOURCES
Expand All @@ -18,6 +19,7 @@ SET(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/time/obc_time_utils.c
${CMAKE_CURRENT_SOURCE_DIR}/utils/obc_crc.c
${CMAKE_CURRENT_SOURCE_DIR}/utils/obc_heap.c
${CMAKE_CURRENT_SOURCE_DIR}/metadata/obc_metadata.c
)

target_include_directories(${OUT_FILE_NAME} PUBLIC ${INCLUDES})
Expand Down
20 changes: 20 additions & 0 deletions obc/app/sys/metadata/obc_metadata.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "obc_metadata.h"
#include "obc_errors.h"

#include <stddef.h>

extern uint32_t __metadata_start__[sizeof(app_metadata_t) / sizeof(uint32_t)];

obc_error_code_t readAppMetadata(app_metadata_t* metadata) {
if (metadata == NULL) {
return OBC_ERR_CODE_INVALID_ARG;
}

// If BL is used, get the metadata and return success. Else return error code stating that there is no metadata
#if ENABLE_BL_BYPASS
return OBC_ERR_CODE_NO_METADATA;
#else
*metadata = *(const app_metadata_t*)(&__metadata_start__);
return OBC_ERR_CODE_SUCCESS;
#endif
}
40 changes: 40 additions & 0 deletions obc/app/sys/metadata/obc_metadata.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include "obc_errors.h"
#include <stdint.h>

/*
Steps to update metadata:
1. Update metadata size in memory.ld. To do this, reduce the size of APP_FLASH and edit the origin to be earlier in
flash (skip this step if buffers are still available in the struct below)
2. Update the struct in this file to include the new metadata. Just replace one of the buffers if available
(assuming you are trying to store a 32 bit value).
3. Update metadata.c in order to read new struct members
4. Update bin_formatter class to include new metadata, find a way to make the struct with the bin_formatter before
sending with serial
5. Update bl_main.c app_header_t struct to match this one
6. Update bl_config.h to represent correct origin (METADATA_START_ADDRESS, METADATA_SIZE_BYTES) (skip this step if
buffers are still available in the struct below)
*/

typedef struct {
uint32_t vers;
uint32_t binSize;
uint32_t boardType;
uint32_t unused0;
uint32_t unused1;
uint32_t unused2;
uint32_t unused3;
uint32_t unused4;
} app_metadata_t;

/**
* @brief reads app metadata from the start of the metadata region specified in memory.ld
*
* @param metadata Pointer to metadata_struct_t instance to store metadata in
* @return obc_error_code_t Success if app is flashed using bootloader, No Metadata otherwise.
*
*
*/

obc_error_code_t readAppMetadata(app_metadata_t* metadata);
1 change: 1 addition & 0 deletions obc/app/sys/obc_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ typedef enum {
/* CDH errors 200 - 299 */
OBC_ERR_CODE_UNSUPPORTED_CMD = 200,
OBC_ERR_CODE_CMD_NOT_ALLOWED = 201,
OBC_ERR_CODE_NO_METADATA = 202,

/* ADCS errors 300 - 399 */

Expand Down
111 changes: 88 additions & 23 deletions obc/bl/bl_main.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "bl_config.h"
#include "bl_flash.h"
#include "bl_uart.h"

#include "bl_errors.h"
#include <stdio.h>
#include <string.h>

Expand All @@ -17,6 +17,9 @@ extern uint32_t __ramFuncsRunEnd__;
// use too much RAM
#define BL_BIN_RX_CHUNK_SIZE 128U // Bytes
#define BL_ECC_FIX_CHUNK_SIZE 128U // Bytes
#define BL_MAX_MSG_SIZE 64U
#define RM46_FLASH_BANK 0U
#define LAST_SECTOR_START_ADDR blFlashSectorStartAddr(15U)

/* TYPEDEFS */
typedef void (*appStartFunc_t)(void);
Expand All @@ -25,6 +28,12 @@ typedef void (*appStartFunc_t)(void);
typedef struct {
uint32_t version;
uint32_t size;
uint32_t boardType;
uint32_t unused0;
uint32_t unused1;
uint32_t unused2;
uint32_t unused3;
uint32_t unused4;
} app_header_t;

typedef enum {
Expand All @@ -50,10 +59,10 @@ int main(void) {
while (1) {
switch (state) {
case BL_STATE_IDLE: {
blUartWriteBytes(BL_UART_SCIREG_1, strlen("Waiting for input\r\n"), (uint8_t *)"Waiting for input\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("Waiting for input\r\n"), (uint8_t *)"Waiting for input\r\n");

char c = '\0';
blUartReadBytes(BL_UART_SCIREG_2, (uint8_t *)&c, 1);
blUartReadBytes(BL_UART_SCIREG, (uint8_t *)&c, 1);

if (c == 'd') {
state = BL_STATE_DOWNLOAD_IMAGE;
Expand All @@ -66,60 +75,74 @@ int main(void) {
break;
}
case BL_STATE_DOWNLOAD_IMAGE: {
blUartWriteBytes(BL_UART_SCIREG_1, strlen("Downloading application\r\n"),
blUartWriteBytes(BL_UART_SCIREG, strlen("Downloading application\r\n"),
(uint8_t *)"Downloading application\r\n");

uint8_t recvBuffer[sizeof(app_header_t)] = {0U};

blUartReadBytes(BL_UART_SCIREG_2, recvBuffer, sizeof(app_header_t));
blUartReadBytes(BL_UART_SCIREG, recvBuffer, sizeof(app_header_t));

app_header_t appHeader = {0};
memcpy((void *)&appHeader, (void *)recvBuffer, sizeof(app_header_t));

if (appHeader.size == 0U) {
blUartWriteBytes(BL_UART_SCIREG_1, strlen("Invalid image size\r\n"), (uint8_t *)"Invalid image size\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("Invalid image size\r\n"), (uint8_t *)"Invalid image size\r\n");
state = BL_STATE_IDLE;
break;
}

if (!blFlashIsStartAddrValid(APP_START_ADDRESS, appHeader.size)) {
blUartWriteBytes(BL_UART_SCIREG_1, strlen("Invalid start address\r\n"),
(uint8_t *)"Invalid start address\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("Invalid start address\r\n"), (uint8_t *)"Invalid start address\r\n");
state = BL_STATE_IDLE;
break;
}

blUartWriteBytes(BL_UART_SCIREG_1, strlen("Received header\r\n"), (uint8_t *)"Received header\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("Received header\r\n"), (uint8_t *)"Received header\r\n");

errCode = blFlashFapiInitBank(0U);
errCode = blFlashFapiInitBank(RM46_FLASH_BANK);
if (errCode != BL_ERR_CODE_SUCCESS) {
blUartWriteBytes(BL_UART_SCIREG_1, strlen("Failed to init flash\r\n"), (uint8_t *)"Failed to init flash\r\n");
char blUartWriteBuffer[BL_MAX_MSG_SIZE] = {0};
int32_t blUartWriteBufferLen =
snprintf(blUartWriteBuffer, BL_MAX_MSG_SIZE, "Failed to init flash, error code: %d\r\n", errCode);
if (blUartWriteBufferLen < 0) {
blUartWriteBytes(BL_UART_SCIREG, strlen("Error with processing message buffer length\r\n"),
Copy link
Contributor

Choose a reason for hiding this comment

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

bl error logging should be identical to obc err logging (LOG_ERR_CODE(x)), but ill let @ThenujaL handle this in his PR since hes already porting the logging stuff over

(uint8_t *)"Error with processing message buffer length\r\n");
} else {
blUartWriteBytes(BL_UART_SCIREG, blUartWriteBufferLen, (uint8_t *)blUartWriteBuffer);
}
state = BL_STATE_IDLE;
break;
}

errCode = blFlashFapiBlockErase(APP_START_ADDRESS, appHeader.size);
if (errCode != BL_ERR_CODE_SUCCESS) {
blUartWriteBytes(BL_UART_SCIREG_1, strlen("Failed to erase flash\r\n"),
(uint8_t *)"Failed to erase flash\r\n");
char blUartWriteBuffer[BL_MAX_MSG_SIZE] = {0};
int32_t blUartWriteBufferLen =
snprintf(blUartWriteBuffer, BL_MAX_MSG_SIZE, "Failed to erase flash, error code: %d\r\n", errCode);
if (blUartWriteBufferLen < 0) {
blUartWriteBytes(BL_UART_SCIREG, strlen("Error with processing message buffer length\r\n"),
(uint8_t *)"Error with processing message buffer length\r\n");
} else {
blUartWriteBytes(BL_UART_SCIREG, blUartWriteBufferLen, (uint8_t *)blUartWriteBuffer);
}
state = BL_STATE_IDLE;
break;
}

blUartWriteBytes(BL_UART_SCIREG_1, strlen("Erased flash\r\n"), (uint8_t *)"Erased flash\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("Erased flash\r\n"), (uint8_t *)"Erased flash\r\n");

// Host will send a 'D' before sending the image
while (1) {
char waitChar = '\0';

blUartReadBytes(BL_UART_SCIREG_2, (uint8_t *)&waitChar, 1U);
blUartReadBytes(BL_UART_SCIREG, (uint8_t *)&waitChar, 1U);

if (waitChar == 'D') {
break;
}
}

blFlashFapiInitBank(0U);
blFlashFapiInitBank(RM46_FLASH_BANK);

// Receive image in chunks and write to flash
uint32_t numAppBytesToFlash = appHeader.size;
Expand All @@ -129,17 +152,59 @@ int main(void) {
uint32_t numBytesToRead =
(numAppBytesToFlash > BL_BIN_RX_CHUNK_SIZE) ? BL_BIN_RX_CHUNK_SIZE : numAppBytesToFlash;

blUartReadBytes(BL_UART_SCIREG_2, recvBuffer, numBytesToRead);
blUartReadBytes(BL_UART_SCIREG, recvBuffer, numBytesToRead);

blFlashFapiBlockWrite(APP_START_ADDRESS + (appHeader.size - numAppBytesToFlash), (uint32_t)recvBuffer,
numBytesToRead);

numAppBytesToFlash -= numBytesToRead;
}

blUartWriteBytes(BL_UART_SCIREG_1, strlen("Wrote application\r\n"), (uint8_t *)"Wrote application\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("Wrote application\r\n"), (uint8_t *)"Wrote application\r\n");

blFlashFapiInitBank(RM46_FLASH_BANK);

// Check if flash last sector (where metadata is located) was already erased when erasing sectors for the app
// bin, if not, erase it
if (APP_START_ADDRESS + appHeader.size < LAST_SECTOR_START_ADDR) {
errCode = blFlashFapiBlockErase(METADATA_START_ADDRESS, METADATA_SIZE_BYTES - 1);
if (errCode != BL_ERR_CODE_SUCCESS) {
char blUartWriteBuffer[BL_MAX_MSG_SIZE] = {0};
int32_t blUartWriteBufferLen =
snprintf(blUartWriteBuffer, BL_MAX_MSG_SIZE, "Failed to erase flash, error code: %d\r\n", errCode);
if (blUartWriteBufferLen < 0) {
blUartWriteBytes(BL_UART_SCIREG, strlen("Error with processing message buffer length\r\n"),
(uint8_t *)"Error with processing message buffer length\r\n");
} else {
blUartWriteBytes(BL_UART_SCIREG, blUartWriteBufferLen, (uint8_t *)blUartWriteBuffer);
}
state = BL_STATE_IDLE;
break;
}
blUartWriteBytes(BL_UART_SCIREG, strlen("Erased last flash sector\r\n"),
(uint8_t *)"Erased last flash sector\r\n");
}

blFlashFapiInitBank(RM46_FLASH_BANK);

bl_error_code_t errCode =
blFlashFapiBlockWrite(METADATA_START_ADDRESS, (uint32_t)&appHeader, sizeof(app_header_t));
if (errCode != BL_ERR_CODE_SUCCESS) {
char blUartWriteBuffer[BL_MAX_MSG_SIZE] = {0};
int32_t blUartWriteBufferLen = snprintf(blUartWriteBuffer, BL_MAX_MSG_SIZE,
"Failed to write metadata to flash, error code: %d \r\n", errCode);
if (blUartWriteBufferLen < 0) {
blUartWriteBytes(BL_UART_SCIREG, strlen("Error with processing message buffer length\r\n"),
(uint8_t *)"Error with processing message buffer length\r\n");
} else {
blUartWriteBytes(BL_UART_SCIREG, blUartWriteBufferLen, (uint8_t *)blUartWriteBuffer);
}
state = BL_STATE_IDLE;
break;
}
blUartWriteBytes(BL_UART_SCIREG, strlen("Wrote metadata \r\n"), ((uint8_t *)"Wrote metadata \r\n"));

blUartWriteBytes(BL_UART_SCIREG_1, strlen("Fixing ECC\r\n"), (uint8_t *)"Fixing ECC\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("Fixing ECC\r\n"), (uint8_t *)"Fixing ECC\r\n");

// Fix the ECC for any flash memory that was erased, but not overwritten by the new app
uint8_t eccFixWriteBuf[BL_ECC_FIX_CHUNK_SIZE] = {0U};
Expand All @@ -162,28 +227,28 @@ int main(void) {
eccFixBytesLeft -= numBytesToWrite;
}

blUartWriteBytes(BL_UART_SCIREG_1, strlen("Finished writing to flash\r\n"),
blUartWriteBytes(BL_UART_SCIREG, strlen("Finished writing to flash\r\n"),
(uint8_t *)"Finished writing to flash\r\n");

state = BL_STATE_IDLE;
break;
}
case BL_STATE_ERASE_IMAGE: {
blUartWriteBytes(BL_UART_SCIREG_1, strlen("NOT IMPLEMENTED\r\n"), (uint8_t *)"NOT IMPLEMENTED\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("NOT IMPLEMENTED\r\n"), (uint8_t *)"NOT IMPLEMENTED\r\n");

// TODO: Erase entire application space

state = BL_STATE_IDLE;
break;
}
case BL_STATE_RUN_APP: {
blUartWriteBytes(BL_UART_SCIREG_1, strlen("Running application\r\n"), (uint8_t *)"Running application\r\n");
blUartWriteBytes(BL_UART_SCIREG, strlen("Running application\r\n"), (uint8_t *)"Running application\r\n");

// Go to the application's entry point
uint32_t appStartAddress = (uint32_t)APP_START_ADDRESS;
((appStartFunc_t)appStartAddress)();

blUartWriteBytes(BL_UART_SCIREG_1, strlen("Failed to run application\r\n"),
blUartWriteBytes(BL_UART_SCIREG, strlen("Failed to run application\r\n"),
(uint8_t *)"Failed to run application\r\n");

// TODO: Restart device if application fails to run or returns
Expand Down
5 changes: 5 additions & 0 deletions obc/bl/include/bl_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@
// The flash image of the bootloader must not be larger than this value.
//*****************************************************************************
#define APP_START_ADDRESS (uint32_t)0x00040000

// The start address of metadata, and the size (used in bl_flash.c and bl_main.c)

#define METADATA_START_ADDRESS (uint32_t)0x0013ffe0
#define METADATA_SIZE_BYTES ((uint32_t)0x00140000 - METADATA_START_ADDRESS)
1 change: 1 addition & 0 deletions obc/bl/include/bl_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ typedef enum {
// General errors
BL_ERR_CODE_INVALID_ARG = 1,
BL_ERR_CODE_UNKNOWN = 2,
// TODO: add more in depth error codes

// F021 Flash API errors
BL_ERR_CODE_FAPI_INIT = 100,
Expand Down
4 changes: 2 additions & 2 deletions obc/bl/include/bl_uart.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#pragma once

#include "obc_board_config.h"
#include <stdint.h>

typedef enum {
BL_UART_SCIREG_1 = 0,
BL_UART_SCIREG_2 = 1,
BL_UART_SCIREG = 0,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused why this enum needs to exist anymore since we only have (and will ever have?) 1 value

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yea i just added it from the old asynch logging PR. i can remove it

} bl_uart_reg_t;

/**
Expand Down
Loading
Loading