예제 #1
0
uint32_t dfu_sd_image_swap(void)
{
    bootloader_settings_t boot_settings;

    bootloader_settings_get(&boot_settings);

    if (boot_settings.sd_image_size == 0)
    {
        return NRF_SUCCESS;
    }
    
    if ((SOFTDEVICE_REGION_START + boot_settings.sd_image_size) > boot_settings.sd_image_start)
    {
        uint32_t err_code;
        uint32_t sd_start        = SOFTDEVICE_REGION_START;
        uint32_t block_size      = (boot_settings.sd_image_start - sd_start) / 2;
        uint32_t image_end       = boot_settings.sd_image_start + boot_settings.sd_image_size;

        uint32_t img_block_start = boot_settings.sd_image_start + 2 * block_size;
        uint32_t sd_block_start  = sd_start + 2 * block_size;
        
        if (SD_SIZE_GET(MBR_SIZE) < boot_settings.sd_image_size)
        {
            // This will clear a page thus ensuring the old image is invalidated before swapping.
            err_code = dfu_copy_sd((uint32_t *)(sd_start + block_size), 
                                   (uint32_t *)(sd_start + block_size), 
                                   sizeof(uint32_t));
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }

            err_code = dfu_copy_sd((uint32_t *)sd_start, (uint32_t *)sd_start, sizeof(uint32_t));
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }
        }
        
        return dfu_sd_img_block_swap((uint32_t *)img_block_start, 
                                     (uint32_t *)sd_block_start, 
                                     image_end - img_block_start, 
                                     block_size);
    }
    else
    {
        if (boot_settings.sd_image_size != 0)
        {
            return dfu_copy_sd((uint32_t *)boot_settings.sd_image_start,
                               (uint32_t *)SOFTDEVICE_REGION_START, 
                               boot_settings.sd_image_size);
        }
    }

    return NRF_SUCCESS;
}
예제 #2
0
/**@brief Function for validating that new application has been correctly installed. */
uint32_t dfu_app_image_validate(void)
{
    bootloader_settings_t bootloader_settings;
    uint32_t              err_code = NRF_SUCCESS;

    bootloader_settings_load(&bootloader_settings);

    if ((bootloader_settings.bank_1 & BANK_VALID_MASK) & (BANK_VALID_APP))
    {
        err_code = compare((uint32_t *)(SD_SIZE_GET(MBR_SIZE)),
                           (uint32_t *)get_address(APPLICATION_PART),
                           bootloader_settings.app_image_size);
    }

    return err_code;
}
예제 #3
0
/**@brief Function for swapping existing application with newly received. */
uint32_t dfu_app_image_swap(void)
{
    bootloader_settings_t bootloader_settings;

    bootloader_settings_load(&bootloader_settings);

    if ((bootloader_settings.bank_1 & BANK_VALID_MASK) & (BANK_VALID_APP))
    {
        bootloader_settings.bank_1 &= ~(BANK_VALID_APP);
        bootloader_settings.bank_0 = BANK_VALID_APP;
        bootloader_settings_save(&bootloader_settings);

        return copy((uint32_t *)get_address(APPLICATION_PART),
                    (uint32_t *)(SD_SIZE_GET(MBR_SIZE)),
                    bootloader_settings.app_image_size);
    }

    return NRF_SUCCESS;
}
예제 #4
0
uint32_t dfu_sd_image_validate(void)
{
    bootloader_settings_t bootloader_settings;
    sd_mbr_command_t      sd_mbr_cmd;

    bootloader_settings_get(&bootloader_settings);

    if (bootloader_settings.sd_image_size == 0)
    {
        return NRF_SUCCESS;
    }
    
    if ((SOFTDEVICE_REGION_START + bootloader_settings.sd_image_size) > bootloader_settings.sd_image_start)
    {
        uint32_t sd_start        = SOFTDEVICE_REGION_START;
        uint32_t block_size      = (bootloader_settings.sd_image_start - sd_start) / 2;
        uint32_t image_end       = bootloader_settings.sd_image_start + 
                                   bootloader_settings.sd_image_size;

        uint32_t img_block_start = bootloader_settings.sd_image_start + 2 * block_size;
        uint32_t sd_block_start  = sd_start + 2 * block_size;

        if (SD_SIZE_GET(MBR_SIZE) < bootloader_settings.sd_image_size)
        {
            return NRF_ERROR_NULL;
        }

        return dfu_sd_img_block_swap((uint32_t *)img_block_start, 
                                     (uint32_t *)sd_block_start, 
                                     image_end - img_block_start, 
                                     block_size);
    }
    
    sd_mbr_cmd.command             = SD_MBR_COMMAND_COMPARE;
    sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)SOFTDEVICE_REGION_START;
    sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)bootloader_settings.sd_image_start;
    sd_mbr_cmd.params.compare.len  = bootloader_settings.sd_image_size / sizeof(uint32_t);

    return sd_mbr_command(&sd_mbr_cmd);
}