build(core): added initial builds for ble_bootloader and ble_firmware

tychovrahe/bluetooth/master
tychovrahe 1 year ago
parent 0aa1512446
commit a8e889afd2

2
core/.gitignore vendored

@ -10,3 +10,5 @@ htmlcov/
mypy_report
/CMakeLists.txt
/cmake-build-debug/
/embed/ble_bootloader/jlink.jdebug.user
/embed/ble_firmware/jlink.jdebug.user

@ -5,6 +5,8 @@ MAKE = make -j $(JOBS)
SCONS = scons -Q -j $(JOBS)
BUILD_DIR = build
BLE_BOOTLOADER_BUILD_DIR = $(BUILD_DIR)/ble_bootloader
BLE_FIRMWARE_BUILD_DIR = $(BUILD_DIR)/ble_firmware
BOARDLOADER_BUILD_DIR = $(BUILD_DIR)/boardloader
BOOTLOADER_BUILD_DIR = $(BUILD_DIR)/bootloader
BOOTLOADER_CI_BUILD_DIR = $(BUILD_DIR)/bootloader_ci
@ -168,6 +170,13 @@ build: build_boardloader build_bootloader build_firmware build_prodtest build_un
build_embed: build_boardloader build_bootloader build_firmware # build boardloader, bootloader, firmware
build_ble_bootloader: ## build ble_bootloader
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" $(BLE_BOOTLOADER_BUILD_DIR)/ble_bootloader.bin
build_ble_firmware: ## build ble_firmware
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" $(BLE_FIRMWARE_BUILD_DIR)/ble_firmware.bin
build_boardloader: ## build boardloader
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" $(BOARDLOADER_BUILD_DIR)/boardloader.bin
@ -205,9 +214,16 @@ build_cross: ## build mpy-cross port
## clean commands:
clean: clean_boardloader clean_bootloader clean_bootloader_ci clean_prodtest clean_reflash clean_firmware clean_unix clean_cross ## clean all
clean: clean_ble_bootloader clean_ble_firmware clean_boardloader clean_bootloader clean_bootloader_ci clean_prodtest clean_reflash clean_firmware clean_unix clean_cross ## clean all
rm -f ".sconsign.dblite"
clean_ble_bootloader: ## clean ble_bootloader build
rm -rf $(BLE_BOOTLOADER_BUILD_DIR)
clean_ble_firmware: ## clean ble_bootloader build
rm -rf $(BLE_FIRMWARE_BUILD_DIR)
clean_boardloader: ## clean boardloader build
rm -rf $(BOARDLOADER_BUILD_DIR)
@ -236,6 +252,24 @@ clean_cross: ## clean mpy-cross build
flash: flash_boardloader flash_bootloader flash_firmware ## flash everything using OpenOCD
flash_ble: flash_ble_bootloader flash_softdevice flash_ble_firmware
flash_ble_bootloader:
@echo Flashing: $(BLE_BOOTLOADER_BUILD_DIR)/ble_bootloader.hex
nrfjprog -f nrf52 --program $(BLE_BOOTLOADER_BUILD_DIR)/ble_bootloader.hex --sectorerase
flash_ble_firmware:
@echo Flashing: $(BLE_FIRMWARE_BUILD_DIR)/ble_firmware_merged.hex
nrfjprog -f nrf52 --program $(BLE_FIRMWARE_BUILD_DIR)/ble_firmware_merged.hex --sectorerase
flash_ble_bl_settings:
@echo Flashing: $(BLE_BOOTLOADER_BUILD_DIR)/settings.hex
nrfjprog -f nrf52 --program $(BLE_BOOTLOADER_BUILD_DIR)/settings.hex --sectorerase
flash_softdevice:
@echo Flashing: s140_nrf52_7.2.0_softdevice.hex
nrfjprog -f nrf52 --program embed/sdk/nrf52/components/softdevice/s140/hex/s140_nrf52_7.2.0_softdevice.hex --sectorerase
flash_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.bin ## flash boardloader using OpenOCD
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"
@ -260,6 +294,9 @@ flash_combine: $(PRODTEST_BUILD_DIR)/combined.bin ## flash combined using OpenOC
flash_erase: ## erase all sectors in flash bank 0
$(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 0 last; flash erase_check 0; exit"
flash_erase_ble:
nrfjprog -f nrf52 --eraseall
flash_read_storage: ## read storage sectors from flash
$(OPENOCD) -c "init; flash read_bank 0 storage1.data 0x10000 65536; flash read_bank 0 storage2.data 0x110000 65536; exit"
@ -288,6 +325,10 @@ openocd: ## start openocd which connects to the device
openocd_reset: ## cause a system reset using OpenOCD
$(OPENOCD) -c "init; reset; exit"
# nrfjprog debug commands:
nrfjprog_reset:
nrfjprog -f nrf52 --reset
GDB = arm-none-eabi-gdb --nx -ex 'set remotetimeout unlimited' -ex 'set confirm off' -ex 'target remote 127.0.0.1:3333' -ex 'monitor reset halt'
gdb_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.elf ## start remote gdb session to openocd with boardloader symbols

@ -0,0 +1,339 @@
# pylint: disable=E0602
import os
import tools
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
if TREZOR_MODEL in ('1', ):
# skip boardloader build
env = Environment()
def build_ble_bootloader(target,source,env):
print(f'BLE BOOTLOADER: nothing to build for Model {TREZOR_MODEL}')
program_bin = env.Command(
target='ble_bootloader.bin',
source=None,
action=build_ble_bootloader
)
Return()
CCFLAGS_MOD = ''
CPPPATH_MOD = []
CPPDEFINES_MOD = []
SOURCE_MOD = []
CCFLAGS_MOD += '-Wno-sequence-point '
if int(ARGUMENTS.get('PRODUCTION', 0)) == 0:
# Build for monitor debug mode and RTT.
DEBUG = True
else:
DEBUG = False
# C flags common to all targets
CPPDEFINES_MOD += [
'BOARD_PCA10056',
'CONFIG_GPIO_AS_PINRESET',
'FLOAT_ABI_HARD',
'NRF52840_XXAA',
('NRF_DFU_SETTINGS_VERSION','2'),
'MBR_PRESENT',
'SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION',
('__HEAP_SIZE','0'),
]
CPPPATH_MOD += [
]
CPPDEFINES_MOD += [
]
SOURCE_MOD += [
]
CPPPATH_MOD += [
'embed/sdk/nrf52/modules/nrfx/drivers/include',
'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc',
'embed/sdk/nrf52/components/libraries/memobj',
'embed/sdk/nrf52/components/libraries/crc32',
'embed/sdk/nrf52/components/libraries/experimental_section_vars',
'embed/sdk/nrf52/components/libraries/mem_manager',
'embed/sdk/nrf52/components/libraries/fstorage',
'embed/sdk/nrf52/components/libraries/util',
'embed/sdk/nrf52/modules/nrfx',
'embed/sdk/nrf52/external/nrf_oberon/include',
'embed/sdk/nrf52/components/libraries/crypto/backend/oberon',
'embed/sdk/nrf52/components/libraries/crypto/backend/cifra',
'embed/sdk/nrf52/components/libraries/atomic',
'embed/sdk/nrf52/integration/nrfx',
'embed/sdk/nrf52/components/libraries/crypto/backend/cc310_bl',
'embed/sdk/nrf52/components/drivers_nrf/nrf_soc_nosd',
'embed/sdk/nrf52/components/libraries/log/src',
'embed/sdk/nrf52/components/libraries/bootloader/dfu',
'embed/sdk/nrf52/components/libraries/bootloader/serial_dfu',
'embed/sdk/nrf52/external/nrf_cc310_bl/include',
'embed/sdk/nrf52/external/segger_rtt',
'embed/sdk/nrf52/components/libraries/delay',
'embed/sdk/nrf52/integration/nrfx/legacy',
'embed/sdk/nrf52/modules/nrfx/hal',
'embed/sdk/nrf52/components/libraries/crypto/backend/nrf_hw',
'embed/sdk/nrf52/components/libraries/log',
'embed/sdk/nrf52/external/nrf_oberon',
'embed/sdk/nrf52/components/libraries/strerror',
'embed/sdk/nrf52/components/libraries/crypto/backend/mbedtls',
'embed/sdk/nrf52/components/boards',
'embed/sdk/nrf52/components/libraries/crypto/backend/cc310',
'embed/sdk/nrf52/components/libraries/bootloader',
'embed/sdk/nrf52/components/softdevice/mbr/headers',
'embed/sdk/nrf52/components/libraries/crypto',
'embed/sdk/nrf52/components/libraries/crypto/backend/optiga',
'embed/sdk/nrf52/components/libraries/scheduler',
'embed/sdk/nrf52/components/libraries/slip',
'embed/sdk/nrf52/external/fprintf',
'embed/sdk/nrf52/components/toolchain/cmsis/include',
'embed/sdk/nrf52/components/libraries/balloc',
'embed/sdk/nrf52/components/libraries/stack_info',
'embed/sdk/nrf52/components/libraries/crypto/backend/nrf_sw',
'embed/sdk/nrf52/modules/nrfx/mdk',
'embed/sdk/nrf52/external/nrf_cc310/include',
'embed/sdk/nrf52/external/nano-pb',
'embed/sdk/nrf52/components/libraries/queue',
'embed/sdk/nrf52/components/libraries/mutex',
'embed/sdk/nrf52/components/libraries/ringbuf',
]
SOURCE_MOD += [
]
SOURCE_NRFHAL_AS = [
'embed/sdk/nrf52/modules/nrfx/mdk/gcc_startup_nrf52840.S',
]
SOURCE_NRFHAL = [
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_frontend.c',
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_str_formatter.c',
'embed/sdk/nrf52/components/boards/boards.c',
'embed/sdk/nrf52/modules/nrfx/mdk/system_nrf52840.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c',
'embed/sdk/nrf52/components/libraries/util/app_error_weak.c',
'embed/sdk/nrf52/components/libraries/scheduler/app_scheduler.c',
'embed/sdk/nrf52/components/libraries/util/app_util_platform.c',
'embed/sdk/nrf52/components/libraries/crc32/crc32.c',
'embed/sdk/nrf52/components/libraries/mem_manager/mem_manager.c',
'embed/sdk/nrf52/components/libraries/util/nrf_assert.c',
'embed/sdk/nrf52/components/libraries/atomic/nrf_atomic.c',
'embed/sdk/nrf52/components/libraries/balloc/nrf_balloc.c',
'embed/sdk/nrf52/external/fprintf/nrf_fprintf.c',
'embed/sdk/nrf52/external/fprintf/nrf_fprintf_format.c',
'embed/sdk/nrf52/components/libraries/fstorage/nrf_fstorage.c',
'embed/sdk/nrf52/components/libraries/fstorage/nrf_fstorage_nvmc.c',
'embed/sdk/nrf52/components/libraries/memobj/nrf_memobj.c',
'embed/sdk/nrf52/components/libraries/queue/nrf_queue.c',
'embed/sdk/nrf52/components/libraries/ringbuf/nrf_ringbuf.c',
'embed/sdk/nrf52/components/libraries/strerror/nrf_strerror.c',
'embed/sdk/nrf52/components/libraries/slip/slip.c',
'embed/sdk/nrf52/integration/nrfx/legacy/nrf_drv_uart.c',
'embed/sdk/nrf52/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c',
'embed/sdk/nrf52/modules/nrfx/hal/nrf_nvmc.c',
'embed/sdk/nrf52/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c',
'embed/sdk/nrf52/modules/nrfx/soc/nrfx_atomic.c',
'embed/sdk/nrf52/modules/nrfx/drivers/src/prs/nrfx_prs.c',
'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_uart.c',
'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_uarte.c',
'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_ecc.c',
'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_ecdsa.c',
'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_hash.c',
'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_init.c',
'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_shared.c',
'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader.c',
'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_app_start.c',
'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_app_start_final.c',
'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_dfu_timers.c',
'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_fw_activation.c',
'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_info.c',
'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_wdt.c',
'embed/sdk/nrf52/external/nano-pb/pb_common.c',
'embed/sdk/nrf52/external/nano-pb/pb_decode.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/dfu-cc.pb.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_flash.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_mbr.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c',
'embed/sdk/nrf52/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_settings.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_transport.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_utils.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_validation.c',
'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c',
'embed/sdk/nrf52/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/oberon/oberon_backend_eddsa.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/oberon/oberon_backend_hash.c',
'embed/sdk/nrf52/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c',
]
SOURCE_BLE_BOOTLOADER = [
'embed/ble_bootloader/main.c',
'embed/ble_bootloader/dfu_public_key.c',
]
if DEBUG:
CPPDEFINES_MOD += [
'DEBUG',
'DEBUG_NRF',
'NRF_DFU_DEBUG_VERSION',
'MMD'
]
SOURCE_BLE_BOOTLOADER += [
'embed/segger/SEGGER_MMD/JLINK_MONITOR.c',
'embed/segger/SEGGER_MMD/JLINK_MONITOR_ISR_SES.S'
]
SOURCE_NRFHAL += [
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_rtt.c',
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_serial.c',
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_uart.c',
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_default_backends.c',
'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT.c',
'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT_Syscalls_GCC.c',
'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT_printf.c',
]
CPPPATH_MOD += [
'embed/segger/SEGGER_MMD'
]
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')))
env.Replace(
CP='cp',
AS='arm-none-eabi-as',
AR='arm-none-eabi-ar',
CC='arm-none-eabi-gcc',
LINK='arm-none-eabi-gcc',
SIZE='arm-none-eabi-size',
STRIP='arm-none-eabi-strip',
OBJCOPY='arm-none-eabi-objcopy',
PYTHON='python',
MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py', )
env.Replace(
TREZOR_MODEL=TREZOR_MODEL, )
CPU_ASFLAGS = '-mthumb -mabi=aapcs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16'
CPU_CCFLAGS = '-mthumb -mabi=aapcs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 '
env.Replace(
COPT=env.get('ENV').get('OPTIMIZE', '-Og'),
CCFLAGS='$COPT '
'-g3 '
'-std=c99 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces '
'-fdata-sections -ffunction-sections '
'-fno-strict-aliasing '
'-fno-builtin '
'-fshort-enums '
+ CPU_CCFLAGS + CCFLAGS_MOD,
LINKFLAGS='-Lembed/sdk/nrf52/modules/nrfx/mdk -T embed/ble_bootloader/memory.ld -Wl,--gc-sections --specs=nano.specs -Wl,-Map=build/ble_bootloader/ble_bootloader.map -Wl,--warn-common -Wl,--print-memory-usage',
CPPPATH=[
'embed/ble_bootloader',
'embed/sdk/nrf52',
] + CPPPATH_MOD,
CPPDEFINES=[
'BLE_BOOTLOADER',
'TREZOR_MODEL_'+TREZOR_MODEL,
] + CPPDEFINES_MOD,
ASFLAGS=CPU_ASFLAGS,
ASPPFLAGS='$CFLAGS $CCFLAGS', )
#
# Program objects
#
obj_program = []
obj_program += env.Object(source=SOURCE_BLE_BOOTLOADER)
obj_program += env.Object(source=SOURCE_NRFHAL_AS, COPT='-O0')
obj_program += env.Object(source=SOURCE_NRFHAL)
obj_program += env.Object(source=SOURCE_MOD)
env.Replace(
ALLSOURCES=SOURCE_NRFHAL_AS + SOURCE_MOD + SOURCE_BLE_BOOTLOADER + SOURCE_NRFHAL,
ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES']))
cmake_gen = env.Command(
target='CMakeLists.txt',
source='',
action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS',
)
LIB_FILES = [
'embed/sdk/nrf52/external/nrf_oberon/lib/cortex-m4/hard-float/liboberon_3.0.8.a',
'embed/sdk/nrf52/external/nrf_cc310_bl/lib/cortex-m4/hard-float/libnrf_cc310_bl_0.9.13.a',
]
program_elf = env.Command(
target='ble_bootloader.elf',
source=obj_program,
action=
'$LINK -o $TARGET $CCFLAGS $CFLAGS $LINKFLAGS $SOURCES ' + ' '.join(LIB_FILES) + ' -lc -lnosys -lm',
)
BINARY_NAME = f"build/ble_bootloader/ble_bootloader-{tools.get_model_identifier(TREZOR_MODEL)}"
BINARY_NAME += "-" + tools.get_version('embed/ble_bootloader/version.h')
BINARY_NAME += "-" + tools.get_git_revision_short_hash()
BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
BINARY_NAME += ".bin"
if CMAKELISTS != 0:
env.Depends(program_elf, cmake_gen)
program_hex = env.Command(
target='ble_bootloader.hex',
source=program_elf,
action='$OBJCOPY -O ihex $SOURCE $TARGET',
)
program_bin = env.Command(
target='ble_bootloader.bin',
source=program_elf,
action=[
'$OBJCOPY -O binary $SOURCE $TARGET',
'$CP $TARGET ' + BINARY_NAME,
],
)
program_settings = env.Command(
target='settings.hex',
source=None,
action='$CP ./embed/ble_bootloader/settings.hex $TARGET',
)
env.Depends(program_bin, program_hex)
env.Depends(program_bin, program_settings)

@ -0,0 +1,414 @@
# pylint: disable=E0602
import os
import tools
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
if TREZOR_MODEL in ('1', ):
# skip boardloader build
env = Environment()
def build_ble_firmware(target,source,env):
print(f'BLE FIRMWARE: nothing to build for Model {TREZOR_MODEL}')
program_bin = env.Command(
target='ble_firmware.bin',
source=None,
action=build_ble_firmware
)
Return()
CCFLAGS_MOD = ''
CPPPATH_MOD = []
CPPDEFINES_MOD = []
SOURCE_MOD = []
CCFLAGS_MOD += '-Wno-sequence-point '
if int(ARGUMENTS.get('PRODUCTION', 0)) == 0:
# Build for monitor debug mode.
MMD = True
else:
MMD = False
# C flags common to all targets
CPPDEFINES_MOD += [
'BOARD_PCA10056',
'CONFIG_GPIO_AS_PINRESET',
'FLOAT_ABI_HARD',
'NRF52840_XXAA',
'SOFTDEVICE_PRESENT',
('NRF_SD_BLE_API_VERSION', '7'),
'APP_TIMER_V2',
'APP_TIMER_V2_RTC1_ENABLED',
'S140',
('__HEAP_SIZE','8192'),
('__STACK_SIZE','8192'),
]
CPPPATH_MOD += [
]
CPPDEFINES_MOD += [
]
SOURCE_MOD += [
]
CPPPATH_MOD += [
'embed/sdk/nrf52/components/nfc/ndef/generic/message',
'embed/sdk/nrf52/components/nfc/t2t_lib',
'embed/sdk/nrf52/components/nfc/t4t_parser/hl_detection_procedure',
'embed/sdk/nrf52/components/ble/ble_services/ble_ancs_c',
'embed/sdk/nrf52/components/ble/ble_services/ble_ias_c',
'embed/sdk/nrf52/components/libraries/pwm',
'embed/sdk/nrf52/components/libraries/usbd/class/cdc/acm',
'embed/sdk/nrf52/components/libraries/usbd/class/hid/generic',
'embed/sdk/nrf52/components/libraries/usbd/class/msc',
'embed/sdk/nrf52/components/libraries/usbd/class/hid',
'embed/sdk/nrf52/modules/nrfx/hal',
'embed/sdk/nrf52/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser',
'embed/sdk/nrf52/components/libraries/log',
'embed/sdk/nrf52/components/ble/ble_services/ble_gls',
'embed/sdk/nrf52/components/libraries/fstorage',
'embed/sdk/nrf52/components/nfc/ndef/text',
'embed/sdk/nrf52/components/libraries/mutex',
'embed/sdk/nrf52/components/libraries/gpiote',
'embed/sdk/nrf52/components/libraries/bootloader/ble_dfu',
'embed/sdk/nrf52/components/nfc/ndef/connection_handover/common',
'embed/sdk/nrf52/components/boards',
'embed/sdk/nrf52/components/nfc/ndef/generic/record',
'embed/sdk/nrf52/components/nfc/t4t_parser/cc_file',
'embed/sdk/nrf52/components/ble/ble_advertising',
'embed/sdk/nrf52/external/utf_converter',
'embed/sdk/nrf52/components/ble/ble_services/ble_bas_c',
'embed/sdk/nrf52/modules/nrfx/drivers/include',
'embed/sdk/nrf52/components/libraries/experimental_task_manager',
'embed/sdk/nrf52/components/ble/ble_services/ble_hrs_c',
'embed/sdk/nrf52/components/softdevice/s140/headers/nrf52',
'embed/sdk/nrf52/components/nfc/ndef/connection_handover/le_oob_rec',
'embed/sdk/nrf52/components/libraries/queue',
'embed/sdk/nrf52/components/libraries/pwr_mgmt',
'embed/sdk/nrf52/components/ble/ble_dtm',
'embed/sdk/nrf52/components/toolchain/cmsis/include',
'embed/sdk/nrf52/components/ble/ble_services/ble_rscs_c',
'embed/sdk/nrf52/components/ble/common',
'embed/sdk/nrf52/components/ble/ble_services/ble_lls',
'embed/sdk/nrf52/components/nfc/platform',
'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ac_rec',
'embed/sdk/nrf52/components/ble/ble_services/ble_bas',
'embed/sdk/nrf52/components/libraries/mpu',
'embed/sdk/nrf52/components/libraries/experimental_section_vars',
'embed/sdk/nrf52/components/ble/ble_services/ble_ans_c',
'embed/sdk/nrf52/components/libraries/slip',
'embed/sdk/nrf52/components/libraries/delay',
'embed/sdk/nrf52/components/libraries/csense_drv',
'embed/sdk/nrf52/components/libraries/memobj',
'embed/sdk/nrf52/components/ble/ble_services/ble_nus_c',
'embed/sdk/nrf52/components/softdevice/common',
'embed/sdk/nrf52/components/ble/ble_services/ble_ias',
'embed/sdk/nrf52/components/libraries/usbd/class/hid/mouse',
'embed/sdk/nrf52/components/libraries/low_power_pwm',
'embed/sdk/nrf52/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser',
'embed/sdk/nrf52/components/ble/ble_services/ble_dfu',
'embed/sdk/nrf52/external/fprintf',
'embed/sdk/nrf52/components/libraries/svc',
'embed/sdk/nrf52/components/libraries/atomic',
'embed/sdk/nrf52/components',
'embed/sdk/nrf52/components/libraries/scheduler',
'embed/sdk/nrf52/components/libraries/cli',
'embed/sdk/nrf52/components/ble/ble_services/ble_lbs',
'embed/sdk/nrf52/components/ble/ble_services/ble_hts',
'embed/sdk/nrf52/components/libraries/crc16',
'embed/sdk/nrf52/components/nfc/t4t_parser/apdu',
'embed/sdk/nrf52/components/libraries/util',
'embed/sdk/nrf52/components/libraries/usbd/class/cdc',
'embed/sdk/nrf52/components/libraries/csense',
'embed/sdk/nrf52/components/libraries/balloc',
'embed/sdk/nrf52/components/libraries/ecc',
'embed/sdk/nrf52/components/libraries/hardfault',
'embed/sdk/nrf52/components/ble/ble_services/ble_cscs',
'embed/sdk/nrf52/components/libraries/hci',
'embed/sdk/nrf52/components/libraries/timer',
'embed/sdk/nrf52/components/softdevice/s140/headers',
'embed/sdk/nrf52/integration/nrfx',
'embed/sdk/nrf52/components/nfc/t4t_parser/tlv',
'embed/sdk/nrf52/components/libraries/sortlist',
'embed/sdk/nrf52/components/libraries/spi_mngr',
'embed/sdk/nrf52/components/libraries/led_softblink',
'embed/sdk/nrf52/components/nfc/ndef/conn_hand_parser',
'embed/sdk/nrf52/components/libraries/sdcard',
'embed/sdk/nrf52/components/nfc/ndef/parser/record',
'embed/sdk/nrf52/modules/nrfx/mdk',
'embed/sdk/nrf52/components/ble/ble_services/ble_cts_c',
'embed/sdk/nrf52/components/ble/ble_services/ble_nus',
'embed/sdk/nrf52/components/libraries/twi_mngr',
'embed/sdk/nrf52/components/ble/ble_services/ble_hids',
'embed/sdk/nrf52/components/libraries/strerror',
'embed/sdk/nrf52/components/libraries/crc32',
'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ble_oob_advdata',
'embed/sdk/nrf52/components/nfc/t2t_parser',
'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ble_pair_msg',
'embed/sdk/nrf52/components/libraries/usbd/class/audio',
'embed/sdk/nrf52/components/nfc/t4t_lib',
'embed/sdk/nrf52/components/ble/peer_manager',
'embed/sdk/nrf52/components/libraries/mem_manager',
'embed/sdk/nrf52/components/libraries/ringbuf',
'embed/sdk/nrf52/components/ble/ble_services/ble_tps',
'embed/sdk/nrf52/components/nfc/ndef/parser/message',
'embed/sdk/nrf52/components/ble/ble_services/ble_dis',
'embed/sdk/nrf52/components/nfc/ndef/uri',
'embed/sdk/nrf52/components/ble/nrf_ble_gatt',
'embed/sdk/nrf52/components/ble/nrf_ble_qwr',
'embed/sdk/nrf52/components/libraries/gfx',
'embed/sdk/nrf52/components/libraries/button',
'embed/sdk/nrf52/modules/nrfx',
'embed/sdk/nrf52/components/libraries/twi_sensor',
'embed/sdk/nrf52/integration/nrfx/legacy',
'embed/sdk/nrf52/components/libraries/usbd/class/hid/kbd',
'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ep_oob_rec',
'embed/sdk/nrf52/external/segger_rtt',
'embed/sdk/nrf52/components/libraries/atomic_fifo',
'embed/sdk/nrf52/components/ble/ble_services/ble_lbs_c',
'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ble_pair_lib',
'embed/sdk/nrf52/components/libraries/crypto',
'embed/sdk/nrf52/components/ble/ble_racp',
'embed/sdk/nrf52/components/libraries/fds',
'embed/sdk/nrf52/components/nfc/ndef/launchapp',
'embed/sdk/nrf52/components/libraries/atomic_flags',
'embed/sdk/nrf52/components/ble/ble_services/ble_hrs',
'embed/sdk/nrf52/components/ble/ble_services/ble_rscs',
'embed/sdk/nrf52/components/nfc/ndef/connection_handover/hs_rec',
'embed/sdk/nrf52/components/libraries/usbd',
'embed/sdk/nrf52/components/nfc/ndef/conn_hand_parser/ac_rec_parser',
'embed/sdk/nrf52/components/libraries/stack_guard',
'embed/sdk/nrf52/components/libraries/log/src',
]
SOURCE_MOD += [
]
SOURCE_NRFHAL_AS = [
'embed/sdk/nrf52/modules/nrfx/mdk/gcc_startup_nrf52840.S',
]
SOURCE_NRFHAL = [
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_frontend.c',
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_str_formatter.c',
'embed/sdk/nrf52/components/libraries/button/app_button.c',
'embed/sdk/nrf52/components/libraries/util/app_error.c',
'embed/sdk/nrf52/components/libraries/util/app_error_handler_gcc.c',
'embed/sdk/nrf52/components/libraries/util/app_error_weak.c',
'embed/sdk/nrf52/components/libraries/scheduler/app_scheduler.c',
'embed/sdk/nrf52/components/libraries/timer/app_timer2.c',
'embed/sdk/nrf52/components/libraries/util/app_util_platform.c',
'embed/sdk/nrf52/components/libraries/timer/drv_rtc.c',
'embed/sdk/nrf52/components/libraries/hardfault/hardfault_implementation.c',
'embed/sdk/nrf52/components/libraries/util/nrf_assert.c',
'embed/sdk/nrf52/components/libraries/atomic_fifo/nrf_atfifo.c',
'embed/sdk/nrf52/components/libraries/atomic_flags/nrf_atflags.c',
'embed/sdk/nrf52/components/libraries/atomic/nrf_atomic.c',
'embed/sdk/nrf52/components/libraries/balloc/nrf_balloc.c',
'embed/sdk/nrf52/external/fprintf/nrf_fprintf.c',
'embed/sdk/nrf52/external/fprintf/nrf_fprintf_format.c',
'embed/sdk/nrf52/components/libraries/memobj/nrf_memobj.c',
'embed/sdk/nrf52/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c',
'embed/sdk/nrf52/components/libraries/ringbuf/nrf_ringbuf.c',
'embed/sdk/nrf52/components/libraries/experimental_section_vars/nrf_section_iter.c',
'embed/sdk/nrf52/components/libraries/sortlist/nrf_sortlist.c',
'embed/sdk/nrf52/components/libraries/strerror/nrf_strerror.c',
'embed/sdk/nrf52/modules/nrfx/mdk/system_nrf52840.c',
'embed/sdk/nrf52/components/boards/boards.c',
'embed/sdk/nrf52/integration/nrfx/legacy/nrf_drv_clock.c',
'embed/sdk/nrf52/integration/nrfx/legacy/nrf_drv_uart.c',
'embed/sdk/nrf52/modules/nrfx/soc/nrfx_atomic.c',
'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_clock.c',
'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_gpiote.c',
'embed/sdk/nrf52/modules/nrfx/drivers/src/prs/nrfx_prs.c',
'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_uart.c',
'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_uarte.c',
'embed/sdk/nrf52/components/ble/common/ble_advdata.c',
'embed/sdk/nrf52/components/ble/common/ble_conn_params.c',
'embed/sdk/nrf52/components/ble/common/ble_conn_state.c',
'embed/sdk/nrf52/components/ble/common/ble_srv_common.c',
'embed/sdk/nrf52/components/ble/nrf_ble_gatt/nrf_ble_gatt.c',
'embed/sdk/nrf52/components/ble/nrf_ble_qwr/nrf_ble_qwr.c',
'embed/sdk/nrf52/external/utf_converter/utf.c',
'embed/sdk/nrf52/components/ble/ble_services/ble_lbs/ble_lbs.c',
'embed/sdk/nrf52/components/softdevice/common/nrf_sdh.c',
'embed/sdk/nrf52/components/softdevice/common/nrf_sdh_ble.c',
'embed/sdk/nrf52/components/softdevice/common/nrf_sdh_soc.c',
]
SOURCE_BLE_FIRMWARE = [
'embed/ble_firmware/main.c',
]
if MMD:
CPPDEFINES_MOD += [
'DEBUG',
'DEBUG_NRF',
'MMD'
]
SOURCE_BLE_FIRMWARE += [
'embed/segger/SEGGER_MMD/JLINK_MONITOR.c',
'embed/segger/SEGGER_MMD/JLINK_MONITOR_ISR_SES.S'
]
SOURCE_NRFHAL += [
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_rtt.c',
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_serial.c',
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_uart.c',
'embed/sdk/nrf52/components/libraries/log/src/nrf_log_default_backends.c',
'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT.c',
'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT_Syscalls_GCC.c',
'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT_printf.c',
]
CPPPATH_MOD += [
'embed/segger/SEGGER_MMD'
]
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')))
env.Replace(
CP='cp',
AS='arm-none-eabi-as',
AR='arm-none-eabi-ar',
CC='arm-none-eabi-gcc',
LINK='arm-none-eabi-gcc',
SIZE='arm-none-eabi-size',
STRIP='arm-none-eabi-strip',
OBJCOPY='arm-none-eabi-objcopy',
PYTHON='python',
MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py', )
env.Replace(
TREZOR_MODEL=TREZOR_MODEL, )
CPU_ASFLAGS = '-mthumb -mabi=aapcs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16'
CPU_CCFLAGS = '-mthumb -mabi=aapcs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 '
env.Replace(
COPT=env.get('ENV').get('OPTIMIZE', '-Og'),
CCFLAGS='$COPT '
'-g3 '
'-std=c99 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces '
'-fdata-sections -ffunction-sections '
'-fno-strict-aliasing '
'-fno-builtin '
'-fshort-enums '
+ CPU_CCFLAGS + CCFLAGS_MOD,
LINKFLAGS='-Lembed/sdk/nrf52/modules/nrfx/mdk -T embed/ble_firmware/memory.ld -Wl,--gc-sections --specs=nano.specs -Wl,-Map=build/ble_firmware/ble_firmware.map -Wl,--warn-common -Wl,--print-memory-usage',
CPPPATH=[
'embed/ble_firmware',
'embed/sdk/nrf52',
] + CPPPATH_MOD,
CPPDEFINES=[
'BLE_FIRMWARE',
'TREZOR_MODEL_'+TREZOR_MODEL,
] + CPPDEFINES_MOD,
ASFLAGS=CPU_ASFLAGS,
ASPPFLAGS='$CFLAGS $CCFLAGS', )
#
# Program objects
#
obj_program = []
obj_program += env.Object(source=SOURCE_BLE_FIRMWARE)
obj_program += env.Object(source=SOURCE_NRFHAL_AS, COPT='-O0')
obj_program += env.Object(source=SOURCE_NRFHAL)
obj_program += env.Object(source=SOURCE_MOD)
env.Replace(
ALLSOURCES=SOURCE_NRFHAL_AS + SOURCE_MOD + SOURCE_BLE_FIRMWARE + SOURCE_NRFHAL,
ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES']))
cmake_gen = env.Command(
target='CMakeLists.txt',
source='',
action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS',
)
LIB_FILES = [
'embed/sdk/nrf52/external/nrf_oberon/lib/cortex-m4/hard-float/liboberon_3.0.8.a',
'embed/sdk/nrf52/external/nrf_cc310_bl/lib/cortex-m4/hard-float/libnrf_cc310_bl_0.9.13.a',
]
program_elf = env.Command(
target='ble_firmware.elf',
source=obj_program,
action=
'$LINK -o $TARGET $CCFLAGS $CFLAGS $LINKFLAGS $SOURCES ' + ' '.join(LIB_FILES) + ' -lc -lnosys -lm',
)
BINARY_NAME = f"build/ble_firmware/ble_firmware-{tools.get_model_identifier(TREZOR_MODEL)}"
BINARY_NAME += "-" + tools.get_version('embed/ble_firmware/version.h')
BINARY_NAME += "-" + tools.get_git_revision_short_hash()
BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
BINARY_NAME += ".bin"
if CMAKELISTS != 0:
env.Depends(program_elf, cmake_gen)
program_hex = env.Command(
target='ble_firmware.hex',
source=program_elf,
action='$OBJCOPY -O ihex $SOURCE $TARGET',
)
program_pkg = env.Command(
target='ble_firmware.zip',
source=program_hex,
action=[
f'nrfutil pkg generate --hw-version 52 --sd-req=0x100 --application $SOURCE --app-boot-validation VALIDATE_ECDSA_P256_SHA256 --key-file ./embed/ble_bootloader/priv.pem $TARGET --application-version-string {tools.get_version("embed/ble_firmware/version.h")}'
],
)
settings = env.Command(
target='settings.hex',
source=program_hex,
action=f'nrfutil settings generate --family NRF52840 --application $SOURCE --app-boot-validation VALIDATE_ECDSA_P256_SHA256 --application-version-string {tools.get_version("embed/ble_firmware/version.h")} --bootloader-version {tools.get_version_int("embed/ble_bootloader/version.h")} --bl-settings-version 2 --sd-boot-validation VALIDATE_ECDSA_P256_SHA256 --softdevice ./embed/sdk/nrf52/components/softdevice/s140/hex/s140_nrf52_7.2.0_softdevice.hex --key-file ./embed/ble_bootloader/priv.pem $TARGET',
)
program_merge = env.Command(
target='ble_firmware_merged.hex',
source=[program_hex, settings],
action='mergehex -m $SOURCES -o $TARGET',
)
program_bin = env.Command(
target='ble_firmware.bin',
source=program_elf,
action=[
'$OBJCOPY -O binary $SOURCE $TARGET',
'$CP $TARGET ' + BINARY_NAME,
],
)
env.Depends(program_bin, program_hex)
env.Depends(program_pkg, program_hex)
env.Depends(settings, program_hex)
env.Depends(program_bin, program_pkg)
env.Depends(program_merge, settings)
env.Depends(program_merge, program_hex)
env.Depends(program_bin, program_merge)

@ -1,5 +1,7 @@
# pylint: disable=E0602
SConscript('SConscript.ble_bootloader', variant_dir='build/ble_bootloader', duplicate=False)
SConscript('SConscript.ble_firmware', variant_dir='build/ble_firmware', duplicate=False)
SConscript('SConscript.boardloader', variant_dir='build/boardloader', duplicate=False)
SConscript('SConscript.bootloader', variant_dir='build/bootloader', duplicate=False)
SConscript('SConscript.bootloader_ci', variant_dir='build/bootloader_ci', duplicate=False)

@ -0,0 +1,16 @@
/* This file was automatically generated by nrfutil on 2023-01-23 (YY-MM-DD) at
* 16:58:55 */
#include "compiler_abstraction.h"
#include "stdint.h"
/** @brief Public key used to verify DFU images */
__ALIGN(4)
const uint8_t pk[64] = {
0x7e, 0x2f, 0x54, 0x41, 0xb7, 0x3f, 0x0c, 0xc8, 0xa8, 0x8f, 0x29,
0x1a, 0x91, 0x3c, 0x9f, 0x70, 0x7e, 0xc6, 0x6f, 0x69, 0x51, 0x14,
0xa6, 0x04, 0xeb, 0x0b, 0x23, 0x61, 0xf0, 0x22, 0xa4, 0xf4, 0xad,
0x73, 0x9b, 0xfa, 0x48, 0x2e, 0x1a, 0x90, 0xf6, 0x59, 0x28, 0x4c,
0x73, 0x49, 0x64, 0xc5, 0x18, 0xd3, 0xb3, 0xb2, 0x1a, 0x60, 0xf0,
0x79, 0xe8, 0x2c, 0x0a, 0x7c, 0x04, 0x84, 0xcd, 0xd6};

@ -0,0 +1,332 @@
/*********************************************************************
* (c) SEGGER Microcontroller GmbH *
* The Embedded Experts *
* www.segger.com *
**********************************************************************
File : /home/mbruna/CLionProjects/trezor-model_r/core/embed/ble_bootloader/jlink.jdebug
Created : 6 Feb 2023 15:54
Ozone Version : V3.28c
*/
/*********************************************************************
*
* OnProjectLoad
*
* Function description
* Project load routine. Required.
*
**********************************************************************
*/
void OnProjectLoad (void) {
//
// Dialog-generated settings
//
Project.AddPathSubstitute (".", "$(ProjectDir)");
Project.AddPathSubstitute (".", "$(ProjectDir)");
Project.SetDevice ("Cortex-M4");
Project.SetHostIF ("USB", "");
Project.SetTargetIF ("SWD");
Project.SetTIFSpeed ("20 MHz");
Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd");
//
// User settings
//
File.Open ("../../build/ble_bootloader/ble_bootloader.elf");
}
/*********************************************************************
*
* OnStartupComplete
*
* Function description
* Called when program execution has reached/passed
* the startup completion point. Optional.
*
**********************************************************************
*/
//void OnStartupComplete (void) {
//}
/*********************************************************************
*
* TargetReset
*
* Function description
* Replaces the default target device reset routine. Optional.
*
* Notes
* This example demonstrates the usage when
* debugging an application in RAM on a Cortex-M target device.
*
**********************************************************************
*/
//void TargetReset (void) {
//
// unsigned int SP;
// unsigned int PC;
// unsigned int VectorTableAddr;
//
// VectorTableAddr = Elf.GetBaseAddr();
// //
// // Set up initial stack pointer
// //
// if (VectorTableAddr != 0xFFFFFFFF) {
// SP = Target.ReadU32(VectorTableAddr);
// Target.SetReg("SP", SP);
// }
// //
// // Set up entry point PC
// //
// PC = Elf.GetEntryPointPC();
//
// if (PC != 0xFFFFFFFF) {
// Target.SetReg("PC", PC);
// } else if (VectorTableAddr != 0xFFFFFFFF) {
// PC = Target.ReadU32(VectorTableAddr + 4);
// Target.SetReg("PC", PC);
// } else {
// Util.Error("Project file error: failed to set entry point PC", 1);
// }
//}
/*********************************************************************
*
* BeforeTargetReset
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetReset (void) {
//}
/*********************************************************************
*
* AfterTargetReset
*
* Function description
* Event handler routine. Optional.
* The default implementation initializes SP and PC to reset values.
**
**********************************************************************
*/
void AfterTargetReset (void) {
_SetupTarget();
}
/*********************************************************************
*
* DebugStart
*
* Function description
* Replaces the default debug session startup routine. Optional.
*
**********************************************************************
*/
//void DebugStart (void) {
//}
/*********************************************************************
*
* TargetConnect
*
* Function description
* Replaces the default target IF connection routine. Optional.
*
**********************************************************************
*/
//void TargetConnect (void) {
//}
/*********************************************************************
*
* BeforeTargetConnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
void BeforeTargetConnect (void) {
Project.SetJLinkScript("./MMDScript.JLinkScript");
}
/*********************************************************************
*
* AfterTargetConnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetConnect (void) {
//}
/*********************************************************************
*
* TargetDownload
*
* Function description
* Replaces the default program download routine. Optional.
*
**********************************************************************
*/
//void TargetDownload (void) {
//}
/*********************************************************************
*
* BeforeTargetDownload
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetDownload (void) {
//}
/*********************************************************************
*
* AfterTargetDownload
*
* Function description
* Event handler routine. Optional.
* The default implementation initializes SP and PC to reset values.
*
**********************************************************************
*/
void AfterTargetDownload (void) {
_SetupTarget();
}
/*********************************************************************
*
* BeforeTargetDisconnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetDisconnect (void) {
//}
/*********************************************************************
*
* AfterTargetDisconnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetDisconnect (void) {
//}
/*********************************************************************
*
* AfterTargetHalt
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetHalt (void) {
//}
/*********************************************************************
*
* BeforeTargetResume
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetResume (void) {
//}
/*********************************************************************
*
* OnSnapshotLoad
*
* Function description
* Called upon loading a snapshot. Optional.
*
* Additional information
* This function is used to restore the target state in cases
* where values cannot simply be written to the target.
* Typical use: GPIO clock needs to be enabled, before
* GPIO is configured.
*
**********************************************************************
*/
//void OnSnapshotLoad (void) {
//}
/*********************************************************************
*
* OnSnapshotSave
*
* Function description
* Called upon saving a snapshot. Optional.
*
* Additional information
* This function is usually used to save values of the target
* state which can either not be trivially read,
* or need to be restored in a specific way or order.
* Typically use: Memory Mapped Registers,
* such as PLL and GPIO configuration.
*
**********************************************************************
*/
//void OnSnapshotSave (void) {
//}
/*********************************************************************
*
* OnError
*
* Function description
* Called when an error ocurred. Optional.
*
**********************************************************************
*/
//void OnError (void) {
//}
/*********************************************************************
*
* AfterProjectLoad
*
* Function description
* After Project load routine. Optional.
*
**********************************************************************
*/
//void AfterProjectLoad (void) {
//}
/*********************************************************************
*
* _SetupTarget
*
* Function description
* Setup the target.
* Called by AfterTargetReset() and AfterTargetDownload().
*
* Auto-generated function. May be overridden by Ozone.
*
**********************************************************************
*/
void _SetupTarget(void) {
//
// this function is intentionally empty because both inital PC and
// initial SP were chosen not to be set
//
}

@ -0,0 +1,154 @@
/**
* Copyright (c) 2016 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be
* reverse engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @file
*
* @defgroup bootloader_secure_ble main.c
* @{
* @ingroup dfu_bootloader_api
* @brief Bootloader project main file for secure DFU.
*
*/
#include <stdint.h>
#include "app_error.h"
#include "app_error_weak.h"
#include "boards.h"
#include "nrf_bootloader.h"
#include "nrf_bootloader_app_start.h"
#include "nrf_bootloader_dfu_timers.h"
#include "nrf_bootloader_info.h"
#include "nrf_delay.h"
#include "nrf_dfu.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "nrf_mbr.h"
static void on_error(void) {
NRF_LOG_FINAL_FLUSH();
#if NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
// To allow the buffer to be flushed by the host.
nrf_delay_ms(100);
#endif
#ifdef NRF_DFU_DEBUG_VERSION
NRF_BREAKPOINT_COND;
#endif
NVIC_SystemReset();
}
void app_error_handler(uint32_t error_code, uint32_t line_num,
const uint8_t* p_file_name) {
NRF_LOG_ERROR("%s:%d", p_file_name, line_num);
on_error();
}
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) {
NRF_LOG_ERROR("Received a fault! id: 0x%08x, pc: 0x%08x, info: 0x%08x", id,
pc, info);
on_error();
}
void app_error_handler_bare(uint32_t error_code) {
NRF_LOG_ERROR("Received an error: 0x%08x!", error_code);
on_error();
}
/**
* @brief Function notifies certain events in DFU process.
*/
static void dfu_observer(nrf_dfu_evt_type_t evt_type) {
switch (evt_type) {
case NRF_DFU_EVT_DFU_FAILED:
case NRF_DFU_EVT_DFU_ABORTED:
case NRF_DFU_EVT_DFU_INITIALIZED:
bsp_board_init(BSP_INIT_LEDS);
bsp_board_led_on(BSP_BOARD_LED_0);
bsp_board_led_on(BSP_BOARD_LED_1);
bsp_board_led_off(BSP_BOARD_LED_2);
break;
case NRF_DFU_EVT_TRANSPORT_ACTIVATED:
bsp_board_led_off(BSP_BOARD_LED_1);
bsp_board_led_on(BSP_BOARD_LED_2);
break;
case NRF_DFU_EVT_DFU_STARTED:
break;
default:
break;
}
}
/**@brief Function for application main entry. */
int main(void) {
uint32_t ret_val;
// Apply priority for monitor mode interrupt
NVIC_SetPriority(DebugMonitor_IRQn, _PRIO_SD_LOW);
// Must happen before flash protection is applied, since it edits a protected
// page.
nrf_bootloader_mbr_addrs_populate();
// Protect MBR and bootloader code from being overwritten.
ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE);
APP_ERROR_CHECK(ret_val);
ret_val =
nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE);
APP_ERROR_CHECK(ret_val);
(void)NRF_LOG_INIT(nrf_bootloader_dfu_timer_counter_get);
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("Inside main");
ret_val = nrf_bootloader_init(dfu_observer);
APP_ERROR_CHECK(ret_val);
NRF_LOG_FLUSH();
NRF_LOG_ERROR("After main, should never be reached.");
NRF_LOG_FLUSH();
APP_ERROR_CHECK_BOOL(false);
}
/**
* @}
*/

@ -0,0 +1,156 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0xf0000, LENGTH = 0xe000
RAM (rwx) : ORIGIN = 0x20005978, LENGTH = 0x3a688
uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
bootloader_settings_page (r) : ORIGIN = 0x000FF000, LENGTH = 0x1000
uicr_mbr_params_page (r) : ORIGIN = 0x10001018, LENGTH = 0x4
mbr_params_page (r) : ORIGIN = 0x000FE000, LENGTH = 0x1000
}
SECTIONS
{
. = ALIGN(4);
.uicr_bootloader_start_address :
{
PROVIDE(__start_uicr_bootloader_start_address = .);
KEEP(*(SORT(.uicr_bootloader_start_address*)))
PROVIDE(__stop_uicr_bootloader_start_address = .);
} > uicr_bootloader_start_address
. = ALIGN(4);
.bootloader_settings_page(NOLOAD) :
{
PROVIDE(__start_bootloader_settings_page = .);
KEEP(*(SORT(.bootloader_settings_page*)))
PROVIDE(__stop_bootloader_settings_page = .);
} > bootloader_settings_page
. = ALIGN(4);
.uicr_mbr_params_page :
{
PROVIDE(__start_uicr_mbr_params_page = .);
KEEP(*(SORT(.uicr_mbr_params_page*)))
PROVIDE(__stop_uicr_mbr_params_page = .);
} > uicr_mbr_params_page
. = ALIGN(4);
.mbr_params_page(NOLOAD) :
{
PROVIDE(__start_mbr_params_page = .);
KEEP(*(SORT(.mbr_params_page*)))
PROVIDE(__stop_mbr_params_page = .);
} > mbr_params_page
}
SECTIONS
{
. = ALIGN(4);
.mem_section_dummy_ram :
{
}
.log_dynamic_data :
{
PROVIDE(__start_log_dynamic_data = .);
KEEP(*(SORT(.log_dynamic_data*)))
PROVIDE(__stop_log_dynamic_data = .);
} > RAM
.log_filter_data :
{
PROVIDE(__start_log_filter_data = .);
KEEP(*(SORT(.log_filter_data*)))
PROVIDE(__stop_log_filter_data = .);
} > RAM
.fs_data :
{
PROVIDE(__start_fs_data = .);
KEEP(*(.fs_data))
PROVIDE(__stop_fs_data = .);
} > RAM
} INSERT AFTER .data;
SECTIONS
{
.mem_section_dummy_rom :
{
}
.crypto_data :
{
PROVIDE(__start_crypto_data = .);
KEEP(*(SORT(.crypto_data*)))
PROVIDE(__stop_crypto_data = .);
} > FLASH
.nrf_queue :
{
PROVIDE(__start_nrf_queue = .);
KEEP(*(.nrf_queue))
PROVIDE(__stop_nrf_queue = .);
} > FLASH
.dfu_trans :
{
PROVIDE(__start_dfu_trans = .);
KEEP(*(SORT(.dfu_trans*)))
PROVIDE(__stop_dfu_trans = .);
} > FLASH
.svc_data :
{
PROVIDE(__start_svc_data = .);
KEEP(*(.svc_data))
PROVIDE(__stop_svc_data = .);
} > FLASH
.log_const_data :
{
PROVIDE(__start_log_const_data = .);
KEEP(*(SORT(.log_const_data*)))
PROVIDE(__stop_log_const_data = .);
} > FLASH
.nrf_balloc :
{
PROVIDE(__start_nrf_balloc = .);
KEEP(*(.nrf_balloc))
PROVIDE(__stop_nrf_balloc = .);
} > FLASH
.sdh_ble_observers :
{
PROVIDE(__start_sdh_ble_observers = .);
KEEP(*(SORT(.sdh_ble_observers*)))
PROVIDE(__stop_sdh_ble_observers = .);
} > FLASH
.log_backends :
{
PROVIDE(__start_log_backends = .);
KEEP(*(SORT(.log_backends*)))
PROVIDE(__stop_log_backends = .);
} > FLASH
.sdh_req_observers :
{
PROVIDE(__start_sdh_req_observers = .);
KEEP(*(SORT(.sdh_req_observers*)))
PROVIDE(__stop_sdh_req_observers = .);
} > FLASH
.sdh_state_observers :
{
PROVIDE(__start_sdh_state_observers = .);
KEEP(*(SORT(.sdh_state_observers*)))
PROVIDE(__stop_sdh_state_observers = .);
} > FLASH
.sdh_stack_observers :
{
PROVIDE(__start_sdh_stack_observers = .);
KEEP(*(SORT(.sdh_stack_observers*)))
PROVIDE(__stop_sdh_stack_observers = .);
} > FLASH
.sdh_soc_observers :
{
PROVIDE(__start_sdh_soc_observers = .);
KEEP(*(SORT(.sdh_soc_observers*)))
PROVIDE(__stop_sdh_soc_observers = .);
} > FLASH
} INSERT AFTER .text
INCLUDE "nrf_common.ld"

@ -0,0 +1,63 @@
/**
* Copyright (c) 2019 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be
* reverse engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_CRYPTO_ALLOCATOR_H__
#define NRF_CRYPTO_ALLOCATOR_H__
#include "nrf_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Crypto library in bootloader case does not use dynamic allocation */
#define NRF_CRYPTO_ALLOC(size) \
NULL; \
ASSERT(0)
#define NRF_CRYPTO_ALLOC_ON_STACK(size) \
NULL; \
ASSERT(0)
#define NRF_CRYPTO_FREE(ptr) (void)ptr;
#ifdef __cplusplus
}
#endif
#endif /* NRF_CRYPTO_ALLOCATOR_H__ */

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOSMfopjR9WnpAjLnog4xJG5XRVi5MfXk7bGGuxLanCAoAoGCCqGSM49
AwEHoUQDQgAE9KQi8GEjC+sEphRRaW/GfnCfPJEaKY+oyAw/t0FUL37WzYQEfAos
6HnwYBqys9MYxWRJc0woWfaQGi5I+ptzrQ==
-----END EC PRIVATE KEY-----

File diff suppressed because it is too large Load Diff

@ -0,0 +1,104 @@
:02000004000FEB
:10E000005FEDFE17020000000000000000000000AD
:10E010000000000000000000BC8D0000C744B10FEC
:10E0200001000000000000000000000000000000EF
:10E030000000000034560200000000000000000054
:10E0400000000000000000000000000000000000D0
:10E0500000000000000000000000000000000000C0
:10E0600000000000000000000000000000000000B0
:10E0700000000000000000000000000000000000A0
:10E080000000000000000000000000000000000090
:10E090000000000000000000000000000000000080
:10E0A0000000000000000000000000000000000070
:10E0B0000000000000000000000000000000000060
:10E0C0000000000000000000000000000000000050
:10E0D0000000000000000000000000000000000040
:10E0E0000000000000000000000000000000000030
:10E0F0000000000000000000000000000000000020
:10E10000000000000000000000000000000000000F
:10E1100000000000000000000000000000000000FF
:10E1200000000000000000000000000000000000EF
:10E1300000000000000000000000000000000000DF
:10E1400000000000000000000000000000000000CF
:10E1500000000000000000000000000000000000BF
:10E1600000000000000000000000000000000000AF
:10E17000000000000000000000000000000000009F
:10E18000000000000000000000000000000000008F
:10E19000000000000000000000000000000000007F
:10E1A000000000000000000000000000000000006F
:10E1B000000000000000000000000000000000005F
:10E1C000000000000000000000000000000000004F
:10E1D000000000000000000000000000000000003F
:10E1E000000000000000000000000000000000002F
:10E1F000000000000000000000000000000000001F
:10E20000000000000000000000000000000000000E
:10E2100000000000000000000000000000000000FE
:10E2200000000000000000000000000000000000EE
:10E2300000000000000000000000000000000000DE
:10E2400000000000000000000000000000000000CE
:10E2500000000000000000000000000058736D691D
:10E26000035D0FD56B57E1D971627ACBB92CE7B654
:10E27000602778AE143B58ABDFA20C2C8906B7C9D7
:10E2800023B9DFF35688897AFB216506C1B822B12C
:10E290006BD0B79801DC9D96A830F6FD7E11E22A7E
:10E2A000DB03FF39BB38CE809A9153EB19915B9019
:10E2B000AE194AC22BE54AEB42D03B9B68070A9B4A
:10E2C0001DB13E09A07C647A7B382CD92F2DB22F4A
:10E2D000C9D6791F225F0A389096F1176004AFA162
:10E2E00096A30000000000000000000000000000F5
:10E2F000000000000000000000000000000000001E
:10E30000000000000000000000000000000000000D
:10E3100000000000000000000000000000000000FD
:04E32000000000FFFA
:10F000005FEDFE170200000000000000000000009D
:10F010000000000000000000BC8D0000C744B10FDC
:10F0200001000000000000000000000000000000DF
:10F030000000000034560200000000000000000044
:10F0400000000000000000000000000000000000C0
:10F0500000000000000000000000000000000000B0
:10F0600000000000000000000000000000000000A0
:10F070000000000000000000000000000000000090
:10F080000000000000000000000000000000000080
:10F090000000000000000000000000000000000070
:10F0A0000000000000000000000000000000000060
:10F0B0000000000000000000000000000000000050
:10F0C0000000000000000000000000000000000040
:10F0D0000000000000000000000000000000000030
:10F0E0000000000000000000000000000000000020
:10F0F0000000000000000000000000000000000010
:10F1000000000000000000000000000000000000FF
:10F1100000000000000000000000000000000000EF
:10F1200000000000000000000000000000000000DF
:10F1300000000000000000000000000000000000CF
:10F1400000000000000000000000000000000000BF
:10F1500000000000000000000000000000000000AF
:10F16000000000000000000000000000000000009F
:10F17000000000000000000000000000000000008F
:10F18000000000000000000000000000000000007F
:10F19000000000000000000000000000000000006F
:10F1A000000000000000000000000000000000005F
:10F1B000000000000000000000000000000000004F
:10F1C000000000000000000000000000000000003F
:10F1D000000000000000000000000000000000002F
:10F1E000000000000000000000000000000000001F
:10F1F000000000000000000000000000000000000F
:10F2000000000000000000000000000000000000FE
:10F2100000000000000000000000000000000000EE
:10F2200000000000000000000000000000000000DE
:10F2300000000000000000000000000000000000CE
:10F2400000000000000000000000000000000000BE
:10F2500000000000000000000000000058736D690D
:10F26000035D0FD56B57E1D971627ACBB92CE7B644
:10F27000602778AE143B58ABDFA20C2C8906B7C9C7
:10F2800023B9DFF35688897AFB216506C1B822B11C
:10F290006BD0B79801DC9D96A830F6FD7E11E22A6E
:10F2A000DB03FF39BB38CE809A9153EB19915B9009
:10F2B000AE194AC22BE54AEB42D03B9B68070A9B3A
:10F2C0001DB13E09A07C647A7B382CD92F2DB22F3A
:10F2D000C9D6791F225F0A389096F1176004AFA152
:10F2E00096A30000000000000000000000000000E5
:10F2F000000000000000000000000000000000000E
:10F3000000000000000000000000000000000000FD
:10F3100000000000000000000000000000000000ED
:04F32000000000FFEA
:00000001FF

@ -0,0 +1,4 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define VERSION_PATCH 0
#define VERSION_BUILD 0

@ -0,0 +1,332 @@
/*********************************************************************
* (c) SEGGER Microcontroller GmbH *
* The Embedded Experts *
* www.segger.com *
**********************************************************************
File : /home/mbruna/CLionProjects/trezor-model_r/core/embed/ble_firmware/jlink.jdebug
Created : 6 Feb 2023 15:54
Ozone Version : V3.28c
*/
/*********************************************************************
*
* OnProjectLoad
*
* Function description
* Project load routine. Required.
*
**********************************************************************
*/
void OnProjectLoad (void) {
//
// Dialog-generated settings
//
Project.AddPathSubstitute (".", "$(ProjectDir)");
Project.AddPathSubstitute (".", "$(ProjectDir)");
Project.SetDevice ("Cortex-M4");
Project.SetHostIF ("USB", "");
Project.SetTargetIF ("SWD");
Project.SetTIFSpeed ("20 MHz");
Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd");
//
// User settings
//
File.Open ("../../build/ble_firmware/ble_firmware.elf");
}
/*********************************************************************
*
* OnStartupComplete
*
* Function description
* Called when program execution has reached/passed
* the startup completion point. Optional.
*
**********************************************************************
*/
//void OnStartupComplete (void) {
//}
/*********************************************************************
*
* TargetReset
*
* Function description
* Replaces the default target device reset routine. Optional.
*
* Notes
* This example demonstrates the usage when
* debugging an application in RAM on a Cortex-M target device.
*
**********************************************************************
*/
//void TargetReset (void) {
//
// unsigned int SP;
// unsigned int PC;
// unsigned int VectorTableAddr;
//
// VectorTableAddr = Elf.GetBaseAddr();
// //
// // Set up initial stack pointer
// //
// if (VectorTableAddr != 0xFFFFFFFF) {
// SP = Target.ReadU32(VectorTableAddr);
// Target.SetReg("SP", SP);
// }
// //
// // Set up entry point PC
// //
// PC = Elf.GetEntryPointPC();
//
// if (PC != 0xFFFFFFFF) {
// Target.SetReg("PC", PC);
// } else if (VectorTableAddr != 0xFFFFFFFF) {
// PC = Target.ReadU32(VectorTableAddr + 4);
// Target.SetReg("PC", PC);
// } else {
// Util.Error("Project file error: failed to set entry point PC", 1);
// }
//}
/*********************************************************************
*
* BeforeTargetReset
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetReset (void) {
//}
/*********************************************************************
*
* AfterTargetReset
*
* Function description
* Event handler routine. Optional.
* The default implementation initializes SP and PC to reset values.
**
**********************************************************************
*/
void AfterTargetReset (void) {
_SetupTarget();
}
/*********************************************************************
*
* DebugStart
*
* Function description
* Replaces the default debug session startup routine. Optional.
*
**********************************************************************
*/
//void DebugStart (void) {
//}
/*********************************************************************
*
* TargetConnect
*
* Function description
* Replaces the default target IF connection routine. Optional.
*
**********************************************************************
*/
//void TargetConnect (void) {
//}
/*********************************************************************
*
* BeforeTargetConnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
void BeforeTargetConnect (void) {
Project.SetJLinkScript("./MMDScript.JLinkScript");
}
/*********************************************************************
*
* AfterTargetConnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetConnect (void) {
//}
/*********************************************************************
*
* TargetDownload
*
* Function description
* Replaces the default program download routine. Optional.
*
**********************************************************************
*/
//void TargetDownload (void) {
//}
/*********************************************************************
*
* BeforeTargetDownload
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetDownload (void) {
//}
/*********************************************************************
*
* AfterTargetDownload
*
* Function description
* Event handler routine. Optional.
* The default implementation initializes SP and PC to reset values.
*
**********************************************************************
*/
void AfterTargetDownload (void) {
_SetupTarget();
}
/*********************************************************************
*
* BeforeTargetDisconnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetDisconnect (void) {
//}
/*********************************************************************
*
* AfterTargetDisconnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetDisconnect (void) {
//}
/*********************************************************************
*
* AfterTargetHalt
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetHalt (void) {
//}
/*********************************************************************
*
* BeforeTargetResume
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetResume (void) {
//}
/*********************************************************************
*
* OnSnapshotLoad
*
* Function description
* Called upon loading a snapshot. Optional.
*
* Additional information
* This function is used to restore the target state in cases
* where values cannot simply be written to the target.
* Typical use: GPIO clock needs to be enabled, before
* GPIO is configured.
*
**********************************************************************
*/
//void OnSnapshotLoad (void) {
//}
/*********************************************************************
*
* OnSnapshotSave
*
* Function description
* Called upon saving a snapshot. Optional.
*
* Additional information
* This function is usually used to save values of the target
* state which can either not be trivially read,
* or need to be restored in a specific way or order.
* Typically use: Memory Mapped Registers,
* such as PLL and GPIO configuration.
*
**********************************************************************
*/
//void OnSnapshotSave (void) {
//}
/*********************************************************************
*
* OnError
*
* Function description
* Called when an error ocurred. Optional.
*
**********************************************************************
*/
//void OnError (void) {
//}
/*********************************************************************
*
* AfterProjectLoad
*
* Function description
* After Project load routine. Optional.
*
**********************************************************************
*/
//void AfterProjectLoad (void) {
//}
/*********************************************************************
*
* _SetupTarget
*
* Function description
* Setup the target.
* Called by AfterTargetReset() and AfterTargetDownload().
*
* Auto-generated function. May be overridden by Ozone.
*
**********************************************************************
*/
void _SetupTarget(void) {
//
// this function is intentionally empty because both inital PC and
// initial SP were chosen not to be set
//
}

@ -0,0 +1,584 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be
* reverse engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @brief Blinky Sample Application main file.
*
* This file contains the source code for a sample server application using the
* LED Button service.
*/
#include <stdint.h>
#include <string.h>
#include "app_button.h"
#include "app_error.h"
#include "app_timer.h"
#include "ble.h"
#include "ble_advdata.h"
#include "ble_conn_params.h"
#include "ble_err.h"
#include "ble_hci.h"
#include "ble_lbs.h"
#include "ble_srv_common.h"
#include "boards.h"
#include "nordic_common.h"
#include "nrf.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_qwr.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#define ADVERTISING_LED \
BSP_BOARD_LED_0 /**< Is on when device is advertising. */
#define CONNECTED_LED BSP_BOARD_LED_1 /**< Is on when device has connected. */
#define LEDBUTTON_LED \
BSP_BOARD_LED_2 /**< LED to be toggled with the help of the LED Button \
Service. */
#define LEDBUTTON_BUTTON \
BSP_BUTTON_0 /**< Button that will trigger the notification event with the \
LED Button Service */
#define DEVICE_NAME \
"Nordic_Blinky" /**< Name of device. Will be included in the advertising \
data. */
#define APP_BLE_OBSERVER_PRIO \
3 /**< Application's BLE observer priority. You shouldn't need to modify \
this value. */
#define APP_BLE_CONN_CFG_TAG \
1 /**< A tag identifying the SoftDevice BLE configuration. */
#define APP_ADV_INTERVAL \
64 /**< The advertising interval (in units of 0.625 ms; this value \
corresponds to 40 ms). */
#define APP_ADV_DURATION \
BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising time-out (in \
units of seconds). When set to 0, \
we will never time out. */
#define MIN_CONN_INTERVAL \
MSEC_TO_UNITS(100, UNIT_1_25_MS) /**< Minimum acceptable connection interval \
(0.5 seconds). */
#define MAX_CONN_INTERVAL \
MSEC_TO_UNITS( \
200, \
UNIT_1_25_MS) /**< Maximum acceptable connection interval (1 second). */
#define SLAVE_LATENCY 0 /**< Slave latency. */
#define CONN_SUP_TIMEOUT \
MSEC_TO_UNITS( \
4000, UNIT_10_MS) /**< Connection supervisory time-out (4 seconds). */
#define FIRST_CONN_PARAMS_UPDATE_DELAY \
APP_TIMER_TICKS( \
20000) /**< Time from initiating event (connect or start of \
notification) to first time sd_ble_gap_conn_param_update is \
called (15 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY \
APP_TIMER_TICKS( \
5000) /**< Time between each call to sd_ble_gap_conn_param_update after \
the first call (5 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT \
3 /**< Number of attempts before giving up the connection parameter \
negotiation. */
#define BUTTON_DETECTION_DELAY \
APP_TIMER_TICKS(50) /**< Delay from a GPIOTE event until a button is \
reported as pushed (in number of timer ticks). */
#define DEAD_BEEF \
0xDEADBEEF /**< Value used as error code on stack dump, can be used to \
identify stack location on stack unwind. */
BLE_LBS_DEF(m_lbs); /**< LED Button Service instance. */
NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */
NRF_BLE_QWR_DEF(m_qwr); /**< Context for the Queued Write module.*/
static uint16_t m_conn_handle =
BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
static uint8_t m_adv_handle =
BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an
advertising set. */
static uint8_t
m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Buffer for storing an
encoded advertising set. */
static uint8_t m_enc_scan_response_data
[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Buffer for storing an encoded scan
data. */
/**@brief Struct that contains pointers to the encoded advertising data. */
static ble_gap_adv_data_t m_adv_data = {
.adv_data = {.p_data = m_enc_advdata, .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX},
.scan_rsp_data = {
.p_data = m_enc_scan_response_data, .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX
}};
/**@brief Function for assert macro callback.
*
* @details This function will be called in case of an assert in the SoftDevice.
*
* @warning This handler is an example only and does not fit a final product.
* You need to analyze how your product is supposed to react in case of Assert.
* @warning On assert from the SoftDevice, the system can only recover on reset.
*
* @param[in] line_num Line number of the failing ASSERT call.
* @param[in] p_file_name File name of the failing ASSERT call.
*/
void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) {
app_error_handler(DEAD_BEEF, line_num, p_file_name);
}
/**@brief Function for the LEDs initialization.
*
* @details Initializes all LEDs used by the application.
*/
static void leds_init(void) { bsp_board_init(BSP_INIT_LEDS); }
/**@brief Function for the Timer initialization.
*
* @details Initializes the timer module.
*/
static void timers_init(void) {
// Initialize timer module, making it use the scheduler
ret_code_t err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
}
/**@brief Function for the GAP initialization.
*
* @details This function sets up all the necessary GAP (Generic Access Profile)
* parameters of the device including the device name, appearance, and the
* preferred connection parameters.
*/
static void gap_params_init(void) {
ret_code_t err_code;
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME,
strlen(DEVICE_NAME));
APP_ERROR_CHECK(err_code);
memset(&gap_conn_params, 0, sizeof(gap_conn_params));
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
gap_conn_params.slave_latency = SLAVE_LATENCY;
gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for initializing the GATT module.
*/
static void gatt_init(void) {
ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for initializing the Advertising functionality.
*
* @details Encodes the required advertising data and passes it to the stack.
* Also builds a structure to be passed to the stack when starting
* advertising.
*/
static void advertising_init(void) {
ret_code_t err_code;
ble_advdata_t advdata;
ble_advdata_t srdata;
ble_uuid_t adv_uuids[] = {{LBS_UUID_SERVICE, m_lbs.uuid_type}};
// Build and set advertising data.
memset(&advdata, 0, sizeof(advdata));
advdata.name_type = BLE_ADVDATA_FULL_NAME;
advdata.include_appearance = true;
advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
memset(&srdata, 0, sizeof(srdata));
srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
srdata.uuids_complete.p_uuids = adv_uuids;
err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data,
&m_adv_data.adv_data.len);
APP_ERROR_CHECK(err_code);
err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data,
&m_adv_data.scan_rsp_data.len);
APP_ERROR_CHECK(err_code);
ble_gap_adv_params_t adv_params;
// Set advertising parameters.
memset(&adv_params, 0, sizeof(adv_params));
adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
adv_params.duration = APP_ADV_DURATION;
adv_params.properties.type =
BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
adv_params.p_peer_addr = NULL;
adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
adv_params.interval = APP_ADV_INTERVAL;
err_code =
sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for handling Queued Write Module errors.
*
* @details A pointer to this function will be passed to each service which may
* need to inform the application about an error.
*
* @param[in] nrf_error Error code containing information about what went
* wrong.
*/
static void nrf_qwr_error_handler(uint32_t nrf_error) {
APP_ERROR_HANDLER(nrf_error);
}
/**@brief Function for handling write events to the LED characteristic.
*
* @param[in] p_lbs Instance of LED Button Service to which the write
* applies.
* @param[in] led_state Written/desired state of the LED.
*/
static void led_write_handler(uint16_t conn_handle, ble_lbs_t *p_lbs,
uint8_t led_state) {
if (led_state) {
bsp_board_led_on(LEDBUTTON_LED);
NRF_LOG_INFO("Received LED ON!");
} else {
bsp_board_led_off(LEDBUTTON_LED);
NRF_LOG_INFO("Received LED OFF!");
}
}
/**@brief Function for initializing services that will be used by the
* application.
*/
static void services_init(void) {
ret_code_t err_code;
ble_lbs_init_t init = {0};
nrf_ble_qwr_init_t qwr_init = {0};
// Initialize Queued Write Module.
qwr_init.error_handler = nrf_qwr_error_handler;
err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
APP_ERROR_CHECK(err_code);
// Initialize LBS.
init.led_write_handler = led_write_handler;
err_code = ble_lbs_init(&m_lbs, &init);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for handling the Connection Parameters Module.
*
* @details This function will be called for all events in the Connection
* Parameters Module that are passed to the application.
*
* @note All this function does is to disconnect. This could have been done by
* simply setting the disconnect_on_fail config parameter, but instead we use
* the event handler mechanism to demonstrate its use.
*
* @param[in] p_evt Event received from the Connection Parameters Module.
*/
static void on_conn_params_evt(ble_conn_params_evt_t *p_evt) {
ret_code_t err_code;
if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) {
err_code = sd_ble_gap_disconnect(m_conn_handle,
BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
APP_ERROR_CHECK(err_code);
}
}
/**@brief Function for handling a Connection Parameters error.
*
* @param[in] nrf_error Error code containing information about what went
* wrong.
*/
static void conn_params_error_handler(uint32_t nrf_error) {
APP_ERROR_HANDLER(nrf_error);
}
/**@brief Function for initializing the Connection Parameters module.
*/
static void conn_params_init(void) {
ret_code_t err_code;
ble_conn_params_init_t cp_init;
memset(&cp_init, 0, sizeof(cp_init));
cp_init.p_conn_params = NULL;
cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
cp_init.disconnect_on_fail = false;
cp_init.evt_handler = on_conn_params_evt;
cp_init.error_handler = conn_params_error_handler;
err_code = ble_conn_params_init(&cp_init);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for starting advertising.
*/
static void advertising_start(void) {
ret_code_t err_code;
err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
APP_ERROR_CHECK(err_code);
bsp_board_led_on(ADVERTISING_LED);
}
/**@brief Function for handling BLE events.
*
* @param[in] p_ble_evt Bluetooth stack event.
* @param[in] p_context Unused.
*/
static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) {
ret_code_t err_code;
switch (p_ble_evt->header.evt_id) {
case BLE_GAP_EVT_CONNECTED:
NRF_LOG_INFO("Connected");
bsp_board_led_on(CONNECTED_LED);
bsp_board_led_off(ADVERTISING_LED);
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
APP_ERROR_CHECK(err_code);
err_code = app_button_enable();
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_DISCONNECTED:
NRF_LOG_INFO("Disconnected");
bsp_board_led_off(CONNECTED_LED);
m_conn_handle = BLE_CONN_HANDLE_INVALID;
err_code = app_button_disable();
APP_ERROR_CHECK(err_code);
advertising_start();
break;
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
// Pairing not supported
err_code = sd_ble_gap_sec_params_reply(
m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
NRF_LOG_DEBUG("PHY update request.");
ble_gap_phys_t const phys = {
.rx_phys = BLE_GAP_PHY_AUTO,
.tx_phys = BLE_GAP_PHY_AUTO,
};
err_code =
sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
APP_ERROR_CHECK(err_code);
} break;
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
// No system attributes have been stored.
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
APP_ERROR_CHECK(err_code);
break;
case BLE_GATTC_EVT_TIMEOUT:
// Disconnect on GATT Client timeout event.
NRF_LOG_DEBUG("GATT Client Timeout.");
err_code =
sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
break;
case BLE_GATTS_EVT_TIMEOUT:
// Disconnect on GATT Server timeout event.
NRF_LOG_DEBUG("GATT Server Timeout.");
err_code =
sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
break;
default:
// No implementation needed.
break;
}
}
/**@brief Function for initializing the BLE stack.
*
* @details Initializes the SoftDevice and the BLE event interrupt.
*/
static void ble_stack_init(void) {
ret_code_t err_code;
err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK(err_code);
// Configure the BLE stack using the default settings.
// Fetch the start address of the application RAM.
uint32_t ram_start = 0;
err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
APP_ERROR_CHECK(err_code);
// Enable BLE stack.
err_code = nrf_sdh_ble_enable(&ram_start);
APP_ERROR_CHECK(err_code);
// Register a handler for BLE events.
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler,
NULL);
}
/**@brief Function for handling events from the button handler module.
*
* @param[in] pin_no The pin that the event applies to.
* @param[in] button_action The button action (press/release).
*/
static void button_event_handler(uint8_t pin_no, uint8_t button_action) {
ret_code_t err_code;
switch (pin_no) {
case LEDBUTTON_BUTTON:
NRF_LOG_INFO("Send button state change.");
err_code = ble_lbs_on_button_change(m_conn_handle, &m_lbs, button_action);
if (err_code != NRF_SUCCESS &&
err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
err_code != NRF_ERROR_INVALID_STATE &&
err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) {
APP_ERROR_CHECK(err_code);
}
break;
default:
APP_ERROR_HANDLER(pin_no);
break;
}
}
/**@brief Function for initializing the button handler module.
*/
static void buttons_init(void) {
ret_code_t err_code;
// The array must be static because a pointer to it will be saved in the
// button handler module.
static app_button_cfg_t buttons[] = {
{LEDBUTTON_BUTTON, false, BUTTON_PULL, button_event_handler}};
err_code =
app_button_init(buttons, ARRAY_SIZE(buttons), BUTTON_DETECTION_DELAY);
APP_ERROR_CHECK(err_code);
}
static void log_init(void) {
ret_code_t err_code = NRF_LOG_INIT(NULL);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEFAULT_BACKENDS_INIT();
}
/**@brief Function for initializing power management.
*/
static void power_management_init(void) {
ret_code_t err_code;
err_code = nrf_pwr_mgmt_init();
APP_ERROR_CHECK(err_code);
}
/**@brief Function for handling the idle state (main loop).
*
* @details If there is no pending log operation, then sleep until next the next
* event occurs.
*/
static void idle_state_handle(void) {
if (NRF_LOG_PROCESS() == false) {
nrf_pwr_mgmt_run();
}
}
/**@brief Function for application main entry.
*/
int main(void) {
// Initialize.
log_init();
leds_init();
timers_init();
buttons_init();
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
// Start execution.
NRF_LOG_INFO("Blinky example started.");
advertising_start();
// Enter main loop.
for (;;) {
idle_state_handle();
}
}
/**
* @}
*/

@ -0,0 +1,130 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xd9000
RAM (rwx) : ORIGIN = 0x20002300, LENGTH = 0x3dd00
}
SECTIONS
{
}
SECTIONS
{
. = ALIGN(4);
.mem_section_dummy_ram :
{
}
.cli_sorted_cmd_ptrs :
{
PROVIDE(__start_cli_sorted_cmd_ptrs = .);
KEEP(*(.cli_sorted_cmd_ptrs))
PROVIDE(__stop_cli_sorted_cmd_ptrs = .);
} > RAM
.fs_data :
{
PROVIDE(__start_fs_data = .);
KEEP(*(.fs_data))
PROVIDE(__stop_fs_data = .);
} > RAM
.log_dynamic_data :
{
PROVIDE(__start_log_dynamic_data = .);
KEEP(*(SORT(.log_dynamic_data*)))
PROVIDE(__stop_log_dynamic_data = .);
} > RAM
.log_filter_data :
{
PROVIDE(__start_log_filter_data = .);
KEEP(*(SORT(.log_filter_data*)))
PROVIDE(__stop_log_filter_data = .);
} > RAM
} INSERT AFTER .data;
SECTIONS
{
.mem_section_dummy_rom :
{
}
.sdh_soc_observers :
{
PROVIDE(__start_sdh_soc_observers = .);
KEEP(*(SORT(.sdh_soc_observers*)))
PROVIDE(__stop_sdh_soc_observers = .);
} > FLASH
.pwr_mgmt_data :
{
PROVIDE(__start_pwr_mgmt_data = .);
KEEP(*(SORT(.pwr_mgmt_data*)))
PROVIDE(__stop_pwr_mgmt_data = .);
} > FLASH
.sdh_ble_observers :
{
PROVIDE(__start_sdh_ble_observers = .);
KEEP(*(SORT(.sdh_ble_observers*)))
PROVIDE(__stop_sdh_ble_observers = .);
} > FLASH
.sdh_req_observers :
{
PROVIDE(__start_sdh_req_observers = .);
KEEP(*(SORT(.sdh_req_observers*)))
PROVIDE(__stop_sdh_req_observers = .);
} > FLASH
.sdh_state_observers :
{
PROVIDE(__start_sdh_state_observers = .);
KEEP(*(SORT(.sdh_state_observers*)))
PROVIDE(__stop_sdh_state_observers = .);
} > FLASH
.sdh_stack_observers :
{
PROVIDE(__start_sdh_stack_observers = .);
KEEP(*(SORT(.sdh_stack_observers*)))
PROVIDE(__stop_sdh_stack_observers = .);
} > FLASH
.nrf_queue :
{
PROVIDE(__start_nrf_queue = .);
KEEP(*(.nrf_queue))
PROVIDE(__stop_nrf_queue = .);
} > FLASH
.nrf_balloc :
{
PROVIDE(__start_nrf_balloc = .);
KEEP(*(.nrf_balloc))
PROVIDE(__stop_nrf_balloc = .);
} > FLASH
.cli_command :
{
PROVIDE(__start_cli_command = .);
KEEP(*(.cli_command))
PROVIDE(__stop_cli_command = .);
} > FLASH
.crypto_data :
{
PROVIDE(__start_crypto_data = .);
KEEP(*(SORT(.crypto_data*)))
PROVIDE(__stop_crypto_data = .);
} > FLASH
.log_const_data :
{
PROVIDE(__start_log_const_data = .);
KEEP(*(SORT(.log_const_data*)))
PROVIDE(__stop_log_const_data = .);
} > FLASH
.log_backends :
{
PROVIDE(__start_log_backends = .);
KEEP(*(SORT(.log_backends*)))
PROVIDE(__stop_log_backends = .);
} > FLASH
} INSERT AFTER .text
INCLUDE "nrf_common.ld"

File diff suppressed because it is too large Load Diff

@ -0,0 +1,4 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define VERSION_PATCH 0
#define VERSION_BUILD 0

@ -0,0 +1,208 @@
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 2014 - 2020 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* conditions are met: *
* *
* - Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* *
* - Neither the name of SEGGER Microcontroller GmbH *
* nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific *
* prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. *
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
;
;----------------------------------------------------------------------
;File : HardFaultHandler.S
;Purpose : HardFault exception handler for IAR, Keil and GNU assembler.
; Evaluates used stack (MSP, PSP) and passes appropiate stack
; pointer to the HardFaultHandler "C"-routine.
;------------- END-OF-HEADER ------------------------------------------
;*/
#ifndef __IAR_SYSTEMS_ASM__
#ifndef __CC_ARM
#ifndef __clang__
#ifndef __GNUC__
#error "Unsupported assembler!"
#endif
#endif
#endif
#endif
;/*********************************************************************
;*
;* Forward declarations of segments used
;*
;**********************************************************************
;*/
#if (defined(__IAR_SYSTEMS_ASM__))
SECTION CODE:CODE:NOROOT(2)
SECTION CSTACK:DATA:NOROOT(3)
#elif (defined(__CC_ARM))
AREA OSKERNEL, CODE, READONLY, ALIGN=2
PRESERVE8
#endif
;/*********************************************************************
;*
;* Publics
;*
;**********************************************************************
;*/
#if (defined(__IAR_SYSTEMS_ASM__))
SECTION .text:CODE:NOROOT(2)
PUBLIC HardFault_Handler
#elif (defined(__CC_ARM))
EXPORT HardFault_Handler
#elif (defined(__clang__) || defined(__GNUC__))
.global HardFault_Handler
.type HardFault_Handler, function
#endif
;/*********************************************************************
;*
;* Externals, code
;*
;**********************************************************************
;*/
#if (defined(__IAR_SYSTEMS_ASM__))
EXTERN HardFaultHandler
#elif (defined(__CC_ARM))
IMPORT HardFaultHandler
#elif (defined(__clang__) || defined(__GNUC__))
.extern HardFaultHandler
#endif
;/*********************************************************************
;*
;* CODE segment
;*
;**********************************************************************
;*/
#if (defined(__clang__) || defined(__GNUC__))
.syntax unified
.thumb
.balign 4
.text
#else
THUMB
#endif
;/*********************************************************************
;*
;* Global functions
;*
;**********************************************************************
;*/
;/*********************************************************************
;*
;* HardFault_Handler()
;*
;* Function description
;* Evaluates the used stack (MSP, PSP) and passes the appropiate
;* stack pointer to the HardFaultHandler "C"-routine.
;*
;* Notes
;* (1) Ensure that HardFault_Handler is part of the exception table
;*/
#if (defined(__clang__) || defined(__GNUC__))
HardFault_Handler:
#else
HardFault_Handler
#endif
#if (defined(__IAR_SYSTEMS_ASM__) && defined(__ARM6M__) && (__CORE__ == __ARM6M__)) || \
(defined(__CC_ARM) && defined(__TARGET_ARCH_6S_M)) || \
(defined(__clang__) && defined(__ARM_ARCH) && (__ARM_ARCH == 6)) || \
(defined(__GNUC__) && (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__)))
;// This version is for Cortex M0
movs R0, #4
mov R1, LR
tst R0, R1 ;// Check EXC_RETURN in Link register bit 2.
bne Uses_PSP
mrs R0, MSP ;// Stacking was using MSP.
b Pass_StackPtr
#if (defined(__clang__) || defined(__GNUC__))
Uses_PSP:
#else
Uses_PSP
#endif
mrs R0, PSP ;// Stacking was using PSP.
#if (defined(__GNUC__) || defined(__clang__))
Pass_StackPtr:
#else
Pass_StackPtr
#endif
#else
;// This version is for Cortex M3, Cortex M4 and Cortex M4F
tst LR, #4 ;// Check EXC_RETURN in Link register bit 2.
ite EQ
mrseq R0, MSP ;// Stacking was using MSP.
mrsne R0, PSP ;// Stacking was using PSP.
#endif
#if (defined(__CC_ARM))
ALIGN
#endif
ldr R1,=HardFaultHandler
bx R1 ;// Stack pointer passed through R0.
#if (defined(__clang__) || defined(__GNUC__))
.end
#else
END
#endif
;/****** End Of File *************************************************/

@ -0,0 +1,155 @@
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2018 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the monitor mode protocol and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* conditions are met: *
* *
* - Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* *
* - Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided *
* with the distribution. *
* *
* - Neither the name of SEGGER Microcontroller GmbH *
* nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific *
* prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
----------------------------------------------------------------------
File : JLINK_MONITOR.c
Purpose : Implementation of debug monitor for J-Link monitor mode debug on Cortex-M devices.
-------- END-OF-HEADER ---------------------------------------------
*/
#include "JLINK_MONITOR.h"
/*********************************************************************
*
* Configuration
*
**********************************************************************
*/
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
/*********************************************************************
*
* Types
*
**********************************************************************
*/
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
/*********************************************************************
*
* JLINK_MONITOR_OnExit()
*
* Function description
* Called from DebugMon_Handler(), once per debug exit.
* May perform some target specific operations to be done on debug mode exit.
*
* Notes
* (1) Must not keep the CPU busy for more than 100 ms
*/
void JLINK_MONITOR_OnExit(void) {
//
// Add custom code here
//
// BSP_ClrLED(0);
}
/*********************************************************************
*
* JLINK_MONITOR_OnEnter()
*
* Function description
* Called from DebugMon_Handler(), once per debug entry.
* May perform some target specific operations to be done on debug mode entry
*
* Notes
* (1) Must not keep the CPU busy for more than 100 ms
*/
void JLINK_MONITOR_OnEnter(void) {
//
// Add custom code here
//
// BSP_SetLED(0);
// BSP_ClrLED(1);
}
/*********************************************************************
*
* JLINK_MONITOR_OnPoll()
*
* Function description
* Called periodically from DebugMon_Handler(), to perform some actions that need to be performed periodically during debug mode.
*
* Notes
* (1) Must not keep the CPU busy for more than 100 ms
*/
void JLINK_MONITOR_OnPoll(void) {
//
// Add custom code here
//
// BSP_ToggleLED(0);
// _Delay(500000);
}
/****** End Of File *************************************************/

@ -0,0 +1,65 @@
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2018 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the monitor mode protocol and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* conditions are met: *
* *
* - Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* *
* - Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided *
* with the distribution. *
* *
* - Neither the name of SEGGER Microcontroller GmbH *
* nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific *
* prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
----------------------------------------------------------------------
File : JLINK_MONITOR.h
Purpose : Header file of debug monitor for J-Link monitor mode debug on Cortex-M devices.
-------- END-OF-HEADER ---------------------------------------------
*/
#ifndef JLINK_MONITOR_H
#define JLINK_MONITOR_H
void JLINK_MONITOR_OnExit (void);
void JLINK_MONITOR_OnEnter (void);
void JLINK_MONITOR_OnPoll (void);
#endif
/****** End Of File *************************************************/

@ -0,0 +1,927 @@
/*********************************************************************
* (c) SEGGER Microcontroller GmbH *
* The Embedded Experts *
* www.segger.com *
**********************************************************************
* *
* (c) 1995 - 2020 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the monitor mode protocol and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* conditions are met: *
* *
* - Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* *
* - Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided *
* with the distribution. *
* *
* - Neither the name of SEGGER Microcontroller GmbH *
* nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific *
* prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
----------------------------------------------------------------------
File : JLINK_MONITOR_ISR_SES.s
Purpose : Implementation of debug monitor for J-Link monitor mode
debug on Cortex-M devices, supporting SES compiler.
-------- END-OF-HEADER ---------------------------------------------
*/
.name JLINK_MONITOR_ISR
.syntax unified
.extern JLINK_MONITOR_OnEnter
.extern JLINK_MONITOR_OnExit
.extern JLINK_MONITOR_OnPoll
.global DebugMon_Handler
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
#define _MON_VERSION 100 // V x.yy
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
#define _APP_SP_OFF_R0 0x00
#define _APP_SP_OFF_R1 0x04
#define _APP_SP_OFF_R2 0x08
#define _APP_SP_OFF_R3 0x0C
#define _APP_SP_OFF_R12 0x10
#define _APP_SP_OFF_R14_LR 0x14
#define _APP_SP_OFF_PC 0x18
#define _APP_SP_OFF_XPSR 0x1C
#define _APP_SP_OFF_S0 0x20
#define _APP_SP_OFF_S1 0x24
#define _APP_SP_OFF_S2 0x28
#define _APP_SP_OFF_S3 0x2C
#define _APP_SP_OFF_S4 0x30
#define _APP_SP_OFF_S5 0x34
#define _APP_SP_OFF_S6 0x38
#define _APP_SP_OFF_S7 0x3C
#define _APP_SP_OFF_S8 0x40
#define _APP_SP_OFF_S9 0x44
#define _APP_SP_OFF_S10 0x48
#define _APP_SP_OFF_S11 0x4C
#define _APP_SP_OFF_S12 0x50
#define _APP_SP_OFF_S13 0x54
#define _APP_SP_OFF_S14 0x58
#define _APP_SP_OFF_S15 0x5C
#define _APP_SP_OFF_FPSCR 0x60
#define _NUM_BYTES_BASIC_STACKFRAME 32
#define _NUM_BYTES_EXTENDED_STACKFRAME 104 // Values for stackframes are explained at location where they are used
#define _SYSTEM_DCRDR_OFF 0x00
#define _SYSTEM_DEMCR_OFF 0x04
#define _SYSTEM_DHCSR 0xE000EDF0 // Debug Halting Control and Status Register (DHCSR)
#define _SYSTEM_DCRSR 0xE000EDF4 // Debug Core Register Selector Register (DCRSR)
#define _SYSTEM_DCRDR 0xE000EDF8 // Debug Core Register Data Register (DCRDR)
#define _SYSTEM_DEMCR 0xE000EDFC // Debug Exception and Monitor Control Register (DEMCR)
#define _SYSTEM_FPCCR 0xE000EF34 // Floating-Point Context Control Register (FPCCR)
#define _SYSTEM_FPCAR 0xE000EF38 // Floating-Point Context Address Register (FPCAR)
#define _SYSTEM_FPDSCR 0xE000EF3C // Floating-Point Default Status Control Register (FPDSCR)
#define _SYSTEM_MVFR0 0xE000EF40 // Media and FP Feature Register 0 (MVFR0)
#define _SYSTEM_MVFR1 0xE000EF44 // Media and FP Feature Register 1 (MVFR1)
/*
* Defines for determining if the current debug config supports FPU registers
* For some compilers like IAR EWARM when disabling the FPU in the compiler settings an error is thrown when
*/
#ifdef __FPU_PRESENT
#if __FPU_PRESENT
#define _HAS_FPU_REGS 1
#else
#define _HAS_FPU_REGS 0
#endif
#else
#define _HAS_FPU_REGS 0
#endif
/*********************************************************************
*
* Signature of monitor
*
* Function description
* Needed for targets where also a boot ROM is present that possibly specifies a vector table with a valid debug monitor exception entry
*/
.section .text, "ax"
//
// JLINKMONHANDLER
//
.byte 0x4A
.byte 0x4C
.byte 0x49
.byte 0x4E
.byte 0x4B
.byte 0x4D
.byte 0x4F
.byte 0x4E
.byte 0x48
.byte 0x41
.byte 0x4E
.byte 0x44
.byte 0x4C
.byte 0x45
.byte 0x52
.byte 0x00 // Align to 8-bytes
/*********************************************************************
*
* DebugMon_Handler()
*
* Function description
* Debug monitor handler. CPU enters this handler in case a "halt" request is made from the debugger.
* This handler is also responsible for handling commands that are sent by the debugger.
*
* Notes
* This is actually the ISR for the debug inerrupt (exception no. 12)
*/
.thumb_func
DebugMon_Handler:
/*
General procedure:
DCRDR is used as communication register
DEMCR[19] is used as ready flag
For the command J-Link sends to the monitor: DCRDR[7:0] == Cmd, DCRDR[31:8] == ParamData
1) Monitor sets DEMCR[19] whenever it is ready to receive new commands/data
DEMCR[19] is initially set on debug monitor entry
2) J-Link will clear DEMCR[19] it has placed command/data in DCRDR for monitor
3) Monitor will wait for DEMCR[19] to be cleared
4) Monitor will process command (May cause additional data transfers etc., depends on command). Monitor will set DEMCR[19] whenever it has placed data for J-Link in the DCRDR
5) No restart-CPU command? => Back to 2), Otherwise => 6)
6) Monitor will clear DEMCR[19] 19 to indicate that it is no longer ready
*/
PUSH {LR}
BL JLINK_MONITOR_OnEnter
POP {LR}
LDR.N R3,_AddrDCRDR // 0xe000edf8 == _SYSTEM_DCRDR
B.N _IndicateMonReady
_WaitProbeReadIndicateMonRdy: // while(_SYSTEM_DEMCR & (1uL << 19)); => Wait until J-Link has read item
LDR R0,[R3, #+_SYSTEM_DEMCR_OFF] // _SYSTEM_DEMCR
LSLS R0,R0,#+12
BMI.N _WaitProbeReadIndicateMonRdy
_IndicateMonReady:
LDR R0,[R3, #+_SYSTEM_DEMCR_OFF] // _SYSTEM_DEMCR |= (1uL << 19); => Set MON_REQ bit, so J-Link knows monitor is ready to receive commands
ORR R0,R0,#0x80000
STR R0,[R3, #+_SYSTEM_DEMCR_OFF]
/*
During command loop:
R0 = Tmp
R1 = Tmp
R2 = Tmp
R3 = &_SYSTEM_DCRDR (allows also access to DEMCR with offset)
R12 = Tmp
Outside command loop R0-R3 and R12 may be overwritten by MONITOR_OnPoll()
*/
_WaitForJLinkCmd: // do {
PUSH {LR}
BL JLINK_MONITOR_OnPoll
POP {LR}
LDR.N R3,_AddrDCRDR // 0xe000edf8 == _SYSTEM_DCRDR
LDR R0,[R3, #+_SYSTEM_DEMCR_OFF]
LSRS R0,R0,#+20 // DEMCR[19] -> Carry Clear? => J-Link has placed command for us
BCS _WaitForJLinkCmd
/*
Perform command
Command is placed by J-Link in DCRDR[7:0] and additional parameter data is stored in DCRDR[31:8]
J-Link clears DEMCR[19] to indicate that it placed a command/data or read data
Monitor sets DEMCR[19] to indicate that it placed data or read data / is ready for a new command
Setting DEMCR[19] indicates "monitor ready for new command / data" and also indicates: "data has been placed in DCRDR by monitor, for J-Link"
Therefore it is responsibility of the commands to respond to the commands accordingly
Commands for debug monitor
Commands must not exceed 0xFF (255) as we only defined 8-bits for command-part. Higher 24-bits are parameter info for current command
Protocol for different commands:
J-Link: Cmd -> DCRDR, DEMCR[19] -> 0 => Cmd placed by probe
*/
LDR R0,[R3, #+_SYSTEM_DCRDR_OFF] // ParamInfo = _SYSTEM_DCRDR
LSRS R1,R0,#+8 // ParamInfo >>= 8
LSLS R0,R0,#+24
LSRS R0,R0,#+24 // Cmd = ParamInfo & 0xFF
//
// switch (Cmd)
//
CMP R0,#+0
BEQ.N _HandleGetMonVersion // case _MON_CMD_GET_MONITOR_VERSION
CMP R0,#+2
BEQ.N _HandleReadReg // case _MON_CMD_READ_REG
BCC.N _HandleRestartCPU // case _MON_CMD_RESTART_CPU
CMP R0,#+3
BEQ.N _HandleWriteReg_Veneer // case _MON_CMD_WRITE_REG
B.N _IndicateMonReady // default : while (1);
/*
Return
_MON_CMD_RESTART_CPU
CPU: DEMCR[19] -> 0 => Monitor no longer ready
*/
_HandleRestartCPU:
LDR R0,[R3, #+_SYSTEM_DEMCR_OFF] // _SYSTEM_DEMCR &= ~(1uL << 19); => Clear MON_REQ to indicate that monitor is no longer active
BIC R0,R0,#0x80000
STR R0,[R3, #+_SYSTEM_DEMCR_OFF]
PUSH {LR}
BL JLINK_MONITOR_OnExit
POP {PC}
//
// Place data section here to not get in trouble with load-offsets
//
.section .text, "ax", %progbits
.align 2
_AddrDCRDR:
.long 0xE000EDF8
_AddrCPACR:
.long 0xE000ED88
.section .text, "ax"
.thumb_func
;/*********************************************************************
;*
;* _HandleGetMonVersion
;*
;*/
_HandleGetMonVersion:
/*
_MON_CMD_GET_MONITOR_VERSION
CPU: Data -> DCRDR, DEMCR[19] -> 1 => Data ready
J-Link: DCRDR -> Read, DEMCR[19] -> 0 => Data read
CPU: DEMCR[19] -> 1 => Mon ready
*/
MOVS R0,#+_MON_VERSION
STR R0,[R3, #+_SYSTEM_DCRDR_OFF] // _SYSTEM_DCRDR = x
LDR R0,[R3, #+_SYSTEM_DEMCR_OFF] // _SYSTEM_DEMCR |= (1uL << 19); => Set MON_REQ bit, so J-Link knows monitor is ready to receive commands
ORR R0,R0,#0x80000
STR R0,[R3, #+_SYSTEM_DEMCR_OFF] // Indicate data ready
B _WaitProbeReadIndicateMonRdy
/*********************************************************************
*
* _HandleReadReg
*
*/
_HandleWriteReg_Veneer:
B.N _HandleWriteReg
_HandleReadReg:
/*
_MON_CMD_READ_REG
CPU: Data -> DCRDR, DEMCR[19] -> 1 => Data ready
J-Link: DCRDR -> Read, DEMCR[19] -> 0 => Data read
CPU: DEMCR[19] -> 1 => Mon ready
Register indexes
0-15: R0-R15 (13 == R13 reserved => is banked ... Has to be read as PSP / MSP. Decision has to be done by J-Link DLL side!)
16: XPSR
17: MSP
18: PSP
19: CFBP CONTROL/FAULTMASK/BASEPRI/PRIMASK (packed into 4 bytes of word. CONTROL = CFBP[31:24], FAULTMASK = CFBP[16:23], BASEPRI = CFBP[15:8], PRIMASK = CFBP[7:0]
20: FPSCR
21-52: FPS0-FPS31
Register usage when entering this "subroutine":
R0 Cmd
R1 ParamInfo
R2 ---
R3 = &_SYSTEM_DCRDR (allows also access to DEMCR with offset)
R12 ---
Table B1-9 EXC_RETURN definition of exception return behavior, with FP extension
LR Return to Return SP Frame type
---------------------------------------------------------
0xFFFFFFE1 Handler mode. MSP Extended
0xFFFFFFE9 Thread mode MSP Extended
0xFFFFFFED Thread mode PSP Extended
0xFFFFFFF1 Handler mode. MSP Basic
0xFFFFFFF9 Thread mode MSP Basic
0xFFFFFFFD Thread mode PSP Basic
So LR[2] == 1 => Return stack == PSP else MSP
R0-R3, R12, PC, xPSR can be read from application stackpointer
Other regs can be read directly
*/
LSRS R2,LR,#+3 // Shift LR[2] into carry => Carry clear means that CPU was running on MSP
ITE CS
MRSCS R2,PSP
MRSCC R2,MSP
CMP R1,#+4 // if (RegIndex < 4) { (R0-R3)
BCS _HandleReadRegR4
LDR R0,[R2, R1, LSL #+2] // v = [SP + Rx * 4] (R0-R3)
B.N _HandleReadRegDone
_HandleReadRegR4:
CMP R1,#+5 // if (RegIndex < 5) { (R4)
BCS _HandleReadRegR5
MOV R0,R4
B.N _HandleReadRegDone
_HandleReadRegR5:
CMP R1,#+6 // if (RegIndex < 6) { (R5)
BCS _HandleReadRegR6
MOV R0,R5
B.N _HandleReadRegDone
_HandleReadRegR6:
CMP R1,#+7 // if (RegIndex < 7) { (R6)
BCS _HandleReadRegR7
MOV R0,R6
B.N _HandleReadRegDone
_HandleReadRegR7:
CMP R1,#+8 // if (RegIndex < 8) { (R7)
BCS _HandleReadRegR8
MOV R0,R7
B.N _HandleReadRegDone
_HandleReadRegR8:
CMP R1,#+9 // if (RegIndex < 9) { (R8)
BCS _HandleReadRegR9
MOV R0,R8
B.N _HandleReadRegDone
_HandleReadRegR9:
CMP R1,#+10 // if (RegIndex < 10) { (R9)
BCS _HandleReadRegR10
MOV R0,R9
B.N _HandleReadRegDone
_HandleReadRegR10:
CMP R1,#+11 // if (RegIndex < 11) { (R10)
BCS _HandleReadRegR11
MOV R0,R10
B.N _HandleReadRegDone
_HandleReadRegR11:
CMP R1,#+12 // if (RegIndex < 12) { (R11)
BCS _HandleReadRegR12
MOV R0,R11
B.N _HandleReadRegDone
_HandleReadRegR12:
CMP R1,#+14 // if (RegIndex < 14) { (R12)
BCS _HandleReadRegR14
LDR R0,[R2, #+_APP_SP_OFF_R12]
B.N _HandleReadRegDone
_HandleReadRegR14:
CMP R1,#+15 // if (RegIndex < 15) { (R14 / LR)
BCS _HandleReadRegR15
LDR R0,[R2, #+_APP_SP_OFF_R14_LR]
B.N _HandleReadRegDone
_HandleReadRegR15:
CMP R1,#+16 // if (RegIndex < 16) { (R15 / PC)
BCS _HandleReadRegXPSR
LDR R0,[R2, #+_APP_SP_OFF_PC]
B.N _HandleReadRegDone
_HandleReadRegXPSR:
CMP R1,#+17 // if (RegIndex < 17) { (xPSR)
BCS _HandleReadRegMSP
LDR R0,[R2, #+_APP_SP_OFF_XPSR]
B.N _HandleReadRegDone
_HandleReadRegMSP:
/*
Stackpointer is tricky because we need to get some info about the SP used in the user app, first
Handle reading R0-R3 which can be read right from application stackpointer
Table B1-9 EXC_RETURN definition of exception return behavior, with FP extension
LR Return to Return SP Frame type
---------------------------------------------------------
0xFFFFFFE1 Handler mode. MSP Extended
0xFFFFFFE9 Thread mode MSP Extended
0xFFFFFFED Thread mode PSP Extended
0xFFFFFFF1 Handler mode. MSP Basic
0xFFFFFFF9 Thread mode MSP Basic
0xFFFFFFFD Thread mode PSP Basic
So LR[2] == 1 => Return stack == PSP else MSP
Per architecture definition: Inside monitor (exception) SP = MSP
Stack pointer handling is complicated because it is different what is pushed on the stack before entering the monitor ISR...
Cortex-M: 8 regs
Cortex-M + forced-stack-alignment: 8 regs + 1 dummy-word if stack was not 8-byte aligned
Cortex-M + FPU: 8 regs + 17 FPU regs + 1 dummy-word + 1-dummy word if stack was not 8-byte aligned
Cortex-M + FPU + lazy mode: 8 regs + 17 dummy-words + 1 dummy-word + 1-dummy word if stack was not 8-byte aligned
*/
CMP R1,#+18 // if (RegIndex < 18) { (MSP)
BCS _HandleReadRegPSP
MRS R0,MSP
LSRS R1,LR,#+3 // LR[2] -> Carry == 0 => CPU was running on MSP => Needs correction
BCS _HandleReadRegDone_Veneer // CPU was running on PSP? => No correction necessary
_HandleSPCorrection:
LSRS R1,LR,#+5 // LR[4] -> Carry == 0 => extended stack frame has been allocated. See ARM DDI0403D, B1.5.7 Stack alignment on exception entry
ITE CS
ADDCS R0,R0,#+_NUM_BYTES_BASIC_STACKFRAME
ADDCC R0,R0,#+_NUM_BYTES_EXTENDED_STACKFRAME
LDR R1,[R2, #+_APP_SP_OFF_XPSR] // Get xPSR from application stack (R2 has been set to app stack on beginning of _HandleReadReg)
LSRS R1,R1,#+5 // xPSR[9] -> Carry == 1 => Stack has been force-aligned before pushing regs. See ARM DDI0403D, B1.5.7 Stack alignment on exception entry
IT CS
ADDCS R0,R0,#+4
B _HandleReadRegDone
_HandleReadRegPSP: // RegIndex == 18
CMP R1,#+19 // if (RegIndex < 19) {
BCS _HandleReadRegCFBP
MRS R0,PSP // PSP is not touched by monitor
LSRS R1,LR,#+3 // LR[2] -> Carry == 1 => CPU was running on PSP => Needs correction
BCC _HandleReadRegDone_Veneer // CPU was running on MSP? => No correction of PSP necessary
B _HandleSPCorrection
_HandleReadRegCFBP:
/*
CFBP is a register that can only be read via debug probe and is a merger of the following regs:
CONTROL/FAULTMASK/BASEPRI/PRIMASK (packed into 4 bytes of word. CONTROL = CFBP[31:24], FAULTMASK = CFBP[16:23], BASEPRI = CFBP[15:8], PRIMASK = CFBP[7:0]
To keep J-Link side the same for monitor and halt mode, we also return CFBP in monitor mode
*/
CMP R1,#+20 // if (RegIndex < 20) { (CFBP)
BCS _HandleReadRegFPU
MOVS R0,#+0
MRS R2,PRIMASK
ORRS R0,R2 // Merge PRIMASK into CFBP[7:0]
MRS R2,BASEPRI
LSLS R2,R2,#+8 // Merge BASEPRI into CFBP[15:8]
ORRS R0,R2
MRS R2,FAULTMASK
LSLS R2,R2,#+16 // Merge FAULTMASK into CFBP[23:16]
ORRS R0,R2
MRS R2,CONTROL
LSRS R1,LR,#3 // LR[2] -> Carry. CONTROL.SPSEL is saved to LR[2] on exception entry => ARM DDI0403D, B1.5.6 Exception entry behavior
IT CS // As J-Link sees value of CONTROL at application time, we need reconstruct original value of CONTROL
ORRCS R2,R2,#+2 // CONTROL.SPSEL (CONTROL[1]) == 0 inside monitor
LSRS R1,LR,#+5 // LR[4] == NOT(CONTROL.FPCA) -> Carry
ITE CS // Merge original value of FPCA (CONTROL[2]) into read data
BICCS R2,R2,#+0x04 // Remember LR contains NOT(CONTROL)
ORRCC R2,R2,#+0x04
LSLS R2,R2,#+24
ORRS R0,R2
B.N _HandleReadRegDone
_HandleReadRegFPU:
#if _HAS_FPU_REGS
CMP R1,#+53 // if (RegIndex < 53) { (20 (FPSCR), 21-52 FPS0-FPS31)
BCS _HandleReadRegDone_Veneer
/*
Read Coprocessor Access Control Register (CPACR) to check if CP10 and CP11 are enabled
If not, access to floating point is not possible
CPACR[21:20] == CP10 enable. 0b01 = Privileged access only. 0b11 = Full access. Other = reserved
CPACR[23:22] == CP11 enable. 0b01 = Privileged access only. 0b11 = Full access. Other = reserved
*/
LDR R0,_AddrCPACR
LDR R0,[R0]
LSLS R0,R0,#+8
LSRS R0,R0,#+28
CMP R0,#+0xF
BEQ _HandleReadRegFPU_Allowed
CMP R0,#+0x5
BNE _HandleReadRegDone_Veneer
_HandleReadRegFPU_Allowed:
CMP R1,#+21 // if (RegIndex < 21) (20 == FPSCR)
BCS _HandleReadRegFPS0_FPS31
LSRS R0,LR,#+5 // CONTROL[2] == FPCA => NOT(FPCA) saved to LR[4]. LR[4] == 0 => Extended stack frame, so FPU regs possibly on stack
BCS _HandleReadFPSCRLazyMode // Remember: NOT(FPCA) is stored to LR. == 0 means: Extended stack frame
LDR R0,=_SYSTEM_FPCCR
LDR R0,[R0]
LSLS R0,R0,#+2 // FPCCR[30] -> Carry == 1 indicates if lazy mode is active, so space on stack is reserved but FPU registers are not saved on stack
BCS _HandleReadFPSCRLazyMode
LDR R0,[R2, #+_APP_SP_OFF_FPSCR]
B _HandleReadRegDone
_HandleReadFPSCRLazyMode:
VMRS R0,FPSCR
B _HandleReadRegDone
_HandleReadRegFPS0_FPS31: // RegIndex == 21-52
LSRS R0,LR,#+5 // CONTROL[2] == FPCA => NOT(FPCA) saved to LR[4]. LR[4] == 0 => Extended stack frame, so FPU regs possibly on stack
BCS _HandleReadFPS0_FPS31LazyMode // Remember: NOT(FPCA) is stored to LR. == 0 means: Extended stack frame
LDR R0,=_SYSTEM_FPCCR
LDR R0,[R0]
LSLS R0,R0,#+2 // FPCCR[30] -> Carry == 1 indicates if lazy mode is active, so space on stack is reserved but FPU registers are not saved on stack
BCS _HandleReadFPS0_FPS31LazyMode
SUBS R1,#+21 // Convert absolute reg index into rel. one
LSLS R1,R1,#+2 // RegIndex to position on stack
ADDS R1,#+_APP_SP_OFF_S0
LDR R0,[R2, R1]
_HandleReadRegDone_Veneer:
B _HandleReadRegDone
_HandleReadFPS0_FPS31LazyMode:
SUBS R1,#+20 // convert abs. RegIndex into rel. one
MOVS R0,#+6
MULS R1,R0,R1
LDR R0,=_HandleReadRegUnknown
SUB R0,R0,R1 // _HandleReadRegUnknown - 6 * ((RegIndex - 21) + 1)
ORR R0,R0,#1 // Thumb bit needs to be set in DestAddr
BX R0
//
// Table for reading FPS0-FPS31
//
VMOV R0,S31 // v = FPSx
B _HandleReadRegDone
VMOV R0,S30
B _HandleReadRegDone
VMOV R0,S29
B _HandleReadRegDone
VMOV R0,S28
B _HandleReadRegDone
VMOV R0,S27
B _HandleReadRegDone
VMOV R0,S26
B _HandleReadRegDone
VMOV R0,S25
B _HandleReadRegDone
VMOV R0,S24
B _HandleReadRegDone
VMOV R0,S23
B _HandleReadRegDone
VMOV R0,S22
B _HandleReadRegDone
VMOV R0,S21
B _HandleReadRegDone
VMOV R0,S20
B _HandleReadRegDone
VMOV R0,S19
B _HandleReadRegDone
VMOV R0,S18
B _HandleReadRegDone
VMOV R0,S17
B _HandleReadRegDone
VMOV R0,S16
B _HandleReadRegDone
VMOV R0,S15
B _HandleReadRegDone
VMOV R0,S14
B _HandleReadRegDone
VMOV R0,S13
B _HandleReadRegDone
VMOV R0,S12
B _HandleReadRegDone
VMOV R0,S11
B _HandleReadRegDone
VMOV R0,S10
B _HandleReadRegDone
VMOV R0,S9
B _HandleReadRegDone
VMOV R0,S8
B _HandleReadRegDone
VMOV R0,S7
B _HandleReadRegDone
VMOV R0,S6
B _HandleReadRegDone
VMOV R0,S5
B _HandleReadRegDone
VMOV R0,S4
B _HandleReadRegDone
VMOV R0,S3
B _HandleReadRegDone
VMOV R0,S2
B _HandleReadRegDone
VMOV R0,S1
B _HandleReadRegDone
VMOV R0,S0
B _HandleReadRegDone
#else
B _HandleReadRegUnknown
_HandleReadRegDone_Veneer:
B _HandleReadRegDone
#endif
_HandleReadRegUnknown:
MOVS R0,#+0 // v = 0
B.N _HandleReadRegDone
_HandleReadRegDone:
// Send register content to J-Link and wait until J-Link has read the data
STR R0,[R3, #+_SYSTEM_DCRDR_OFF] // DCRDR = v;
LDR R0,[R3, #+_SYSTEM_DEMCR_OFF] // _SYSTEM_DEMCR |= (1uL << 19); => Set MON_REQ bit, so J-Link knows monitor is ready to receive commands
ORR R0,R0,#0x80000
STR R0,[R3, #+_SYSTEM_DEMCR_OFF] // Indicate data ready
B _WaitProbeReadIndicateMonRdy
// Data section for register addresses
_HandleWriteReg:
/*
_MON_CMD_WRITE_REG
CPU: DEMCR[19] -> 1 => Mon ready
J-Link: Data -> DCRDR, DEMCR[19] -> 0 => Data placed by probe
CPU: DCRDR -> Read, Process command, DEMCR[19] -> 1 => Data read & mon ready
Register indexes
0-15: R0-R15 (13 == R13 reserved => is banked ... Has to be read as PSP / MSP. Decision has to be done by J-Link DLL side!)
16: XPSR
17: MSP
18: PSP
19: CFBP CONTROL/FAULTMASK/BASEPRI/PRIMASK (packed into 4 bytes of word. CONTROL = CFBP[31:24], FAULTMASK = CFBP[16:23], BASEPRI = CFBP[15:8], PRIMASK = CFBP[7:0]
20: FPSCR
21-52: FPS0-FPS31
Register usage when entering this "subroutine":
R0 Cmd
R1 ParamInfo
R2 ---
R3 = &_SYSTEM_DCRDR (allows also access to DEMCR with offset)
R12 ---
Table B1-9 EXC_RETURN definition of exception return behavior, with FP extension
LR Return to Return SP Frame type
---------------------------------------------------------
0xFFFFFFE1 Handler mode. MSP Extended
0xFFFFFFE9 Thread mode MSP Extended
0xFFFFFFED Thread mode PSP Extended
0xFFFFFFF1 Handler mode. MSP Basic
0xFFFFFFF9 Thread mode MSP Basic
0xFFFFFFFD Thread mode PSP Basic
So LR[2] == 1 => Return stack == PSP else MSP
R0-R3, R12, PC, xPSR can be written via application stackpointer
Other regs can be written directly
Read register data from J-Link into R0
*/
LDR R0,[R3, #+_SYSTEM_DEMCR_OFF] // _SYSTEM_DEMCR |= (1uL << 19); => Monitor is ready to receive register data
ORR R0,R0,#0x80000
STR R0,[R3, #+_SYSTEM_DEMCR_OFF]
_HandleWRegWaitUntilDataRecv:
LDR R0,[R3, #+_SYSTEM_DEMCR_OFF]
LSLS R0,R0,#+12
BMI.N _HandleWRegWaitUntilDataRecv // DEMCR[19] == 0 => J-Link has placed new data for us
LDR R0,[R3, #+_SYSTEM_DCRDR_OFF] // Get register data
//
// Determine application SP
//
LSRS R2,LR,#+3 // Shift LR[2] into carry => Carry clear means that CPU was running on MSP
ITE CS
MRSCS R2,PSP
MRSCC R2,MSP
CMP R1,#+4 // if (RegIndex < 4) { (R0-R3)
BCS _HandleWriteRegR4
STR R0,[R2, R1, LSL #+2] // v = [SP + Rx * 4] (R0-R3)
B.N _HandleWriteRegDone
_HandleWriteRegR4:
CMP R1,#+5 // if (RegIndex < 5) { (R4)
BCS _HandleWriteRegR5
MOV R4,R0
B.N _HandleWriteRegDone
_HandleWriteRegR5:
CMP R1,#+6 // if (RegIndex < 6) { (R5)
BCS _HandleWriteRegR6
MOV R5,R0
B.N _HandleWriteRegDone
_HandleWriteRegR6:
CMP R1,#+7 // if (RegIndex < 7) { (R6)
BCS _HandleWriteRegR7
MOV R6,R0
B.N _HandleWriteRegDone
_HandleWriteRegR7:
CMP R1,#+8 // if (RegIndex < 8) { (R7)
BCS _HandleWriteRegR8
MOV R7,R0
B.N _HandleWriteRegDone
_HandleWriteRegR8:
CMP R1,#+9 // if (RegIndex < 9) { (R8)
BCS _HandleWriteRegR9
MOV R8,R0
B.N _HandleWriteRegDone
_HandleWriteRegR9:
CMP R1,#+10 // if (RegIndex < 10) { (R9)
BCS _HandleWriteRegR10
MOV R9,R0
B.N _HandleWriteRegDone
_HandleWriteRegR10:
CMP R1,#+11 // if (RegIndex < 11) { (R10)
BCS _HandleWriteRegR11
MOV R10,R0
B.N _HandleWriteRegDone
_HandleWriteRegR11:
CMP R1,#+12 // if (RegIndex < 12) { (R11)
BCS _HandleWriteRegR12
MOV R11,R0
B.N _HandleWriteRegDone
_HandleWriteRegR12:
CMP R1,#+14 // if (RegIndex < 14) { (R12)
BCS _HandleWriteRegR14
STR R0,[R2, #+_APP_SP_OFF_R12]
B.N _HandleWriteRegDone
_HandleWriteRegR14:
CMP R1,#+15 // if (RegIndex < 15) { (R14 / LR)
BCS _HandleWriteRegR15
STR R0,[R2, #+_APP_SP_OFF_R14_LR]
B.N _HandleWriteRegDone
_HandleWriteRegR15:
CMP R1,#+16 // if (RegIndex < 16) { (R15 / PC)
BCS _HandleWriteRegXPSR
STR R0,[R2, #+_APP_SP_OFF_PC]
B.N _HandleWriteRegDone
_HandleWriteRegXPSR:
CMP R1,#+17 // if (RegIndex < 17) { (xPSR)
BCS _HandleWriteRegMSP
STR R0,[R2, #+_APP_SP_OFF_XPSR]
B.N _HandleWriteRegDone
_HandleWriteRegMSP:
//
// For now, SP cannot be modified because it is needed to jump back from monitor mode
//
CMP R1,#+18 // if (RegIndex < 18) { (MSP)
BCS _HandleWriteRegPSP
B.N _HandleWriteRegDone
_HandleWriteRegPSP: // RegIndex == 18
CMP R1,#+19 // if (RegIndex < 19) {
BCS _HandleWriteRegCFBP
B.N _HandleWriteRegDone
_HandleWriteRegCFBP:
/*
CFBP is a register that can only be read via debug probe and is a merger of the following regs:
CONTROL/FAULTMASK/BASEPRI/PRIMASK (packed into 4 bytes of word. CONTROL = CFBP[31:24], FAULTMASK = CFBP[16:23], BASEPRI = CFBP[15:8], PRIMASK = CFBP[7:0]
To keep J-Link side the same for monitor and halt mode, we also return CFBP in monitor mode
*/
CMP R1,#+20 // if (RegIndex < 20) { (CFBP)
BCS _HandleWriteRegFPU
LSLS R1,R0,#+24
LSRS R1,R1,#+24 // Extract CFBP[7:0] => PRIMASK
MSR PRIMASK,R1
LSLS R1,R0,#+16
LSRS R1,R1,#+24 // Extract CFBP[15:8] => BASEPRI
MSR BASEPRI,R1
LSLS R1,R0,#+8 // Extract CFBP[23:16] => FAULTMASK
LSRS R1,R1,#+24
MSR FAULTMASK,R1
LSRS R1,R0,#+24 // Extract CFBP[31:24] => CONTROL
LSRS R0,R1,#2 // Current CONTROL[1] -> Carry
ITE CS // Update saved CONTROL.SPSEL (CONTROL[1]). CONTROL.SPSEL is saved to LR[2] on exception entry => ARM DDI0403D, B1.5.6 Exception entry behavior
ORRCS LR,LR,#+4
BICCC LR,LR,#+4
BIC R1,R1,#+2 // CONTROL.SPSEL (CONTROL[1]) == 0 inside monitor. Otherwise behavior is UNPREDICTABLE
LSRS R0,R1,#+3 // New CONTROL.FPCA (CONTROL[2]) -> Carry
ITE CS // CONTROL[2] == FPCA => NOT(FPCA) saved to LR[4]. LR[4] == 0 => Extended stack frame, so FPU regs possibly on stack
BICCS LR,LR,#+0x10 // Remember: NOT(FPCA) is stored to LR. == 0 means: Extended stack frame
ORRCC LR,LR,#+0x10
MRS R0,CONTROL
LSRS R0,R0,#+3 // CONTROL[2] -> Carry
ITE CS // Preserve original value of current CONTROL[2]
ORRCS R1,R1,#+0x04
BICCC R1,R1,#+0x04
MSR CONTROL,R1
ISB // Necessary after writing to CONTROL, see ARM DDI0403D, B1.4.4 The special-purpose CONTROL register
B.N _HandleWriteRegDone
_HandleWriteRegFPU:
#if _HAS_FPU_REGS
CMP R1,#+53 // if (RegIndex < 53) { (20 (FPSCR), 21-52 FPS0-FPS31)
BCS _HandleWriteRegDone_Veneer
/*
Read Coprocessor Access Control Register (CPACR) to check if CP10 and CP11 are enabled
If not, access to floating point is not possible
CPACR[21:20] == CP10 enable. 0b01 = Privileged access only. 0b11 = Full access. Other = reserved
CPACR[23:22] == CP11 enable. 0b01 = Privileged access only. 0b11 = Full access. Other = reserved
*/
MOV R12,R0 // Save register data
LDR R0,_AddrCPACR
LDR R0,[R0]
LSLS R0,R0,#+8
LSRS R0,R0,#+28
CMP R0,#+0xF
BEQ _HandleWriteRegFPU_Allowed
CMP R0,#+0x5
BNE _HandleWriteRegDone_Veneer
_HandleWriteRegFPU_Allowed:
CMP R1,#+21 // if (RegIndex < 21) (20 == FPSCR)
BCS _HandleWriteRegFPS0_FPS31
LSRS R0,LR,#+5 // CONTROL[2] == FPCA => NOT(FPCA) saved to LR[4]. LR[4] == 0 => Extended stack frame, so FPU regs possibly on stack
BCS _HandleWriteFPSCRLazyMode // Remember: NOT(FPCA) is stored to LR. == 0 means: Extended stack frame
LDR R0,=_SYSTEM_FPCCR
LDR R0,[R0]
LSLS R0,R0,#+2 // FPCCR[30] -> Carry == 1 indicates if lazy mode is active, so space on stack is reserved but FPU registers are not saved on stack
BCS _HandleWriteFPSCRLazyMode
STR R12,[R2, #+_APP_SP_OFF_FPSCR]
B _HandleWriteRegDone
_HandleWriteFPSCRLazyMode:
VMSR FPSCR,R12
B _HandleWriteRegDone
_HandleWriteRegFPS0_FPS31: // RegIndex == 21-52
LDR R0,=_SYSTEM_FPCCR
LDR R0,[R0]
LSLS R0,R0,#+2 // FPCCR[30] -> Carry == 1 indicates if lazy mode is active, so space on stack is reserved but FPU registers are not saved on stack
BCS _HandleWriteFPS0_FPS31LazyMode
LSRS R0,LR,#+5 // CONTROL[2] == FPCA => NOT(FPCA) saved to LR[4]. LR[4] == 0 => Extended stack frame, so FPU regs possibly on stack
BCS _HandleWriteFPS0_FPS31LazyMode // Remember: NOT(FPCA) is stored to LR. == 0 means: Extended stack frame
SUBS R1,#+21 // Convert absolute reg index into rel. one
LSLS R1,R1,#+2 // RegIndex to position on stack
ADDS R1,#+_APP_SP_OFF_S0
STR R12,[R2, R1]
_HandleWriteRegDone_Veneer:
B _HandleWriteRegDone
_HandleWriteFPS0_FPS31LazyMode:
SUBS R1,#+20 // Convert abs. RegIndex into rel. one
MOVS R0,#+6
MULS R1,R0,R1
LDR R0,=_HandleReadRegUnknown
SUB R0,R0,R1 // _HandleReadRegUnknown - 6 * ((RegIndex - 21) + 1)
ORR R0,R0,#1 // Thumb bit needs to be set in DestAddr
BX R0
//
// Table for reading FPS0-FPS31
//
VMOV S31,R12 // v = FPSx
B _HandleWriteRegDone
VMOV S30,R12
B _HandleWriteRegDone
VMOV S29,R12
B _HandleWriteRegDone
VMOV S28,R12
B _HandleWriteRegDone
VMOV S27,R12
B _HandleWriteRegDone
VMOV S26,R12
B _HandleWriteRegDone
VMOV S25,R12
B _HandleWriteRegDone
VMOV S24,R12
B _HandleWriteRegDone
VMOV S23,R12
B _HandleWriteRegDone
VMOV S22,R12
B _HandleWriteRegDone
VMOV S21,R12
B _HandleWriteRegDone
VMOV S20,R12
B _HandleWriteRegDone
VMOV S19,R12
B _HandleWriteRegDone
VMOV S18,R12
B _HandleWriteRegDone
VMOV S17,R12
B _HandleWriteRegDone
VMOV S16,R12
B _HandleWriteRegDone
VMOV S15,R12
B _HandleWriteRegDone
VMOV S14,R12
B _HandleWriteRegDone
VMOV S13,R12
B _HandleWriteRegDone
VMOV S12,R12
B _HandleWriteRegDone
VMOV S11,R12
B _HandleWriteRegDone
VMOV S10,R12
B _HandleWriteRegDone
VMOV S9,R12
B _HandleWriteRegDone
VMOV S8,R12
B _HandleWriteRegDone
VMOV S7,R12
B _HandleWriteRegDone
VMOV S6,R12
B _HandleWriteRegDone
VMOV S5,R12
B _HandleWriteRegDone
VMOV S4,R12
B _HandleWriteRegDone
VMOV S3,R12
B _HandleWriteRegDone
VMOV S2,R12
B _HandleWriteRegDone
VMOV S1,R12
B _HandleWriteRegDone
VMOV S0,R12
B _HandleWriteRegDone
#else
B _HandleWriteRegUnknown
#endif
_HandleWriteRegUnknown:
B.N _HandleWriteRegDone
_HandleWriteRegDone:
B _IndicateMonReady // Indicate that monitor has read data, processed command and is ready for a new one
.end
/****** End Of File *************************************************/

@ -0,0 +1,280 @@
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 2014 - 2020 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* conditions are met: *
* *
* - Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* *
* - Neither the name of SEGGER Microcontroller GmbH *
* nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific *
* prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. *
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
----------------------------------------------------------------------
File : SEGGER_HardFaultHandler.c
Purpose : Generic SEGGER HardFault handler for Cortex-M
Literature:
[1] Analyzing HardFaults on Cortex-M CPUs (https://www.segger.com/downloads/appnotes/AN00016_AnalyzingHardFaultsOnCortexM.pdf)
Additional information:
This HardFault handler enables user-friendly analysis of hard faults
in debug configurations.
If a release configuration requires a HardFault handler,
a specific HardFault handler should be included instead,
which for example issues a reset or lits an error LED.
-------- END-OF-HEADER ---------------------------------------------
*/
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define SYSHND_CTRL (*(volatile unsigned int*) (0xE000ED24u)) // System Handler Control and State Register
#define NVIC_MFSR (*(volatile unsigned char*) (0xE000ED28u)) // Memory Management Fault Status Register
#define NVIC_BFSR (*(volatile unsigned char*) (0xE000ED29u)) // Bus Fault Status Register
#define NVIC_UFSR (*(volatile unsigned short*)(0xE000ED2Au)) // Usage Fault Status Register
#define NVIC_HFSR (*(volatile unsigned int*) (0xE000ED2Cu)) // Hard Fault Status Register
#define NVIC_DFSR (*(volatile unsigned int*) (0xE000ED30u)) // Debug Fault Status Register
#define NVIC_BFAR (*(volatile unsigned int*) (0xE000ED38u)) // Bus Fault Manage Address Register
#define NVIC_AFSR (*(volatile unsigned int*) (0xE000ED3Cu)) // Auxiliary Fault Status Register
#ifndef DEBUG // Should be overwritten by project settings
#define DEBUG (0) // in debug builds
#endif
/*********************************************************************
*
* Prototypes
*
**********************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
void HardFaultHandler(unsigned int* pStack);
#ifdef __cplusplus
}
#endif
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
#if DEBUG
static volatile unsigned int _Continue; // Set this variable to 1 to run further
static struct {
struct {
volatile unsigned int r0; // Register R0
volatile unsigned int r1; // Register R1
volatile unsigned int r2; // Register R2
volatile unsigned int r3; // Register R3
volatile unsigned int r12; // Register R12
volatile unsigned int lr; // Link register
volatile unsigned int pc; // Program counter
union {
volatile unsigned int byte;
struct {
unsigned int IPSR : 8; // Interrupt Program Status register (IPSR)
unsigned int EPSR : 19; // Execution Program Status register (EPSR)
unsigned int APSR : 5; // Application Program Status register (APSR)
} bits;
} psr; // Program status register.
} SavedRegs;
union {
volatile unsigned int byte;
struct {
unsigned int MEMFAULTACT : 1; // Read as 1 if memory management fault is active
unsigned int BUSFAULTACT : 1; // Read as 1 if bus fault exception is active
unsigned int UnusedBits1 : 1;
unsigned int USGFAULTACT : 1; // Read as 1 if usage fault exception is active
unsigned int UnusedBits2 : 3;
unsigned int SVCALLACT : 1; // Read as 1 if SVC exception is active
unsigned int MONITORACT : 1; // Read as 1 if debug monitor exception is active
unsigned int UnusedBits3 : 1;
unsigned int PENDSVACT : 1; // Read as 1 if PendSV exception is active
unsigned int SYSTICKACT : 1; // Read as 1 if SYSTICK exception is active
unsigned int USGFAULTPENDED : 1; // Usage fault pended; usage fault started but was replaced by a higher-priority exception
unsigned int MEMFAULTPENDED : 1; // Memory management fault pended; memory management fault started but was replaced by a higher-priority exception
unsigned int BUSFAULTPENDED : 1; // Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception
unsigned int SVCALLPENDED : 1; // SVC pended; SVC was started but was replaced by a higher-priority exception
unsigned int MEMFAULTENA : 1; // Memory management fault handler enable
unsigned int BUSFAULTENA : 1; // Bus fault handler enable
unsigned int USGFAULTENA : 1; // Usage fault handler enable
} bits;
} syshndctrl; // System Handler Control and State Register (0xE000ED24)
union {
volatile unsigned char byte;
struct {
unsigned char IACCVIOL : 1; // Instruction access violation
unsigned char DACCVIOL : 1; // Data access violation
unsigned char UnusedBits : 1;
unsigned char MUNSTKERR : 1; // Unstacking error
unsigned char MSTKERR : 1; // Stacking error
unsigned char UnusedBits2 : 2;
unsigned char MMARVALID : 1; // Indicates the MMAR is valid
} bits;
} mfsr; // Memory Management Fault Status Register (0xE000ED28)
union {
volatile unsigned int byte;
struct {
unsigned int IBUSERR : 1; // Instruction access violation
unsigned int PRECISERR : 1; // Precise data access violation
unsigned int IMPREISERR : 1; // Imprecise data access violation
unsigned int UNSTKERR : 1; // Unstacking error
unsigned int STKERR : 1; // Stacking error
unsigned int UnusedBits : 2;
unsigned int BFARVALID : 1; // Indicates BFAR is valid
} bits;
} bfsr; // Bus Fault Status Register (0xE000ED29)
volatile unsigned int bfar; // Bus Fault Manage Address Register (0xE000ED38)
union {
volatile unsigned short byte;
struct {
unsigned short UNDEFINSTR : 1; // Attempts to execute an undefined instruction
unsigned short INVSTATE : 1; // Attempts to switch to an invalid state (e.g., ARM)
unsigned short INVPC : 1; // Attempts to do an exception with a bad value in the EXC_RETURN number
unsigned short NOCP : 1; // Attempts to execute a coprocessor instruction
unsigned short UnusedBits : 4;
unsigned short UNALIGNED : 1; // Indicates that an unaligned access fault has taken place
unsigned short DIVBYZERO : 1; // Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)
} bits;
} ufsr; // Usage Fault Status Register (0xE000ED2A)
union {
volatile unsigned int byte;
struct {
unsigned int UnusedBits : 1;
unsigned int VECTBL : 1; // Indicates hard fault is caused by failed vector fetch
unsigned int UnusedBits2 : 28;
unsigned int FORCED : 1; // Indicates hard fault is taken because of bus fault/memory management fault/usage fault
unsigned int DEBUGEVT : 1; // Indicates hard fault is triggered by debug event
} bits;
} hfsr; // Hard Fault Status Register (0xE000ED2C)
union {
volatile unsigned int byte;
struct {
unsigned int HALTED : 1; // Halt requested in NVIC
unsigned int BKPT : 1; // BKPT instruction executed
unsigned int DWTTRAP : 1; // DWT match occurred
unsigned int VCATCH : 1; // Vector fetch occurred
unsigned int EXTERNAL : 1; // EDBGRQ signal asserted
} bits;
} dfsr; // Debug Fault Status Register (0xE000ED30)
volatile unsigned int afsr; // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
} HardFaultRegs;
#endif
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
/*********************************************************************
*
* HardFaultHandler()
*
* Function description
* C part of the hard fault handler which is called by the assembler
* function HardFault_Handler
*/
void HardFaultHandler(unsigned int* pStack) {
//
// In case we received a hard fault because of a breakpoint instruction, we return.
// This may happen when using semihosting for printf outputs and no debugger is connected,
// i.e. when running a "Debug" configuration in release mode.
//
if (NVIC_HFSR & (1u << 31)) {
NVIC_HFSR |= (1u << 31); // Reset Hard Fault status
*(pStack + 6u) += 2u; // PC is located on stack at SP + 24 bytes. Increment PC by 2 to skip break instruction.
return; // Return to interrupted application
}
#if DEBUG
//
// Read NVIC registers
//
HardFaultRegs.syshndctrl.byte = SYSHND_CTRL; // System Handler Control and State Register
HardFaultRegs.mfsr.byte = NVIC_MFSR; // Memory Fault Status Register
HardFaultRegs.bfsr.byte = NVIC_BFSR; // Bus Fault Status Register
HardFaultRegs.bfar = NVIC_BFAR; // Bus Fault Manage Address Register
HardFaultRegs.ufsr.byte = NVIC_UFSR; // Usage Fault Status Register
HardFaultRegs.hfsr.byte = NVIC_HFSR; // Hard Fault Status Register
HardFaultRegs.dfsr.byte = NVIC_DFSR; // Debug Fault Status Register
HardFaultRegs.afsr = NVIC_AFSR; // Auxiliary Fault Status Register
//
// Halt execution
// If NVIC registers indicate readable memory, change the variable value to != 0 to continue execution.
//
_Continue = 0u;
while (_Continue == 0u) {
}
//
// Read saved registers from the stack.
//
HardFaultRegs.SavedRegs.r0 = pStack[0]; // Register R0
HardFaultRegs.SavedRegs.r1 = pStack[1]; // Register R1
HardFaultRegs.SavedRegs.r2 = pStack[2]; // Register R2
HardFaultRegs.SavedRegs.r3 = pStack[3]; // Register R3
HardFaultRegs.SavedRegs.r12 = pStack[4]; // Register R12
HardFaultRegs.SavedRegs.lr = pStack[5]; // Link register LR
HardFaultRegs.SavedRegs.pc = pStack[6]; // Program counter PC
HardFaultRegs.SavedRegs.psr.byte = pStack[7]; // Program status word PSR
//
// Halt execution
// To step out of the HardFaultHandler, change the variable value to != 0.
//
_Continue = 0u;
while (_Continue == 0u) {
}
#else
//
// If this module is included in a release configuration, simply stay in the HardFault handler
//
(void)pStack;
do {
} while (1);
#endif
}
/*************************** End of file ****************************/

@ -71,6 +71,25 @@ def get_version(file):
return f'{major}.{minor}.{patch}'
def get_version_int(file):
major = 0
minor = 0
patch = 0
file = PROJECT_ROOT / file
with open(file, 'r') as f:
for line in f:
if line.startswith('#define VERSION_MAJOR '):
major = int(line.split('VERSION_MAJOR')[1].strip())
if line.startswith('#define VERSION_MINOR '):
minor = int(line.split('VERSION_MINOR')[1].strip())
if line.startswith('#define VERSION_PATCH '):
patch = int(line.split('VERSION_PATCH')[1].strip())
if major > 99 or minor > 99 or patch > 99:
raise Exception("Version number too large")
return major * 10000 + minor * 100 + patch
def get_git_revision_hash() -> str:
return subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('ascii').strip()

@ -0,0 +1 @@
nrfutil settings generate --family NRF52840 --bootloader-version 0 --bl-settings-version 2 --app-boot-validation VALIDATE_ECDSA_P256_SHA256 --application ./build/ble_firmware/ble_firmware.hex --application-version 0 --sd-boot-validation VALIDATE_ECDSA_P256_SHA256 --softdevice ./embed/sdk/nrf52/components/softdevice/s140/hex/s140_nrf52_7.2.0_softdevice.hex --key-file ./embed/ble_bootloader/priv.pem ./build/ble_bootloader/settings.hex

@ -12,3 +12,4 @@
^\./crypto/sha3
^\./legacy/vendor
^\./core/embed/segger
^\./core/embed/sdk

Loading…
Cancel
Save