Skip to content

Commit

Permalink
[nrfconnect] Improved generation of the factory data
Browse files Browse the repository at this point in the history
Allow to merge the factory data .hex file with the firmware's .hex
file when partition manager is not available.
  • Loading branch information
ArekBalysNordic authored and kkasperczyk-no committed Apr 26, 2024
1 parent 1a0f4f2 commit 3594ca7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
5 changes: 2 additions & 3 deletions config/nrfconnect/chip-module/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ config CHIP_MALLOC_SYS_HEAP
config CHIP_FACTORY_DATA
bool "Factory data provider"
select ZCBOR
imply FPROTECT
help
Enables the default nRF Connect factory data provider implementation that
supports reading the factory data encoded in the CBOR format from the
Expand Down Expand Up @@ -147,9 +146,9 @@ config CHIP_FACTORY_DATA_ROTATING_DEVICE_UID_MAX_LEN

config CHIP_FACTORY_DATA_WRITE_PROTECT
bool "Enable Factory Data write protection"
imply FPROTECT
select FPROTECT
depends on CHIP_FACTORY_DATA
default y if SOC_SERIES_NRF53X || SOC_SERIES_NRF52X
default y
help
Enables the write protection of the Factory Data partition in the flash memory.
This is a recommended feature, but it requires the Settings partition size to be
Expand Down
31 changes: 24 additions & 7 deletions config/nrfconnect/chip-module/generate_factory_data.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,21 @@ set(factory_data_output_path ${output_path}/${factory_data_target})
string(APPEND script_args "-o \"${factory_data_output_path}\"\n")
string(APPEND script_args "-s \"${schema_path}\"\n")

# Add optional offset and size arguments to generate both .hex and .json files.
string(APPEND script_args "--offset $<TARGET_PROPERTY:partition_manager,PM_FACTORY_DATA_ADDRESS>\n")
string(APPEND script_args "--size $<TARGET_PROPERTY:partition_manager,PM_FACTORY_DATA_OFFSET>\n")
# Add optional offset and size arguments to generate .hex file as well as .json.
if(CONFIG_PARTITION_MANAGER_ENABLED)
string(APPEND script_args "--offset $<TARGET_PROPERTY:partition_manager,PM_FACTORY_DATA_ADDRESS>\n")
string(APPEND script_args "--size $<TARGET_PROPERTY:partition_manager,PM_FACTORY_DATA_OFFSET>\n")
else()
dt_alias(factory_data_alias PROPERTY "factory-data")
dt_node_exists(factory_data_exists PATH "${factory_data_alias}")
if(NOT ${factory_data_exists})
message(FATAL_ERROR "factory-data alias does not exist in DTS")
endif()
dt_reg_addr(factory_data_addr PATH ${factory_data_alias})
dt_reg_size(factory_data_size PATH ${factory_data_alias})
string(APPEND script_args "--offset ${factory_data_addr}\n")
string(APPEND script_args "--size ${factory_data_size}\n")
endif()

# execute first script to create a JSON file
separate_arguments(separated_script_args NATIVE_COMMAND ${script_args})
Expand Down Expand Up @@ -175,10 +187,15 @@ nrfconnect_create_factory_data(factory_data
${FACTORY_DATA_SCHEMA_PATH}
${OUTPUT_FILE_PATH})

if(CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE)
# set custom target for merging factory_data hex file
set_property(GLOBAL PROPERTY factory_data_PM_HEX_FILE ${OUTPUT_FILE_PATH}/factory_data.hex)
set_property(GLOBAL PROPERTY factory_data_PM_TARGET factory_data)
if(CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE)
if(CONFIG_PARTITION_MANAGER_ENABLED)
# set custom target for merging factory_data hex file
set_property(GLOBAL PROPERTY factory_data_PM_HEX_FILE ${OUTPUT_FILE_PATH}/factory_data.hex)
set_property(GLOBAL PROPERTY factory_data_PM_TARGET factory_data)
else()
set_property(GLOBAL APPEND PROPERTY HEX_FILES_TO_MERGE ${OUTPUT_FILE_PATH}/factory_data.hex ${OUTPUT_FILE_PATH}/zephyr.hex)
set_property(TARGET runners_yaml_props_target PROPERTY hex_file ${OUTPUT_FILE_PATH}/merged.hex)
endif()
endif()


Expand Down
8 changes: 4 additions & 4 deletions src/platform/nrfconnect/FactoryDataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,16 @@ struct InternalFlashFactoryData
// the application code at runtime anyway.
constexpr size_t FactoryDataBlockBegin()
{
// calculate the nearest multiple of CONFIG_FPROTECT_BLOCK_SIZE smaller than PM_FACTORY_DATA_ADDRESS
return PM_FACTORY_DATA_ADDRESS & (-CONFIG_FPROTECT_BLOCK_SIZE);
// calculate the nearest multiple of CONFIG_FPROTECT_BLOCK_SIZE smaller than FACTORY_DATA_ADDRESS
return FACTORY_DATA_ADDRESS & (-CONFIG_FPROTECT_BLOCK_SIZE);
}

constexpr size_t FactoryDataBlockSize()
{
// calculate the factory data end address rounded up to the nearest multiple of CONFIG_FPROTECT_BLOCK_SIZE
// and make sure we do not overlap with settings partition
constexpr size_t kFactoryDataBlockEnd =
(PM_FACTORY_DATA_ADDRESS + PM_FACTORY_DATA_SIZE + CONFIG_FPROTECT_BLOCK_SIZE - 1) & (-CONFIG_FPROTECT_BLOCK_SIZE);
(FACTORY_DATA_ADDRESS + FACTORY_DATA_SIZE + CONFIG_FPROTECT_BLOCK_SIZE - 1) & (-CONFIG_FPROTECT_BLOCK_SIZE);
static_assert(kFactoryDataBlockEnd <= PM_SETTINGS_STORAGE_ADDRESS,
"FPROTECT memory block, which contains factory data"
"partition overlaps with the settings partition."
Expand All @@ -88,7 +88,7 @@ struct InternalFlashFactoryData
CHIP_ERROR ProtectFactoryDataPartitionAgainstWrite()
{
#ifdef CONFIG_FPROTECT
int ret = fprotect_area(FACTORY_DATA_ADDRESS, FACTORY_DATA_SIZE);
int ret = fprotect_area(FactoryDataBlockBegin(), FactoryDataBlockSize());
return System::MapErrorZephyr(ret);
#else
return CHIP_ERROR_NOT_IMPLEMENTED;
Expand Down

0 comments on commit 3594ca7

Please sign in to comment.