Skip to content

Commit

Permalink
Merge pull request #224 from aabadie/bootloader
Browse files Browse the repository at this point in the history
Testbed: add bootloader application with examples
  • Loading branch information
aabadie authored Oct 25, 2023
2 parents 5ca5ad7 + 1fd0604 commit 5b43c37
Show file tree
Hide file tree
Showing 32 changed files with 1,012 additions and 30 deletions.
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,26 @@ else
PROJECTS ?= $(shell find projects/ -maxdepth 1 -mindepth 1 -type d | tr -d "/" | sed -e s/projects// | sort)
endif

TESTBED_APPS ?= $(shell find testbed/ -maxdepth 1 -mindepth 1 -type d | tr -d "/" | sed -e s/testbed// | sort)

# remove incompatible apps (nrf5340, sailbot gateway) for dotbot (v1, v2) builds
ifneq (,$(filter dotbot-v1,$(BUILD_TARGET)))
PROJECTS := $(filter-out 01bsp_qdec 01drv_move 03app_dotbot_gateway 03app_sailbot 03app_nrf5340_%,$(PROJECTS))
ARTIFACT_PROJECTS := 03app_dotbot
TESTBED_APPS := $(filter-out bootloader partition0 partition1,$(TESTBED_APPS))
endif

ifneq (,$(filter dotbot-v2,$(BUILD_TARGET)))
PROJECTS := $(filter-out 03app_dotbot_gateway 03app_sailbot 03app_nrf5340_net,$(PROJECTS))
ARTIFACT_PROJECTS := 03app_dotbot
TESTBED_APPS := $(filter-out bootloader partition0 partition1,$(TESTBED_APPS))
endif

# remove incompatible apps (nrf5340, dotbot, gateway) for sailbot-v1 build
ifeq (sailbot-v1,$(BUILD_TARGET))
PROJECTS := $(filter-out 01bsp_qdec 01drv_move 03app_dotbot_gateway 03app_dotbot 03app_nrf5340_%,$(PROJECTS))
ARTIFACT_PROJECTS := 03app_sailbot
TESTBED_APPS := $(filter-out bootloader partition0 partition1,$(TESTBED_APPS))
endif

# remove incompatible apps (nrf5340) for nrf52833dk/nrf52840dk build
Expand All @@ -91,13 +96,18 @@ ARTIFACTS = $(ARTIFACT_ELF) $(ARTIFACT_HEX)

.PHONY: $(PROJECTS) $(ARTIFACT_PROJECTS) artifacts docker docker-release format check-format

all: $(PROJECTS)
all: $(PROJECTS) $(TESTBED_APPS)

$(PROJECTS):
@echo "\e[1mBuilding project $@\e[0m"
"$(SEGGER_DIR)/bin/emBuild" $(PROJECT_FILE) -project $@ -config $(BUILD_CONFIG) $(PACKAGES_DIR_OPT) -rebuild -verbose
@echo "\e[1mDone\e[0m\n"

$(TESTBED_APPS):
@echo "\e[1mBuilding testbed application $@\e[0m"
"$(SEGGER_DIR)/bin/emBuild" $(PROJECT_FILE) -project $@ -config Release $(PACKAGES_DIR_OPT) -rebuild -verbose
@echo "\e[1mDone\e[0m\n"

list-projects:
@echo "\e[1mAvailable projects:\e[0m"
@echo $(PROJECTS) | tr ' ' '\n'
Expand Down
25 changes: 17 additions & 8 deletions bsp/bsp.emProject
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,6 @@
<file file_name="nrf/motors.c" />
<file file_name="motors.h" />
</project>
<project Name="00bsp_nvmc">
<configuration
Name="Common"
project_directory="."
project_type="Library" />
<file file_name="nrf/nvmc.c" />
<file file_name="nvmc.h" />
</project>
<project Name="00bsp_dotbot_rgbled">
<configuration
Name="Common"
Expand Down Expand Up @@ -82,6 +74,23 @@
<file file_name="nrf/i2c.c" />
<file file_name="i2c.h" />
</project>
<project Name="00bsp_nvmc">
<configuration
Name="Common"
project_directory="."
project_type="Library" />
<file file_name="nrf/nvmc.c" />
<file file_name="nvmc.h" />
</project>
<project Name="00bsp_partition">
<configuration
Name="Common"
project_dependencies=""
project_directory="."
project_type="Library" />
<file file_name="nrf/partition.c" />
<file file_name="partition.h" />
</project>
<project Name="00bsp_pwm">
<configuration
Name="Common"
Expand Down
59 changes: 59 additions & 0 deletions bsp/nrf/partition.c
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);
}
47 changes: 47 additions & 0 deletions bsp/partition.h
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
45 changes: 27 additions & 18 deletions drv/drv.emProject
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@
<file file_name="protocol.c" />
<file file_name="../protocol.h" />
</project>
<project Name="00drv_imu">
<configuration
Name="Common"
project_dependencies="00drv_lis2mdl(drv);00drv_lsm6ds(drv)"
project_directory="imu"
project_type="Library" />
<file file_name="imu.c" />
<file file_name="../imu.h" />
</project>
<project Name="00drv_ism330">
<configuration
Name="Common"
Expand All @@ -40,24 +49,6 @@
<file file_name="lis2mdl.c" />
<file file_name="../lis2mdl.h" />
</project>
<project Name="00drv_lsm6ds">
<configuration
Name="Common"
project_dependencies="00bsp_i2c(bsp);00bsp_gpio(bsp)"
project_directory="lsm6ds"
project_type="Library" />
<file file_name="lsm6ds.c" />
<file file_name="../lsm6ds.h" />
</project>
<project Name="00drv_imu">
<configuration
Name="Common"
project_dependencies="00drv_lis2mdl(drv);00drv_lsm6ds(drv)"
project_directory="imu"
project_type="Library" />
<file file_name="imu.c" />
<file file_name="../imu.h" />
</project>
<project Name="00drv_log_flash">
<configuration
Name="Common"
Expand All @@ -67,6 +58,15 @@
<file file_name="log_flash/log_flash.c" />
<file file_name="log_flash.h" />
</project>
<project Name="00drv_lsm6ds">
<configuration
Name="Common"
project_dependencies="00bsp_i2c(bsp);00bsp_gpio(bsp)"
project_directory="lsm6ds"
project_type="Library" />
<file file_name="lsm6ds.c" />
<file file_name="../lsm6ds.h" />
</project>
<project Name="00drv_move">
<configuration
Name="Common"
Expand All @@ -76,6 +76,15 @@
<file file_name="move/move.c" />
<file file_name="move.h" />
</project>
<project Name="00drv_ota">
<configuration
Name="Common"
project_dependencies="00bsp_partition(bsp);00bsp_nvmc(bsp)"
project_directory="ota"
project_type="Library" />
<file file_name="ota.c" />
<file file_name="../ota.h" />
</project>
<project Name="00drv_pid">
<configuration
Name="Common"
Expand Down
46 changes: 46 additions & 0 deletions drv/ota.h
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
54 changes: 54 additions & 0 deletions drv/ota/ota.c
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);
}
3 changes: 2 additions & 1 deletion nrf52833dk.emProject
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
link_time_optimization="No"
linker_memory_map_file="$(PackagesDir)/nRF/XML/nRF52833_xxAA_MemoryMap.xml"
linker_output_format="hex"
macros="BuildTarget=nrf52833dk;Lh2ImplementationFile=lh2.c;PwmImplementationFile=pwm.c;RadioImplementationFile=radio.c;RngImplementationFile=rng.c;DeviceHeaderFile=$(PackagesDir)/nRF/Device/Include/nrf52833.h;DeviceCommonHeaderFile=$(PackagesDir)/nRF/Device/Include/nrf.h;DeviceSystemFile=$(PackagesDir)/nRF/Device/Source/system_nrf52.c;DeviceVectorsFile=$(PackagesDir)/nRF/Source/nrf52833_Vectors.s;DeviceCommonVectorsFile=$(PackagesDir)/nRF/Source/nRF_Startup.s;SeggerThumbStartup=$(ProjectDir)/../../../nRF/SEGGER_THUMB_Startup.s;DeviceLinkerScript=$(ProjectDir)/../../../nRF/nrf5340/nRF_Flash_Variant1.icf;DeviceMemoryMap=$(PackagesDir)/nRF/XML/nRF52840_xxAA_MemoryMap.xml;DeviceLibraryIdentifier=M4lf;DeviceFamily=nRF;Target=nRF52833_xxAA;Placement=Flash"
macros="BuildTarget=nrf52833dk;Lh2ImplementationFile=lh2.c;PwmImplementationFile=pwm.c;RadioImplementationFile=radio.c;RngImplementationFile=rng.c;DeviceHeaderFile=$(PackagesDir)/nRF/Device/Include/nrf52833.h;DeviceCommonHeaderFile=$(PackagesDir)/nRF/Device/Include/nrf.h;DeviceSystemFile=$(PackagesDir)/nRF/Device/Source/system_nrf52.c;DeviceVectorsFile=$(PackagesDir)/nRF/Source/nrf52833_Vectors.s;DeviceCommonVectorsFile=$(PackagesDir)/nRF/Source/nRF_Startup.s;SeggerThumbStartup=$(ProjectDir)/../../../nRF/SEGGER_THUMB_Startup.s;DeviceLinkerScript=$(ProjectDir)/../../../nRF/nrf5340/nRF_Flash_Variant1.icf;DeviceMemoryMap=$(PackagesDir)/nRF/XML/nRF52833_xxAA_MemoryMap.xml;DeviceLibraryIdentifier=M4lf;DeviceFamily=nRF;Target=nRF52833_xxAA;Placement=Flash"
project_type="Executable"
target_reset_script="Reset();"
target_trace_initialize_script="EnableTrace(&quot;$(TraceInterfaceType)&quot;)" />
Expand All @@ -61,4 +61,5 @@
<import file_name="projects/projects-gateway.emProject" />
<import file_name="projects/projects-log-dump.emProject" />
<import file_name="projects/projects-sailbot.emProject" />
<import file_name="testbed/testbed.emProject" />
</solution>
1 change: 1 addition & 0 deletions nrf52840dk.emProject
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@
<import file_name="projects/projects-gateway.emProject" />
<import file_name="projects/projects-log-dump.emProject" />
<import file_name="projects/projects-sailbot.emProject" />
<import file_name="testbed/testbed.emProject" />
</solution>
1 change: 1 addition & 0 deletions nrf5340dk-app.emProject
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@
<import file_name="projects/projects-log-dump.emProject" />
<import file_name="projects/projects-sailbot.emProject" />
<import file_name="projects/projects-nrf5340-app.emProject" />
<import file_name="testbed/testbed.emProject" />
</solution>
Loading

0 comments on commit 5b43c37

Please sign in to comment.