Ejemplo n.º 1
0
static unsigned int try_to_flush_duplicates(const char *new_key, unsigned int buf_len)
{
    unsigned int key_size, new_record_size, ret = 0, can_rollback = 0;
    struct record record, previous_record;
    char sector_buff[STORAGE_SIZE];
    struct iter_state is;

    memcpy(sector_buff, STORAGE_ADDRESS, STORAGE_SIZE);
    if(check_for_duplicates(sector_buff)
       || key_exists(sector_buff, new_key, &sector_buff[STORAGE_SIZE], 0, NULL)
       || check_for_empty_records(sector_buff)) {
        fs_erase();
        record_iter_init(&is, sector_buff, STORAGE_SIZE);
        while(record_iter_next(&is, &record, NULL)) {
            if(is_empty(&record))
                continue;
            if(!key_exists((char *)STORAGE_ADDRESS, record.key, STORAGE_ADDRESS + STORAGE_SIZE, 1, NULL)) {
                struct record rec;

                if(!key_exists(sector_buff, record.key, &sector_buff[STORAGE_SIZE], 0, &rec))
                    continue;
                if(strcmp(new_key, record.key) == 0) { // If we are about to write this key we don't keep the old value.
                    previous_record = rec; // This holds the old record in case we need it back (for instance if new record is too long)
                    can_rollback = 1;
                } else
                    fs_write(record.key, rec.value, rec.value_len);
            }
        }
        ret = 1;
    }

    key_size = strlen(new_key) + 1;
    new_record_size = key_size + buf_len + sizeof(new_record_size);
    if(can_rollback && new_record_size > get_free_space()) {
        fs_write(new_key, previous_record.value, previous_record.value_len);
    }

    return ret;
}
Ejemplo n.º 2
0
/** @brief Internal function to initialize DFU BLE transport
 */
fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback)
{
    fs_ret_t ret_val = FS_SUCCESS;
    NRF_LOG_INFO("Erasing: 0x%08x, num: %d\r\n", (uint32_t)p_dest, num_pages);

#ifdef BLE_STACK_SUPPORT_REQD

    if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0)
    {
        // Check if there is a pending error
        if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0)
        {
            NRF_LOG_ERROR("Erase: Failure since last\r\n");
            return FS_ERR_FAILURE_SINCE_LAST;
        }

        m_flags |= FLASH_FLAG_OPER;
        ret_val = fs_erase(&fs_dfu_config, p_dest, num_pages, (void*)callback);

        if (ret_val != FS_SUCCESS)
        {
            NRF_LOG_ERROR("Erase failed: %d\r\n", ret_val);
            m_flags &= ~FLASH_FLAG_OPER;
            return ret_val;
        }

        // Set the flag to indicate ongoing operation
        m_flags |= FLASH_FLAG_OPER;
    }
    else
#endif
    {
#ifndef NRF51
        // Softdevice is not present or activated. Run the NVMC instead
        if (((uint32_t)p_dest & (CODE_PAGE_SIZE-1)) != 0)
        {
            NRF_LOG_ERROR("Invalid address\r\n");
            return FS_ERR_UNALIGNED_ADDR;
        }
#endif

        uint16_t first_page = ((uint32_t)p_dest / CODE_PAGE_SIZE);
        do
        {
            nrf_nvmc_page_erase((uint32_t)p_dest);
            p_dest += CODE_PAGE_SIZE/sizeof(uint32_t);
        }
        while(--num_pages > 0);


        if (callback)
        {
            #if (__LINT__ != 1)
            fs_evt_t evt =
            {
                .id = FS_EVT_ERASE,
                .p_context = (void*)callback,
                .erase =
                {
                    .first_page = first_page,
                    .last_page = ((uint32_t)p_dest / CODE_PAGE_SIZE)
                }
            };
            callback(&evt, FS_SUCCESS);
            #else
            (void)first_page;
            #endif
        }
    }

    return ret_val;
}