mirror of https://github.com/ARMmbed/mbed-os.git
ARM cc has difficulties to link binary with undefined symbols, even if
those symbols are not used. bootloader and log are not needed in our case, just remove files causing troubles. define app_timer symbols with the RTX implementation.pull/2234/head
parent
3368fa8b0d
commit
6d214eb76a
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 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 or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* 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 THE COPYRIGHT HOLDER 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <nrf.h>
|
||||
#include "ble_error_log.h"
|
||||
#include "app_util.h"
|
||||
#include "app_error.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "pstorage.h"
|
||||
|
||||
|
||||
// Made static to avoid the error_log to go on the stack.
|
||||
static ble_error_log_data_t m_ble_error_log; /**< . */
|
||||
//lint -esym(526,__Vectors)
|
||||
extern uint32_t * __Vectors; /**< The initialization vector holds the address to __initial_sp that will be used when fetching the stack. */
|
||||
|
||||
static void fetch_stack(ble_error_log_data_t * error_log)
|
||||
{
|
||||
uint32_t * p_stack;
|
||||
uint32_t * initial_sp;
|
||||
uint32_t length;
|
||||
|
||||
initial_sp = (uint32_t *) __Vectors;
|
||||
p_stack = (uint32_t *) GET_SP();
|
||||
|
||||
length = ((uint32_t) initial_sp) - ((uint32_t) p_stack);
|
||||
memcpy(error_log->stack_info,
|
||||
p_stack,
|
||||
(length > STACK_DUMP_LENGTH) ? STACK_DUMP_LENGTH : length);
|
||||
}
|
||||
|
||||
uint32_t ble_error_log_write(uint32_t err_code, const uint8_t * p_message, uint16_t line_number)
|
||||
{
|
||||
m_ble_error_log.failure = true;
|
||||
m_ble_error_log.err_code = err_code;
|
||||
m_ble_error_log.line_number = line_number;
|
||||
|
||||
strncpy((char *)m_ble_error_log.message, (const char *)p_message, ERROR_MESSAGE_LENGTH - 1);
|
||||
m_ble_error_log.message[ERROR_MESSAGE_LENGTH - 1] = '\0';
|
||||
|
||||
fetch_stack(&m_ble_error_log);
|
||||
|
||||
// Write to flash removed, to be redone.
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
|
@ -1,409 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 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 or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* 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 THE COPYRIGHT HOLDER 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bootloader.h"
|
||||
#include "bootloader_types.h"
|
||||
#include "bootloader_util.h"
|
||||
#include "bootloader_settings.h"
|
||||
#include "dfu.h"
|
||||
#include "dfu_transport.h"
|
||||
#include "nrf.h"
|
||||
#include "app_error.h"
|
||||
#include "nrf_sdm.h"
|
||||
#include "nrf_mbr.h"
|
||||
#include "nordic_common.h"
|
||||
#include "crc16.h"
|
||||
#include "pstorage.h"
|
||||
#include "app_scheduler.h"
|
||||
#include "nrf_delay.h"
|
||||
#include "sdk_common.h"
|
||||
|
||||
#define IRQ_ENABLED 0x01 /**< Field identifying if an interrupt is enabled. */
|
||||
#define MAX_NUMBER_INTERRUPTS 32 /**< Maximum number of interrupts available. */
|
||||
|
||||
/**@brief Enumeration for specifying current bootloader status.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
BOOTLOADER_UPDATING, /**< Bootloader status for indicating that an update is in progress. */
|
||||
BOOTLOADER_SETTINGS_SAVING, /**< Bootloader status for indicating that saving of bootloader settings is in progress. */
|
||||
BOOTLOADER_COMPLETE, /**< Bootloader status for indicating that all operations for the update procedure has completed and it is safe to reset the system. */
|
||||
BOOTLOADER_TIMEOUT, /**< Bootloader status field for indicating that a timeout has occured and current update process should be aborted. */
|
||||
BOOTLOADER_RESET, /**< Bootloader status field for indicating that a reset has been requested and current update process should be aborted. */
|
||||
} bootloader_status_t;
|
||||
|
||||
static pstorage_handle_t m_bootsettings_handle; /**< Pstorage handle to use for registration and identifying the bootloader module on subsequent calls to the pstorage module for load and store of bootloader setting in flash. */
|
||||
static bootloader_status_t m_update_status; /**< Current update status for the bootloader module to ensure correct behaviour when updating settings and when update completes. */
|
||||
|
||||
/**@brief Function for handling callbacks from pstorage module.
|
||||
*
|
||||
* @details Handles pstorage results for clear and storage operation. For detailed description of
|
||||
* the parameters provided with the callback, please refer to \ref pstorage_ntf_cb_t.
|
||||
*/
|
||||
static void pstorage_callback_handler(pstorage_handle_t * p_handle,
|
||||
uint8_t op_code,
|
||||
uint32_t result,
|
||||
uint8_t * p_data,
|
||||
uint32_t data_len)
|
||||
{
|
||||
// If we are in BOOTLOADER_SETTINGS_SAVING state and we receive an PSTORAGE_STORE_OP_CODE
|
||||
// response then settings has been saved and update has completed.
|
||||
if ((m_update_status == BOOTLOADER_SETTINGS_SAVING) && (op_code == PSTORAGE_STORE_OP_CODE))
|
||||
{
|
||||
m_update_status = BOOTLOADER_COMPLETE;
|
||||
}
|
||||
|
||||
APP_ERROR_CHECK(result);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for waiting for events.
|
||||
*
|
||||
* @details This function will place the chip in low power mode while waiting for events from
|
||||
* the SoftDevice or other peripherals. When interrupted by an event, it will call the
|
||||
* @ref app_sched_execute function to process the received event. This function will return
|
||||
* when the final state of the firmware update is reached OR when a tear down is in
|
||||
* progress.
|
||||
*/
|
||||
static void wait_for_events(void)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
// Wait in low power state for any events.
|
||||
uint32_t err_code = sd_app_evt_wait();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Event received. Process it from the scheduler.
|
||||
app_sched_execute();
|
||||
|
||||
if ((m_update_status == BOOTLOADER_COMPLETE) ||
|
||||
(m_update_status == BOOTLOADER_TIMEOUT) ||
|
||||
(m_update_status == BOOTLOADER_RESET))
|
||||
{
|
||||
// When update has completed or a timeout/reset occured we will return.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool bootloader_app_is_valid(uint32_t app_addr)
|
||||
{
|
||||
const bootloader_settings_t * p_bootloader_settings;
|
||||
|
||||
// There exists an application in CODE region 1.
|
||||
if (*((uint32_t *)app_addr) == EMPTY_FLASH_MASK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
||||
bootloader_util_settings_get(&p_bootloader_settings);
|
||||
|
||||
// The application in CODE region 1 is flagged as valid during update.
|
||||
if (p_bootloader_settings->bank_0 == BANK_VALID_APP)
|
||||
{
|
||||
uint16_t image_crc = 0;
|
||||
|
||||
// A stored crc value of 0 indicates that CRC checking is not used.
|
||||
if (p_bootloader_settings->bank_0_crc != 0)
|
||||
{
|
||||
image_crc = crc16_compute((uint8_t *)DFU_BANK_0_REGION_START,
|
||||
p_bootloader_settings->bank_0_size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
success = (image_crc == p_bootloader_settings->bank_0_crc);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
static void bootloader_settings_save(bootloader_settings_t * p_settings)
|
||||
{
|
||||
uint32_t err_code = pstorage_clear(&m_bootsettings_handle, sizeof(bootloader_settings_t));
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
err_code = pstorage_store(&m_bootsettings_handle,
|
||||
(uint8_t *)p_settings,
|
||||
sizeof(bootloader_settings_t),
|
||||
0);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
|
||||
|
||||
void bootloader_dfu_update_process(dfu_update_status_t update_status)
|
||||
{
|
||||
static bootloader_settings_t settings;
|
||||
const bootloader_settings_t * p_bootloader_settings;
|
||||
|
||||
bootloader_util_settings_get(&p_bootloader_settings);
|
||||
|
||||
if (update_status.status_code == DFU_UPDATE_APP_COMPLETE)
|
||||
{
|
||||
settings.bank_0_crc = update_status.app_crc;
|
||||
settings.bank_0_size = update_status.app_size;
|
||||
settings.bank_0 = BANK_VALID_APP;
|
||||
settings.bank_1 = BANK_INVALID_APP;
|
||||
|
||||
m_update_status = BOOTLOADER_SETTINGS_SAVING;
|
||||
bootloader_settings_save(&settings);
|
||||
}
|
||||
else if (update_status.status_code == DFU_UPDATE_SD_COMPLETE)
|
||||
{
|
||||
settings.bank_0_crc = update_status.app_crc;
|
||||
settings.bank_0_size = update_status.sd_size +
|
||||
update_status.bl_size +
|
||||
update_status.app_size;
|
||||
settings.bank_0 = BANK_VALID_SD;
|
||||
settings.bank_1 = BANK_INVALID_APP;
|
||||
settings.sd_image_size = update_status.sd_size;
|
||||
settings.bl_image_size = update_status.bl_size;
|
||||
settings.app_image_size = update_status.app_size;
|
||||
settings.sd_image_start = update_status.sd_image_start;
|
||||
|
||||
m_update_status = BOOTLOADER_SETTINGS_SAVING;
|
||||
bootloader_settings_save(&settings);
|
||||
}
|
||||
else if (update_status.status_code == DFU_UPDATE_BOOT_COMPLETE)
|
||||
{
|
||||
settings.bank_0 = p_bootloader_settings->bank_0;
|
||||
settings.bank_0_crc = p_bootloader_settings->bank_0_crc;
|
||||
settings.bank_0_size = p_bootloader_settings->bank_0_size;
|
||||
settings.bank_1 = BANK_VALID_BOOT;
|
||||
settings.sd_image_size = update_status.sd_size;
|
||||
settings.bl_image_size = update_status.bl_size;
|
||||
settings.app_image_size = update_status.app_size;
|
||||
|
||||
m_update_status = BOOTLOADER_SETTINGS_SAVING;
|
||||
bootloader_settings_save(&settings);
|
||||
}
|
||||
else if (update_status.status_code == DFU_UPDATE_SD_SWAPPED)
|
||||
{
|
||||
if (p_bootloader_settings->bank_0 == BANK_VALID_SD)
|
||||
{
|
||||
settings.bank_0_crc = 0;
|
||||
settings.bank_0_size = 0;
|
||||
settings.bank_0 = BANK_INVALID_APP;
|
||||
}
|
||||
// This handles cases where SoftDevice was not updated, hence bank0 keeps its settings.
|
||||
else
|
||||
{
|
||||
settings.bank_0 = p_bootloader_settings->bank_0;
|
||||
settings.bank_0_crc = p_bootloader_settings->bank_0_crc;
|
||||
settings.bank_0_size = p_bootloader_settings->bank_0_size;
|
||||
}
|
||||
|
||||
settings.bank_1 = BANK_INVALID_APP;
|
||||
settings.sd_image_size = 0;
|
||||
settings.bl_image_size = 0;
|
||||
settings.app_image_size = 0;
|
||||
|
||||
m_update_status = BOOTLOADER_SETTINGS_SAVING;
|
||||
bootloader_settings_save(&settings);
|
||||
}
|
||||
else if (update_status.status_code == DFU_TIMEOUT)
|
||||
{
|
||||
// Timeout has occurred. Close the connection with the DFU Controller.
|
||||
uint32_t err_code = dfu_transport_close();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
m_update_status = BOOTLOADER_TIMEOUT;
|
||||
}
|
||||
else if (update_status.status_code == DFU_BANK_0_ERASED)
|
||||
{
|
||||
settings.bank_0_crc = 0;
|
||||
settings.bank_0_size = 0;
|
||||
settings.bank_0 = BANK_INVALID_APP;
|
||||
settings.bank_1 = p_bootloader_settings->bank_1;
|
||||
|
||||
bootloader_settings_save(&settings);
|
||||
}
|
||||
else if (update_status.status_code == DFU_RESET)
|
||||
{
|
||||
m_update_status = BOOTLOADER_RESET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No implementation needed.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t bootloader_init(void)
|
||||
{
|
||||
uint32_t err_code;
|
||||
pstorage_module_param_t storage_params = {.cb = pstorage_callback_handler};
|
||||
|
||||
err_code = pstorage_init();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
m_bootsettings_handle.block_id = BOOTLOADER_SETTINGS_ADDRESS;
|
||||
err_code = pstorage_register(&storage_params, &m_bootsettings_handle);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t bootloader_dfu_start(void)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
// Clear swap if banked update is used.
|
||||
err_code = dfu_init();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
err_code = dfu_transport_update_start();
|
||||
|
||||
wait_for_events();
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for disabling all interrupts before jumping from bootloader to application.
|
||||
*/
|
||||
static void interrupts_disable(void)
|
||||
{
|
||||
uint32_t interrupt_setting_mask;
|
||||
uint32_t irq = 0; // We start from first interrupt, i.e. interrupt 0.
|
||||
|
||||
// Fetch the current interrupt settings.
|
||||
interrupt_setting_mask = NVIC->ISER[0];
|
||||
|
||||
for (; irq < MAX_NUMBER_INTERRUPTS; irq++)
|
||||
{
|
||||
if (interrupt_setting_mask & (IRQ_ENABLED << irq))
|
||||
{
|
||||
// The interrupt was enabled, and hence disable it.
|
||||
NVIC_DisableIRQ((IRQn_Type)irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bootloader_app_start(uint32_t app_addr)
|
||||
{
|
||||
// If the applications CRC has been checked and passed, the magic number will be written and we
|
||||
// can start the application safely.
|
||||
uint32_t err_code = sd_softdevice_disable();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
interrupts_disable();
|
||||
|
||||
err_code = sd_softdevice_vector_table_base_set(CODE_REGION_1_START);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
bootloader_util_app_start(CODE_REGION_1_START);
|
||||
}
|
||||
|
||||
|
||||
bool bootloader_dfu_sd_in_progress(void)
|
||||
{
|
||||
const bootloader_settings_t * p_bootloader_settings;
|
||||
|
||||
bootloader_util_settings_get(&p_bootloader_settings);
|
||||
|
||||
if (p_bootloader_settings->bank_0 == BANK_VALID_SD ||
|
||||
p_bootloader_settings->bank_1 == BANK_VALID_BOOT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint32_t bootloader_dfu_sd_update_continue(void)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
if ((dfu_sd_image_validate() == NRF_SUCCESS) &&
|
||||
(dfu_bl_image_validate() == NRF_SUCCESS))
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
// Ensure that flash operations are not executed within the first 100 ms seconds to allow
|
||||
// a debugger to be attached.
|
||||
nrf_delay_ms(100);
|
||||
|
||||
err_code = dfu_sd_image_swap();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
err_code = dfu_sd_image_validate();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
err_code = dfu_bl_image_swap();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t bootloader_dfu_sd_update_finalize(void)
|
||||
{
|
||||
dfu_update_status_t update_status = {DFU_UPDATE_SD_SWAPPED, };
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
|
||||
wait_for_events();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void bootloader_settings_get(bootloader_settings_t * const p_settings)
|
||||
{
|
||||
const bootloader_settings_t * p_bootloader_settings;
|
||||
|
||||
bootloader_util_settings_get(&p_bootloader_settings);
|
||||
|
||||
p_settings->bank_0 = p_bootloader_settings->bank_0;
|
||||
p_settings->bank_0_crc = p_bootloader_settings->bank_0_crc;
|
||||
p_settings->bank_0_size = p_bootloader_settings->bank_0_size;
|
||||
p_settings->bank_1 = p_bootloader_settings->bank_1;
|
||||
p_settings->sd_image_size = p_bootloader_settings->sd_image_size;
|
||||
p_settings->bl_image_size = p_bootloader_settings->bl_image_size;
|
||||
p_settings->app_image_size = p_bootloader_settings->app_image_size;
|
||||
p_settings->sd_image_start = p_bootloader_settings->sd_image_start;
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 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 or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* 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 THE COPYRIGHT HOLDER 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.
|
||||
*
|
||||
*/
|
||||
#ifdef NORDIC_BOOTLOADER_SETTINGS // avoid from unwanted commpilation
|
||||
|
||||
#include "bootloader_settings.h"
|
||||
#include <stdint.h>
|
||||
#include <dfu_types.h>
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
|
||||
uint8_t m_boot_settings[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) __attribute__((used)); /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate any code or variables at his location. */
|
||||
uint32_t m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOT_START_ADDRESS))) = BOOTLOADER_REGION_START; /**< This variable makes the linker script write the bootloader start address to the UICR register. This value will be written in the HEX file and thus written to UICR when the bootloader is flashed into the chip. */
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
|
||||
uint8_t m_boot_settings[CODE_PAGE_SIZE] __attribute__ ((section(".bootloaderSettings"))); /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate any code or variables at his location. */
|
||||
volatile uint32_t m_uicr_bootloader_start_address __attribute__ ((section(".uicrBootStartAddress"))) = BOOTLOADER_REGION_START; /**< This variable ensures that the linker script will write the bootloader start address to the UICR register. This value will be written in the HEX file and thus written to UICR when the bootloader is flashed into the chip. */
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
|
||||
__no_init uint8_t m_boot_settings[CODE_PAGE_SIZE] @ BOOTLOADER_SETTINGS_ADDRESS; /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate any code or variables at his location. */
|
||||
__root const uint32_t m_uicr_bootloader_start_address @ NRF_UICR_BOOT_START_ADDRESS = BOOTLOADER_REGION_START; /**< This variable ensures that the linker script will write the bootloader start address to the UICR register. This value will be written in the HEX file and thus written to UICR when the bootloader is flashed into the chip. */
|
||||
|
||||
#endif
|
||||
|
||||
#if defined ( NRF52 )
|
||||
#if defined ( __CC_ARM )
|
||||
|
||||
uint8_t m_mbr_params_page[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS))) __attribute__((used)); /**< This variable reserves a codepage for mbr parameters, to ensure the compiler doesn't locate any code or variables at his location. */
|
||||
uint32_t m_uicr_mbr_params_page_address __attribute__((at(NRF_UICR_MBR_PARAMS_PAGE_ADDRESS)))
|
||||
= BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS; /**< This variable makes the linker script write the mbr parameters page address to the UICR register. This value will be written in the HEX file and thus written to the UICR when the bootloader is flashed into the chip */
|
||||
|
||||
#elif defined (__GNUC__ )
|
||||
|
||||
uint8_t m_mbr_params_page[CODE_PAGE_SIZE] __attribute__ ((section(".mbrParamsPage"))); /**< This variable reserves a codepage for mbr parameters, to ensure the compiler doesn't locate any code or variables at his location. */
|
||||
volatile uint32_t m_uicr_mbr_params_page_address __attribute__ ((section(".uicrMbrParamsPageAddress")))
|
||||
= BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS; /**< This variable makes the linker script write the mbr parameters page address to the UICR register. This value will be written in the HEX file and thus written to the UICR when the bootloader is flashed into the chip */
|
||||
|
||||
#elif defined (__ICCARM__ )
|
||||
|
||||
__no_init uint8_t m_mbr_params_page[CODE_PAGE_SIZE] @ BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS; /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate any code or variables at his location. */
|
||||
__root const uint32_t m_uicr_mbr_params_page_address @ NRF_UICR_MBR_PARAMS_PAGE_ADDRESS = BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS; /**< This variable ensures that the linker script will write the bootloader start address to the UICR register. This value will be written in the HEX file and thus written to UICR when the bootloader is flashed into the chip. */
|
||||
|
||||
#endif
|
||||
#endif //defined ( NRF52 )
|
||||
|
||||
|
||||
void bootloader_util_settings_get(const bootloader_settings_t ** pp_bootloader_settings)
|
||||
{
|
||||
// Read only pointer to bootloader settings in flash.
|
||||
bootloader_settings_t const * const p_bootloader_settings =
|
||||
(bootloader_settings_t *)&m_boot_settings[0];
|
||||
|
||||
*pp_bootloader_settings = p_bootloader_settings;
|
||||
}
|
||||
|
||||
#endif // NORDIC_BOOTLOADER
|
|
@ -0,0 +1,239 @@
|
|||
#include "app_timer.h"
|
||||
#include <stdlib.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_soc.h"
|
||||
#include "app_error.h"
|
||||
#include "app_util.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "app_util_platform.h"
|
||||
|
||||
#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOW /**< Priority of the RTC1 interrupt. */
|
||||
|
||||
#define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */
|
||||
|
||||
/**@brief This structure keeps information about osTimer.*/
|
||||
typedef struct
|
||||
{
|
||||
osTimerDef_t timerDef;
|
||||
uint32_t buffer[5];
|
||||
osTimerId id;
|
||||
}app_timer_info_t;
|
||||
|
||||
/**@brief Store an array of timers with configuration. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t max_timers; /**< The maximum number of timers*/
|
||||
uint32_t prescaler;
|
||||
app_timer_info_t * app_timers; /**< Pointer to table of timers*/
|
||||
}app_timer_control_t;
|
||||
app_timer_control_t app_timer_control;
|
||||
|
||||
/**@brief This structure is defined by RTX. It keeps information about created osTimers. It is used in app_timer_start(). */
|
||||
typedef struct os_timer_cb_
|
||||
{
|
||||
struct os_timer_cb_ * next;
|
||||
uint8_t state;
|
||||
uint8_t type;
|
||||
uint16_t reserved;
|
||||
uint16_t tcnt;
|
||||
uint16_t icnt;
|
||||
void * arg;
|
||||
const osTimerDef_t * timer;
|
||||
} os_timer_cb;
|
||||
|
||||
/**@brief This functions are defined by RTX.*/
|
||||
//lint --save -e10 -e19 -e526
|
||||
extern osStatus svcTimerStop(osTimerId timer_id); /**< Used in app_timer_stop(). */
|
||||
extern osStatus svcTimerStart(osTimerId timer_id, uint32_t millisec); /**< Used in app_timer_start(). */
|
||||
// lint --restore
|
||||
static void * rt_id2obj(void *id) /**< Used in app_timer_start(). This function gives information if osTimerID is valid */
|
||||
{
|
||||
|
||||
if ((uint32_t)id & 3)
|
||||
return NULL;
|
||||
|
||||
#ifdef OS_SECTIONS_LINK_INFO
|
||||
|
||||
if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0))
|
||||
{
|
||||
if (id < (void *)os_section_id$$Base)
|
||||
return NULL;
|
||||
|
||||
if (id >= (void *)os_section_id$$Limit)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_timer_init(uint32_t prescaler,
|
||||
uint8_t op_queues_size,
|
||||
void * p_buffer,
|
||||
app_timer_evt_schedule_func_t evt_schedule_func)
|
||||
{
|
||||
if (p_buffer == NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
app_timer_control.prescaler = prescaler;
|
||||
app_timer_control.app_timers = p_buffer;
|
||||
NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_timer_create(app_timer_id_t const * p_timer_id,
|
||||
app_timer_mode_t mode,
|
||||
app_timer_timeout_handler_t timeout_handler)
|
||||
{
|
||||
|
||||
if ((timeout_handler == NULL) || (p_timer_id == NULL))
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
app_timer_info_t * p_timer_info = (app_timer_info_t *)*p_timer_id;
|
||||
p_timer_info->timerDef.timer = p_timer_info->buffer;
|
||||
p_timer_info->timerDef.ptimer = (os_ptimer)timeout_handler;
|
||||
|
||||
p_timer_info->id = osTimerCreate(&(p_timer_info->timerDef), (os_timer_type)mode, NULL);
|
||||
|
||||
if (p_timer_info->id)
|
||||
return NRF_SUCCESS;
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM; // This error is unspecified by rtx
|
||||
}
|
||||
}
|
||||
|
||||
#define osTimerRunning 2
|
||||
uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)
|
||||
{
|
||||
if ((timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS))
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
uint32_t timeout_ms =
|
||||
((uint32_t)ROUNDED_DIV(timeout_ticks * 1000 * (app_timer_control.prescaler + 1),
|
||||
(uint32_t)APP_TIMER_CLOCK_FREQ));
|
||||
|
||||
app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id;
|
||||
if (rt_id2obj((void *)p_timer_info->id) == NULL)
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
|
||||
// Pass p_context to timer_timeout_handler
|
||||
((os_timer_cb *)(p_timer_info->id))->arg = p_context;
|
||||
|
||||
if (((os_timer_cb *)(p_timer_info->id))->state == osTimerRunning)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
// osTimerStart() returns osErrorISR if it is called in interrupt routine.
|
||||
switch (osTimerStart((osTimerId)p_timer_info->id, timeout_ms) )
|
||||
{
|
||||
case osOK:
|
||||
return NRF_SUCCESS;
|
||||
|
||||
case osErrorISR:
|
||||
break;
|
||||
|
||||
case osErrorParameter:
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
|
||||
default:
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Start timer without svcCall
|
||||
switch (svcTimerStart((osTimerId)p_timer_info->id, timeout_ms))
|
||||
{
|
||||
case osOK:
|
||||
return NRF_SUCCESS;
|
||||
|
||||
case osErrorISR:
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
|
||||
case osErrorParameter:
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
|
||||
default:
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t app_timer_stop(app_timer_id_t timer_id)
|
||||
{
|
||||
app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id;
|
||||
switch (osTimerStop((osTimerId)p_timer_info->id) )
|
||||
{
|
||||
case osOK:
|
||||
return NRF_SUCCESS;
|
||||
|
||||
case osErrorISR:
|
||||
break;
|
||||
|
||||
case osErrorParameter:
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
|
||||
case osErrorResource:
|
||||
return NRF_SUCCESS;
|
||||
|
||||
default:
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Stop timer without svcCall
|
||||
switch (svcTimerStop((osTimerId)p_timer_info->id))
|
||||
{
|
||||
case osOK:
|
||||
return NRF_SUCCESS;
|
||||
|
||||
case osErrorISR:
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
|
||||
case osErrorParameter:
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
|
||||
case osErrorResource:
|
||||
return NRF_SUCCESS;
|
||||
|
||||
default:
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_timer_stop_all(void)
|
||||
{
|
||||
for (int i = 0; i < app_timer_control.max_timers; i++)
|
||||
{
|
||||
if (app_timer_control.app_timers[i].id)
|
||||
{
|
||||
(void)app_timer_stop((app_timer_id_t)app_timer_control.app_timers[i].id);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern uint32_t os_tick_val(void);
|
||||
uint32_t app_timer_cnt_get(uint32_t * p_ticks)
|
||||
{
|
||||
*p_ticks = os_tick_val();
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
|
||||
uint32_t ticks_from,
|
||||
uint32_t * p_ticks_diff)
|
||||
{
|
||||
*p_ticks_diff = ((ticks_to - ticks_from) & MAX_RTC_COUNTER_VAL);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue