-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #224 from aabadie/bootloader
Testbed: add bootloader application with examples
- Loading branch information
Showing
32 changed files
with
1,012 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/** | ||
* @file partition.c | ||
* @addtogroup BSP | ||
* | ||
* @brief Implementation of the "partition" bsp module. | ||
* | ||
* @author Alexandre Abadie <[email protected]> | ||
* | ||
* @copyright Inria, 2023 | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
|
||
#include "nrf.h" | ||
#include "nvmc.h" | ||
#include "partition.h" | ||
|
||
//=========================== defines ========================================= | ||
|
||
//=========================== defines ========================================= | ||
|
||
#if defined(NRF5340_XXAA) && defined(NRF_APPLICATION) | ||
#define NRF_NVMC NRF_NVMC_S | ||
#elif defined(NRF5340_XXAA) && defined(NRF_NETWORK) | ||
#define NRF_NVMC NRF_NVMC_NS | ||
#endif | ||
|
||
#define DB_PARTITIONS_TABLE_ADDRESS (0x00001000UL + DB_FLASH_OFFSET) | ||
|
||
//=========================== public ========================================== | ||
|
||
void db_read_partitions_table(db_partitions_table_t *partitions) { | ||
memcpy((void *)partitions, (uint32_t *)DB_PARTITIONS_TABLE_ADDRESS, sizeof(db_partitions_table_t)); | ||
} | ||
|
||
void db_write_partitions_table(const db_partitions_table_t *partitions) { | ||
uint32_t *addr = (uint32_t *)DB_PARTITIONS_TABLE_ADDRESS; | ||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos); | ||
#if defined(NRF5340_XXAA) | ||
*(uint32_t *)addr = 0xFFFFFFFF; | ||
#else | ||
NRF_NVMC->ERASEPAGE = (uint32_t)addr; | ||
#endif | ||
while (!NRF_NVMC->READY) {} | ||
|
||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); | ||
*addr++ = partitions->magic; | ||
*addr++ = partitions->length; | ||
*addr++ = partitions->active_image; | ||
for (uint32_t i = 0; i < partitions->length; i++) { | ||
*addr++ = partitions->partitions[i].address; | ||
*addr++ = partitions->partitions[i].size; | ||
} | ||
|
||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#ifndef __PARTITION_H | ||
#define __PARTITION_H | ||
|
||
/** | ||
* @file partition.h | ||
* @addtogroup BSP | ||
* | ||
* @brief Cross-platform declaration "partition" bsp module. | ||
* | ||
* @author Alexandre Abadie <[email protected]> | ||
* | ||
* @copyright Inria, 2023 | ||
*/ | ||
|
||
#include <stdint.h> | ||
#include <string.h> | ||
|
||
#include <nrf.h> | ||
|
||
#define DB_PARTITIONS_TABLE_MAGIC (0xD07B0723UL) ///< Magic number used at the beginning of the partition table | ||
#define DB_PARTITIONS_MAX_COUNT (4U) ///< Maximum number of available partitions | ||
|
||
typedef struct { | ||
uint32_t address; ///< Start address of a partition | ||
uint32_t size; ///< Size of the partition | ||
} db_partition_t; | ||
|
||
typedef struct { | ||
uint32_t magic; ///< Magic number | ||
uint32_t length; ///< Current number of partitions in the table | ||
uint32_t active_image; ///< Active image to boot on | ||
db_partition_t partitions[DB_PARTITIONS_MAX_COUNT]; ///< List of partitions | ||
} db_partitions_table_t; | ||
|
||
/** | ||
* @brief Read partition table on flash | ||
* @param data Pointer to the runtime partition table | ||
*/ | ||
void db_read_partitions_table(db_partitions_table_t *partitions); | ||
|
||
/** | ||
* @brief Write partition table on flash | ||
* @param data Pointer to the runtime partition table | ||
*/ | ||
void db_write_partitions_table(const db_partitions_table_t *partitions); | ||
|
||
#endif // __PARTITION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#ifndef __OTA_H | ||
#define __OTA_H | ||
|
||
/** | ||
* @file ota.h | ||
* @addtogroup BSP | ||
* | ||
* @brief Cross-platform declaration "ota" drv module. | ||
* | ||
* @author Alexandre Abadie <[email protected]> | ||
* | ||
* @copyright Inria, 2023 | ||
*/ | ||
|
||
#include <stdint.h> | ||
|
||
//=========================== defines ========================================== | ||
|
||
#define DB_OTA_CHUNK_SIZE (32U) | ||
|
||
typedef struct __attribute__((packed, aligned(4))) { | ||
uint32_t index; | ||
uint32_t chunk_count; | ||
uint8_t fw_chunk[DB_OTA_CHUNK_SIZE]; | ||
} db_ota_pkt_t; | ||
|
||
//=========================== prototypes ======================================= | ||
|
||
/** | ||
* @brief Start the OTA process | ||
*/ | ||
void db_ota_start(void); | ||
|
||
/** | ||
* @brief Finalize the OTA process: switch the active partition and reboot | ||
*/ | ||
void db_ota_finish(void); | ||
|
||
/** | ||
* @brief Write a chunk of the firmware on the inactive partition | ||
* | ||
* @param[in] pkt Pointer the OTA packet | ||
*/ | ||
void db_ota_write_chunk(const db_ota_pkt_t *pkt); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** | ||
* @file ota.c | ||
* @addtogroup DRV | ||
* | ||
* @brief nRF52833-specific definition of the "ota" drv module. | ||
* | ||
* @author Alexandre Abadie <[email protected]> | ||
* | ||
* @copyright Inria, 2023 | ||
*/ | ||
#include <nrf.h> | ||
#include <assert.h> | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
|
||
#include "nvmc.h" | ||
#include "ota.h" | ||
#include "partition.h" | ||
|
||
//=========================== defines ========================================== | ||
|
||
typedef struct { | ||
db_partitions_table_t table; | ||
uint32_t slot; | ||
uint32_t addr; | ||
} db_ota_vars_t; | ||
|
||
//=========================== variables ======================================== | ||
|
||
static db_ota_vars_t _ota_vars = { 0 }; | ||
|
||
//============================ public ========================================== | ||
|
||
void db_ota_start(void) { | ||
db_read_partitions_table(&_ota_vars.table); | ||
_ota_vars.slot = (_ota_vars.table.active_image + 1) % 2; | ||
_ota_vars.addr = _ota_vars.table.partitions[_ota_vars.slot].address; | ||
} | ||
|
||
void db_ota_finish(void) { | ||
// Switch active image in partition table before resetting the device | ||
// TODO: do more verifications (CRC, etc) before rebooting | ||
_ota_vars.table.active_image = _ota_vars.slot; | ||
db_write_partitions_table(&_ota_vars.table); | ||
NVIC_SystemReset(); | ||
} | ||
|
||
void db_ota_write_chunk(const db_ota_pkt_t *pkt) { | ||
uint32_t addr = _ota_vars.addr + pkt->index * DB_OTA_CHUNK_SIZE; | ||
if (addr % DB_FLASH_PAGE_SIZE == 0) { | ||
db_nvmc_page_erase(addr / DB_FLASH_PAGE_SIZE); | ||
} | ||
db_nvmc_write((uint32_t *)addr, pkt->fw_chunk, DB_OTA_CHUNK_SIZE); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.