-
Notifications
You must be signed in to change notification settings - Fork 17
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
base: main
Are you sure you want to change the base?
Add flash metadata #308
Changes from all commits
ce2aa32
51e973b
5fa7234
956aab2
b5507f6
d0ec9fc
8b2d559
29807bf
93661af
93a2751
2814b18
81a5f7c
f924c11
a67cab2
aaa9f3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
} |
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); |
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> | ||
|
||
|
@@ -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); | ||
|
@@ -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 { | ||
|
@@ -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; | ||
|
@@ -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"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
|
@@ -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}; | ||
|
@@ -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 | ||
|
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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
|
||
/** | ||
|
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldve been merged