Skip to content

Commit

Permalink
Merge pull request #1325 from spark/feature/bootloader_dct
Browse files Browse the repository at this point in the history
Minimize DCT usage in bootloader
  • Loading branch information
technobly committed May 10, 2017
2 parents 0a9e4aa + fe0c8fa commit aa22f1a
Show file tree
Hide file tree
Showing 315 changed files with 80,868 additions and 2,616 deletions.
2 changes: 0 additions & 2 deletions bootloader/build.mk
Expand Up @@ -5,10 +5,8 @@ ASRC += $(COMMON_BUILD)/arm/startup/startup_$(STM32_DEVICE_LC).S
ASFLAGS += -I$(COMMON_BUILD)/arm/startup

# Linker flags
LDFLAGS += -T$(COMMON_BUILD)/arm/linker/linker_$(STM32_DEVICE_LC).ld
LDFLAGS += -Wl,-Map,$(TARGET_BASE).map

LINKER_DEPS += $(COMMON_BUILD)/arm/linker/linker_$(STM32_DEVICE_LC).ld
LINKER_DEPS += $(COMMON_BUILD)/arm/linker/module_start.ld
LINKER_DEPS += $(COMMON_BUILD)/arm/linker/module_end.ld
LINKER_DEPS += $(COMMON_BUILD)/arm/linker/module_info.ld
Expand Down
2 changes: 2 additions & 0 deletions bootloader/makefile
Expand Up @@ -12,6 +12,8 @@ LIB_DIRS += $(dir $(LIB_DEPS))

export COMPILE_LTO=y

export BOOTLOADER_MODULE=1

include ../build/platform-id.mk

# Target this makefile is building.
Expand Down
3 changes: 3 additions & 0 deletions bootloader/src/core/sources.mk
@@ -1,3 +1,6 @@
BOOTLOADER_SRC_COREV1_PATH = $(BOOTLOADER_MODULE_PATH)/src/core

CSRC += $(call target_files,$(BOOTLOADER_SRC_COREV1_PATH)/,*.c)

LDFLAGS += -T$(COMMON_BUILD)/arm/linker/linker_$(STM32_DEVICE_LC).ld
LINKER_DEPS += $(COMMON_BUILD)/arm/linker/linker_$(STM32_DEVICE_LC).ld
7 changes: 7 additions & 0 deletions bootloader/src/electron/bootloader_dct.c
@@ -0,0 +1,7 @@
int dct_lock(int write) {
return 0;
}

int dct_unlock(int write) {
return 0;
}
6 changes: 4 additions & 2 deletions bootloader/src/electron/sources.mk
Expand Up @@ -3,7 +3,9 @@ include $(BOOTLOADER_MODULE_PATH)/src/stm32f2xx/sources.mk

CSRC += $(call target_files,$(BOOTLOADER_SRC_ELECTRON_PATH)/,*.c)

CSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/electron/,dct_hal.c)
CSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/electron/,watchdog_hal.c)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/electron/,dcd_hal.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/electron/,dct_hal.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/stm32/,newlib.cpp)

LDFLAGS += -L$(PROJECT_ROOT)/modules/electron/user-part
LINKER_DEPS += $(PROJECT_ROOT)/modules/electron/user-part/module_user_memory.ld
2 changes: 1 addition & 1 deletion bootloader/src/electron/startup.c
Expand Up @@ -17,7 +17,7 @@
******************************************************************************
*/

#include "dcd_flash.h"
#include "dct_hal.h"

void platform_startup()
{
Expand Down
13 changes: 11 additions & 2 deletions bootloader/src/main.c
Expand Up @@ -31,9 +31,14 @@
#include "rgbled.h"
#include "button.h"

#if (PLATFORM_ID == 6) || (PLATFORM_ID == 10) || (PLATFORM_ID == 8)
#include "led_signal.h"
#if PLATFORM_ID == 6 || PLATFORM_ID == 8
#define LOAD_DCT_FUNCTIONS
#include "bootloader_dct.h"
#endif

#if PLATFORM_ID == 6 || PLATFORM_ID == 10 || PLATFORM_ID == 8
#define USE_LED_THEME
#include "led_signal.h"
#endif

void platform_startup();
Expand Down Expand Up @@ -386,6 +391,10 @@ int main(void)
* Currently FLASH_UPDATE_MODULES support is enabled only on BM-09 bootloader
*/
FLASH_UpdateModules(flashModulesCallback);
#ifdef LOAD_DCT_FUNCTIONS
// DCT functions may need to be reloaded after updating a system module
load_dct_functions();
#endif
#else
if (REFLASH_FROM_BACKUP == 1)
{
Expand Down
145 changes: 145 additions & 0 deletions bootloader/src/photon/bootloader_dct.c
@@ -0,0 +1,145 @@
#include "bootloader_dct.h"

#include "flash_mal.h"

#include <string.h>
#include <stdint.h>
#include <stddef.h>

#include "../../../hal/src/stm32f2xx/dct_hal_stm32f2xx.h"

#define MODULAR_FIRMWARE 1
#include "../../../hal/src/photon/ota_module_bounds.c"

#define MIN_MODULE_VERSION_SYSTEM_PART2 200 // 0.7.0-rc.1

#define DYNALIB_INDEX_SYSTEM_MODULE_PART1 2 // system_module_part1
#define FUNC_INDEX_MODULE_SYSTEM_PART1_PRE_INIT 0 // module_system_part1_pre_init()

#define DYNALIB_INDEX_SYSTEM_MODULE_PART2 19 // system_module_part2
#define FUNC_INDEX_MODULE_SYSTEM_PART2_PRE_INIT 0 // module_system_part2_pre_init()

#define DYNALIB_INDEX_HAL_DCT 18 // hal_dct
#define FUNC_INDEX_DCT_READ_APP_DATA 0 // dct_read_app_data()
#define FUNC_INDEX_DCT_WRITE_APP_DATA 4 // dct_write_app_data()
#define FUNC_INDEX_DCT_SET_LOCK_ENABLED 5 // dct_set_lock_enabled()

typedef const void*(*dct_read_app_data_func_t)(uint32_t);
typedef int(*dct_write_app_data_func_t)(const void*, uint32_t, uint32_t);
typedef void(*dct_set_lock_enabled_func_t)(int);
typedef void*(*module_pre_init_func_t)();

static dct_read_app_data_func_t dct_read_app_data_func = NULL;
static dct_write_app_data_func_t dct_write_app_data_func = NULL;
static uint8_t dct_funcs_inited = 0;

static const module_info_t* get_module_info(const module_bounds_t* bounds, uint16_t min_version) {
const module_info_t* module = FLASH_ModuleInfo(FLASH_INTERNAL, bounds->start_address);
// Check primary module info
if (!module || module->platform_id != PLATFORM_ID || module->module_function != bounds->module_function ||
module->module_index != bounds->module_index || module->module_version < min_version) {
return NULL;
}
// Check module boundaries
const uintptr_t startAddr = (uintptr_t)module->module_start_address;
const uintptr_t endAddr = (uintptr_t)module->module_end_address;
if (endAddr < startAddr || startAddr != bounds->start_address || endAddr > bounds->end_address) {
return NULL;
}
// Verify checksum
if (!FLASH_VerifyCRC32(FLASH_INTERNAL, startAddr, endAddr - startAddr)) {
return NULL;
}
return module;
}

static const void* get_module_func(const module_info_t* module, size_t dynalib_index, size_t func_index) {
// Get dynalib table
void*** module_table = (void***)((const char*)module + sizeof(module_info_t));
void** dynalib = module_table[dynalib_index];
// Get function address
void* func = dynalib[func_index];
if (func < module->module_start_address || func >= module->module_end_address) {
return NULL;
}
return func;
}

static void init_dct_functions() {
dct_read_app_data_func = NULL;
dct_write_app_data_func = NULL;
const module_info_t* part2 = get_module_info(&module_system_part2, MIN_MODULE_VERSION_SYSTEM_PART2);
if (!part2) {
return;
}
// Part2 should contain complete DCT implementation, but it's easy to introduce an additional
// dependency during development, so we require part1 to be consistent as well
const module_info_t* part1 = get_module_info(&module_system_part1, part2->dependency.module_version);
if (!part1 || part1->dependency.module_function != MODULE_FUNCTION_NONE) {
return;
}
// Get addresses of the DCT functions
dct_read_app_data_func_t dct_read = get_module_func(part2, DYNALIB_INDEX_HAL_DCT, FUNC_INDEX_DCT_READ_APP_DATA);
dct_write_app_data_func_t dct_write = get_module_func(part2, DYNALIB_INDEX_HAL_DCT, FUNC_INDEX_DCT_WRITE_APP_DATA);
dct_set_lock_enabled_func_t dct_set_lock_enabled = get_module_func(part2, DYNALIB_INDEX_HAL_DCT, FUNC_INDEX_DCT_SET_LOCK_ENABLED);
if (!dct_read || !dct_write || !dct_set_lock_enabled) {
return;
}
// Initialize static data of each module
module_pre_init_func_t part1_init = get_module_func(part1, DYNALIB_INDEX_SYSTEM_MODULE_PART1,
FUNC_INDEX_MODULE_SYSTEM_PART1_PRE_INIT);
module_pre_init_func_t part2_init = get_module_func(part2, DYNALIB_INDEX_SYSTEM_MODULE_PART2,
FUNC_INDEX_MODULE_SYSTEM_PART2_PRE_INIT);
if (!part1_init || !part2_init) {
return;
}
part1_init();
part2_init();
// Disable global DCT lock
dct_set_lock_enabled(0);
dct_read_app_data_func = dct_read;
dct_write_app_data_func = dct_write;
}

void load_dct_functions() {
dct_funcs_inited = 0;
}

const void* dct_read_app_data(uint32_t offset) {
if (!dct_funcs_inited) {
init_dct_functions();
dct_funcs_inited = 1;
}
if (dct_read_app_data_func) {
return dct_read_app_data_func(offset);
}
return NULL;
}

int dct_write_app_data(const void* data, uint32_t offset, uint32_t size) {
if (!dct_funcs_inited) {
init_dct_functions();
dct_funcs_inited = 1;
}
if (dct_write_app_data_func) {
return dct_write_app_data_func(data, offset, size);
}
return -1;
}

int dct_read_app_data_copy(uint32_t offset, void* ptr, size_t size) {
const void* data = dct_read_app_data(offset);
if (!data) {
return -1;
}
memcpy(ptr, data, size);
return 0;
}

const void* dct_read_app_data_lock(uint32_t offset) {
return dct_read_app_data(offset);
}

int dct_read_app_data_unlock(uint32_t offset) {
return 0;
}
6 changes: 6 additions & 0 deletions bootloader/src/photon/bootloader_dct.h
@@ -0,0 +1,6 @@
#ifndef BOOTLOADER_DCT_H
#define BOOTLOADER_DCT_H

void load_dct_functions();

#endif // BOOTLOADER_DCT_H
11 changes: 0 additions & 11 deletions bootloader/src/photon/dct_hal.c

This file was deleted.

4 changes: 3 additions & 1 deletion bootloader/src/photon/sources.mk
Expand Up @@ -3,11 +3,13 @@ include $(BOOTLOADER_MODULE_PATH)/src/stm32f2xx/sources.mk

CSRC += $(call target_files,$(BOOTLOADER_SRC_COREV2_PATH)/,*.c)


HAL_LIB_COREV2 = $(HAL_SRC_COREV2_PATH)/lib
WICED_LIBS = Platform_$(PLATFORM_NET) SPI_Flash_Library_$(PLATFORM_NET)

WICED_LIB_FILES = $(addprefix $(HAL_LIB_COREV2)/,$(addsuffix .a,$(WICED_LIBS)))
WICED_LIB_FILES = $(HAL_LIB_COREV2)/FreeRTOS/STM32F2xx_bootloader.a

LIBS_EXT += -Wl,--whole-archive $(WICED_LIB_FILES) -Wl,--no-whole-archive

LDFLAGS += -L$(PROJECT_ROOT)/modules/photon/user-part
LINKER_DEPS += $(PROJECT_ROOT)/modules/photon/user-part/module_user_memory.ld
6 changes: 4 additions & 2 deletions bootloader/src/stm32f2xx/button.c
Expand Up @@ -63,9 +63,9 @@ int BUTTON_Debounce() {
}

void BUTTON_Init_Ext() {
const button_config_t* conf = (const button_config_t*)dct_read_app_data(DCT_MODE_BUTTON_MIRROR_OFFSET);
const button_config_t* conf = (const button_config_t*)dct_read_app_data_lock(DCT_MODE_BUTTON_MIRROR_OFFSET);

if (conf->active == 0xAA && conf->debounce_time == 0xBBCC) {
if (conf && conf->active == 0xAA && conf->debounce_time == 0xBBCC) {
//int32_t state = HAL_disable_irq();
memcpy((void*)&HAL_Buttons[BUTTON1_MIRROR], (void*)conf, sizeof(button_config_t));
HAL_Buttons[BUTTON1_MIRROR].active = 0;
Expand All @@ -74,6 +74,8 @@ void BUTTON_Init_Ext() {
//HAL_enable_irq(state);
}

dct_read_app_data_unlock(DCT_MODE_BUTTON_MIRROR_OFFSET);

if (BUTTON_Debounce())
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
}
Expand Down
12 changes: 12 additions & 0 deletions bootloader/src/stm32f2xx/concurrent_hal.c
@@ -0,0 +1,12 @@

int os_thread_yield() {
return 0;
}

void __flash_acquire() {

}

void __flash_release() {

}
3 changes: 2 additions & 1 deletion bootloader/src/stm32f2xx/led_signal.c
Expand Up @@ -19,10 +19,11 @@ static uint32_t led_signal_color(int signal, const uint8_t* data) {

void get_led_theme_colors(uint32_t* firmware_update, uint32_t* safe_mode, uint32_t* dfu_mode) {
// Check if theme data is initialized in DCT
const uint8_t* d = (const char*)dct_read_app_data(DCT_LED_THEME_OFFSET);
const uint8_t* d = (const uint8_t*)dct_read_app_data_lock(DCT_LED_THEME_OFFSET);
if (d && *d == LED_SIGNAL_THEME_VERSION) {
*firmware_update = led_signal_color(LED_SIGNAL_FIRMWARE_UPDATE, d);
*safe_mode = led_signal_color(LED_SIGNAL_SAFE_MODE, d);
*dfu_mode = led_signal_color(LED_SIGNAL_DFU_MODE, d);
}
dct_read_app_data_unlock(DCT_LED_THEME_OFFSET);
}
2 changes: 2 additions & 0 deletions bootloader/src/stm32f2xx/sources.mk
Expand Up @@ -2,3 +2,5 @@ BOOTLOADER_SRC_STM32F2XX_PATH = $(BOOTLOADER_MODULE_PATH)/src/stm32f2xx

CSRC += $(call target_files,$(BOOTLOADER_SRC_STM32F2XX_PATH)/,*.c)

LDFLAGS += -T$(COMMON_BUILD)/arm/linker/linker_$(STM32_DEVICE_LC)_bootloader.ld
LINKER_DEPS += $(COMMON_BUILD)/arm/linker/linker_$(STM32_DEVICE_LC)_bootloader.ld
30 changes: 30 additions & 0 deletions build/arm/linker/linker_stm32f2xx_bootloader.ld
@@ -0,0 +1,30 @@
/* Default stack sizes. These are used by the startup in order to allocate stacks for the
different modes. */
__Stack_Size = 2048;
__Stack_Init = _estack - __Stack_Size;

/* There will be a link error if there is not this amount of RAM free at the end. */
_Minimum_Stack_Size = 0x1400;

/* Memory Spaces Definitions */

INCLUDE module_user_memory.ld

/* Ensure RAM region doesn't overlap with the system modules, since the bootloader imports
dynalib functions dynamically on certain platforms */
bootloader_ram_length = 16K;
bootloader_ram_offset = 8K;
bootloader_ram_origin = user_module_sram_origin + bootloader_ram_offset;
ASSERT(bootloader_ram_offset + bootloader_ram_length <= user_module_sram_length,
"Insufficient space for RAM region");

MEMORY
{
RAM (xrw) : ORIGIN = bootloader_ram_origin, LENGTH = bootloader_ram_length
APP_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K
DCT1_FLASH (rx) : ORIGIN = 0x08004000, LENGTH = 16K
DCT2_FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 16K
INCLUDE backup_ram_memory.ld
}

INCLUDE linker_stm32f2xx_common.ld
1 change: 1 addition & 0 deletions hal-dynalib/src/hal_dct.c
@@ -0,0 +1 @@
#include "hal_dynalib_dct.h"
3 changes: 1 addition & 2 deletions hal/inc/hal_dynalib_concurrent.h
Expand Up @@ -61,8 +61,7 @@ DYNALIB_FN(24, hal_concurrent, os_queue_destroy, int(os_queue_t, void*))
DYNALIB_FN(25, hal_concurrent, os_queue_put, int(os_queue_t, const void* item, system_tick_t, void*))
DYNALIB_FN(26, hal_concurrent, os_queue_take, int(os_queue_t, void* item, system_tick_t, void*))
DYNALIB_FN(27, hal_concurrent, os_thread_exit, os_result_t(os_thread_t))

#endif
#endif // PLATFORM_THREADING

DYNALIB_END(hal_concurrent)

Expand Down
18 changes: 18 additions & 0 deletions hal/inc/hal_dynalib_dct.h
@@ -0,0 +1,18 @@
#pragma once

#include "dynalib.h"

#ifdef DYNALIB_EXPORT
#include "dct_hal.h"
#endif

DYNALIB_BEGIN(hal_dct)

DYNALIB_FN(0, hal_dct, dct_read_app_data, const void*(uint32_t))
DYNALIB_FN(1, hal_dct, dct_read_app_data_copy, int(uint32_t, void*, size_t))
DYNALIB_FN(2, hal_dct, dct_read_app_data_lock, const void*(uint32_t))
DYNALIB_FN(3, hal_dct, dct_read_app_data_unlock, int(uint32_t))
DYNALIB_FN(4, hal_dct, dct_write_app_data, int(const void*, uint32_t, uint32_t))
DYNALIB_FN(5, hal_dct, dct_set_lock_enabled, void(int))

DYNALIB_END(hal_dct)
1 change: 1 addition & 0 deletions hal/src/electron/FreeRTOSConfig.h
Expand Up @@ -119,6 +119,7 @@
#define configUSE_RECURSIVE_MUTEXES 1
#define configENABLE_BACKWARD_COMPATIBILITY 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configSUPPORT_STATIC_ALLOCATION 1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
Expand Down
2 changes: 1 addition & 1 deletion hal/src/electron/core_hal.c
Expand Up @@ -29,7 +29,7 @@
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "dcd_flash.h"
#include "dct_hal.h"

/* Private typedef ----------------------------------------------------------*/

Expand Down

0 comments on commit aa22f1a

Please sign in to comment.