Ejemplo n.º 1
0
// Update the tranfer state with new information
static void transfer_stream_data(uint32_t sector, const uint8_t *data, uint32_t size)
{
    error_t status;
    vfs_mngr_printf("vfs_manager transfer_stream_data(sector=%i, size=%i)\r\n", sector, size);
    vfs_mngr_printf("    size processed=0x%x, data=%x,%x,%x,%x,...\r\n",
                    file_transfer_state.size_processed, data[0], data[1], data[2], data[3]);

    if (file_transfer_state.stream_finished) {
        util_assert(0);
        return;
    }

    util_assert(size % VFS_SECTOR_SIZE == 0);
    util_assert(file_transfer_state.stream_open);
    status = stream_write((uint8_t *)data, size);
    vfs_mngr_printf("    stream_write ret=%i\r\n", status);

    if (ERROR_SUCCESS_DONE == status) {
        // Override status so ERROR_SUCCESS_DONE
        // does not get passed into transfer_update_state
        status = stream_close();
        vfs_mngr_printf("    stream_close ret=%i\r\n", status);
        file_transfer_state.stream_open = false;
        file_transfer_state.stream_finished = true;
        file_transfer_state.stream_optional_finish = true;
    } else if (ERROR_SUCCESS_DONE_OR_CONTINUE == status) {
        status = ERROR_SUCCESS;
        file_transfer_state.stream_optional_finish = true;
    } else {
        file_transfer_state.stream_optional_finish = false;
    }

    file_transfer_state.size_processed += size;
    transfer_update_state(status);
}
Ejemplo n.º 2
0
error_t stream_write(const uint8_t *data, uint32_t size)
{
    error_t status;

    // Stream must be open already
    if (state != STREAM_STATE_OPEN) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Check thread after checking state since the stream thread is
    // set only if stream_open has been called
    stream_thread_assert();
    // Write to stream
    status = current_stream->write(&shared_state, data, size);

    if (ERROR_SUCCESS_DONE == status) {
        state = STREAM_STATE_END;
    } else if ((ERROR_SUCCESS_DONE_OR_CONTINUE == status) || (ERROR_SUCCESS == status)) {
        // Stream should remain in the open state
        util_assert(STREAM_STATE_OPEN == state);
    } else {
        state = STREAM_STATE_ERROR;
    }

    return status;
}
Ejemplo n.º 3
0
error_t stream_open(stream_type_t stream_type)
{
    error_t status;

    // Stream must not be open already
    if (state != STREAM_STATE_CLOSED) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Stream must be of a supported type
    if (stream_type >= STREAM_TYPE_COUNT) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    stream_thread_set();
    // Initialize all variables
    memset(&shared_state, 0, sizeof(shared_state));
    state = STREAM_STATE_OPEN;
    current_stream = &stream[stream_type];
    // Initialize the specified stream
    status = current_stream->open(&shared_state);

    if (ERROR_SUCCESS != status) {
        state = STREAM_STATE_ERROR;
    }

    return status;
}
Ejemplo n.º 4
0
// Update the tranfer state with new information
static void transfer_stream_open(stream_type_t stream, uint32_t start_sector)
{
    error_t status;
    util_assert(!file_transfer_state.stream_open);
    util_assert(start_sector != VFS_INVALID_SECTOR);
    vfs_mngr_printf("vfs_manager transfer_update_stream_open(stream=%i, start_sector=%i)\r\n",
                    stream, start_sector);

    // Initialize the starting sector if it has not been set
    if (VFS_INVALID_SECTOR == file_transfer_state.start_sector) {
        file_transfer_state.start_sector = start_sector;

        if (start_sector != VFS_INVALID_SECTOR) {
            vfs_mngr_printf("    start_sector=%i\r\n", start_sector);
        }
    }

    // Initialize the stream if it has not been set
    if (STREAM_TYPE_NONE == file_transfer_state.stream) {
        file_transfer_state.stream = stream;

        if (stream != STREAM_TYPE_NONE) {
            vfs_mngr_printf("    stream=%i\r\n", stream);
        }
    }

    // Check - Starting sector must be the same
    if (start_sector != file_transfer_state.start_sector) {
        vfs_mngr_printf("    error: starting sector changed from %i to %i\r\n", file_transfer_state.start_sector, start_sector);
        transfer_update_state(ERROR_ERROR_DURING_TRANSFER);
        return;
    }

    // Check - stream must be the same
    if (stream != file_transfer_state.stream) {
        vfs_mngr_printf("    error: changed types during tranfer from %i to %i\r\n", stream, file_transfer_state.stream);
        transfer_update_state(ERROR_ERROR_DURING_TRANSFER);
        return;
    }

    // Open stream
    status = stream_open(stream);
    vfs_mngr_printf("    stream_open stream=%i ret %i\r\n", stream, status);

    if (ERROR_SUCCESS == status) {
        file_transfer_state.file_next_sector = start_sector;
        file_transfer_state.stream_open = true;
        file_transfer_state.stream_started = true;
    }

    transfer_update_state(status);
}
Ejemplo n.º 5
0
// Update the tranfer state with new information
static void transfer_update_stream_data(uint32_t current_sector, uint32_t size, error_t status)
{
    util_assert(file_transfer_state.stream_open);
    util_assert(size % VFS_SECTOR_SIZE == 0);
    util_assert(file_transfer_state.file_next_sector == current_sector);

    file_transfer_state.size_processed += size;
    file_transfer_state.file_next_sector = current_sector + size / VFS_SECTOR_SIZE;
    
    // Update status
    file_transfer_state.status = status;
    transfer_check_for_completion();
}
Ejemplo n.º 6
0
error_t flash_manager_init(const flash_intf_t *flash_intf)
{
    error_t status;
    // Assert that interface has been properly uninitialized
    flash_manager_printf("flash_manager_init()\r\n");

    if (state != STATE_CLOSED) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Check for a valid flash interface
    if (!flash_intf_valid(flash_intf)) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Initialize variables
    memset(buf, 0xFF, sizeof(buf));
    buf_empty = true;
    current_sector_valid = false;
    current_write_block_addr = 0;
    current_write_block_size = 0;
    current_sector_addr = 0;
    current_sector_size = 0;
    last_addr = 0;
    intf = flash_intf;
    // Initialize flash
    status = intf->init();
    flash_manager_printf("    intf->init ret=%i\r\n", status);

    if (ERROR_SUCCESS != status) {
        return status;
    }

    if (!page_erase_enabled) {
        // Erase flash and unint if there are errors
        status = intf->erase_chip();
        flash_manager_printf("    intf->erase_chip ret=%i\r\n", status);

        if (ERROR_SUCCESS != status) {
            intf->uninit();
            return status;
        }
    }

    state = STATE_OPEN;
    return status;
}
Ejemplo n.º 7
0
flash_decoder_type_t flash_decoder_detect_type(const uint8_t *data, uint32_t size, uint32_t addr, bool addr_valid)
{
    daplink_info_t info;
    util_assert(size >= FLASH_DECODER_MIN_SIZE);
    // Check if this is a daplink image
    memcpy(&info, data + DAPLINK_INFO_OFFSET, sizeof(info));

    if (DAPLINK_HIC_ID == info.hic_id) {
        if (DAPLINK_BUILD_KEY_IF == info.build_key) {
            // Interface update
            return FLASH_DECODER_TYPE_INTERFACE;
        } else if (DAPLINK_BUILD_KEY_BL == info.build_key) {
            // Bootloader update
            return FLASH_DECODER_TYPE_BOOTLOADER;
        } else {
            return FLASH_DECODER_TYPE_UNKNOWN;
        }
    }

    // Check if a valid vector table for the target can be found
    if (validate_bin_nvic(data)) {
        return FLASH_DECODER_TYPE_TARGET;
    }

    // If an address is specified then the data can be decoded
    if (addr_valid) {
        // TODO - future improvement - make sure address is within target's flash
        return FLASH_DECODER_TYPE_TARGET;
    }

    return FLASH_DECODER_TYPE_UNKNOWN;
}
Ejemplo n.º 8
0
__declspec(naked) code *code_calloc()
{
    if (sizeof(code) != 0x24)
        util_assert("code",__LINE__);
    __asm
    {
        mov     EAX,code_list
        test    EAX,EAX
        je      L20
        mov     ECX,[EAX]
        mov     code_list,ECX
        jmp     L29

L20:    push    sizeof(code)
        call    mem_fmalloc
        ;add    ESP,4
L29:
        xor     ECX,ECX
        mov     DWORD PTR [EAX],0

        mov     4[EAX],ECX      ;these pair
        mov     8[EAX],ECX

        mov     12[EAX],ECX
        mov     16[EAX],ECX

        mov     20[EAX],ECX
        mov     24[EAX],ECX

        mov     28[EAX],ECX
        mov     32[EAX],ECX
        ret
    }
}
Ejemplo n.º 9
0
error_t flash_decoder_close(void)
{
    error_t status = ERROR_SUCCESS;
    decoder_state_t prev_state = state;
    flash_decoder_printf("flash_decoder_close()\r\n");

    if (DECODER_STATE_CLOSED == state) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    state = DECODER_STATE_CLOSED;

    if (flash_initialized) {
        status = flash_manager_uninit();
        flash_decoder_printf("    flash_manager_uninit ret %i\r\n", status);
    }

    if ((DECODER_STATE_DONE != prev_state) &&
            (flash_type != FLASH_DECODER_TYPE_TARGET) &&
            (status == ERROR_SUCCESS)) {
        status = ERROR_IAP_UPDT_INCOMPLETE;
    }

    return status;
}
Ejemplo n.º 10
0
static bool ready_for_state_change(void)
{
    uint32_t timeout_ms = INVALID_TIMEOUT_MS;
    util_assert(vfs_state != vfs_state_next);

    if (VFS_MNGR_STATE_CONNECTED == vfs_state) {
        switch (file_transfer_state.transfer_state) {
            case TRANSFER_NOT_STARTED:
            case TRASNFER_FINISHED:
                timeout_ms = DISCONNECT_DELAY_MS;
                break;

            case TRANSFER_IN_PROGRESS:
                timeout_ms = DISCONNECT_DELAY_TRANSFER_TIMEOUT_MS;
                break;

            case TRANSFER_CAN_BE_FINISHED:
                timeout_ms = DISCONNECT_DELAY_TRANSFER_IDLE_MS;
                break;

            default:
                util_assert(0);
                timeout_ms = DISCONNECT_DELAY_MS;
                break;
        }
    } else if ((VFS_MNGR_STATE_DISCONNECTED == vfs_state) &&
               (VFS_MNGR_STATE_CONNECTED == vfs_state_next)) {
        timeout_ms = CONNECT_DELAY_MS;
    } else if ((VFS_MNGR_STATE_RECONNECTING == vfs_state) &&
               (VFS_MNGR_STATE_CONNECTED == vfs_state_next)) {
        timeout_ms = RECONNECT_DELAY_MS;
    } else if ((VFS_MNGR_STATE_RECONNECTING == vfs_state) &&
               (VFS_MNGR_STATE_DISCONNECTED == vfs_state_next)) {
        timeout_ms = 0;
    }

    if (INVALID_TIMEOUT_MS == timeout_ms) {
        util_assert(0);
        timeout_ms = 0;
    }

    return time_usb_idle > timeout_ms ? true : false;
}
Ejemplo n.º 11
0
static error_t setup_next_sector(uint32_t addr)
{
    uint32_t min_prog_size;
    uint32_t sector_size;
    error_t status;
    min_prog_size = intf->program_page_min_size(addr);
    sector_size = intf->erase_sector_size(addr);

    if ((min_prog_size <= 0) || (sector_size <= 0)) {
        // Either of these conditions could cause divide by 0 error
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Assert required size and alignment
    util_assert(sizeof(buf) >= min_prog_size);
    util_assert(sizeof(buf) % min_prog_size == 0);
    util_assert(sector_size >= min_prog_size);
    util_assert(sector_size % min_prog_size == 0);
    // Setup global variables
    current_sector_addr = ROUND_DOWN(addr, sector_size);
    current_sector_size = sector_size;
    current_write_block_addr = current_sector_addr;
    current_write_block_size = MIN(sector_size, sizeof(buf));

    if(page_erase_enabled) {
        // Erase the current sector
        status = intf->erase_sector(current_sector_addr);
        flash_manager_printf("    intf->erase_sector(addr=0x%x) ret=%i\r\n", current_sector_addr);
        if (ERROR_SUCCESS != status) {
            intf->uninit();
            return status;
        }         
    }

    // Clear out buffer in case block size changed
    memset(buf, 0xFF, current_write_block_size);
    flash_manager_printf("    setup_next_sector(addr=0x%x) sect_addr=0x%x, write_addr=0x%x,\r\n",
                         addr, current_sector_addr, current_write_block_addr);
    flash_manager_printf("        actual_write_size=0x%x, sector_size=0x%x, min_write=0x%x\r\n",
                         current_write_block_size, current_sector_size, min_prog_size);
    return ERROR_SUCCESS;
}
Ejemplo n.º 12
0
static error_t write_hex(void *state, const uint8_t *data, uint32_t size)
{
    error_t status = ERROR_SUCCESS;
    hex_state_t *hex_state = (hex_state_t *)state;
    hexfile_parse_status_t parse_status = HEX_PARSE_UNINIT;
    uint32_t bin_start_address = 0; // Decoded from the hex file, the binary buffer data starts at this address
    uint32_t bin_buf_written = 0;   // The amount of data in the binary buffer starting at address above
    uint32_t block_amt_parsed = 0;  // amount of data parsed in the block on the last call

    while (1) {
        // try to decode a block of hex data into bin data
        parse_status = parse_hex_blob(data, size, &block_amt_parsed, hex_state->bin_buffer, sizeof(hex_state->bin_buffer), &bin_start_address, &bin_buf_written);

        // the entire block of hex was decoded. This is a simple state
        if (HEX_PARSE_OK == parse_status) {
            if (bin_buf_written > 0) {
                status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written);
            }

            break;
        } else if (HEX_PARSE_UNALIGNED == parse_status) {
            if (bin_buf_written > 0) {
                status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written);

                if (ERROR_SUCCESS != status) {
                    break;
                }
            }

            // incrememntal offset to finish the block
            size -= block_amt_parsed;
            data += block_amt_parsed;
        } else if (HEX_PARSE_EOF == parse_status) {
            if (bin_buf_written > 0) {
                status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written);
            }

            if (ERROR_SUCCESS == status) {
                status = ERROR_SUCCESS_DONE;
            }

            break;
        } else if (HEX_PARSE_CKSUM_FAIL == parse_status) {
            status = ERROR_HEX_CKSUM;
            break;
        } else if ((HEX_PARSE_UNINIT == parse_status) || (HEX_PARSE_FAILURE == parse_status)) {
            util_assert(HEX_PARSE_UNINIT != parse_status);
            status = ERROR_HEX_PARSER;
            break;
        }
    }

    return status;
}
Ejemplo n.º 13
0
// Update the tranfer state with new information
static void transfer_update_stream_open(stream_type_t stream, uint32_t start_sector, error_t status)
{
    util_assert(!file_transfer_state.stream_open);
    vfs_user_printf("virtual_fs_user transfer_update_stream_open(stream=%i, start_sector=%i, status=%i)\r\n",
                    stream, start_sector, status);

    // Status should still be at it's default of ERROR_SUCCESS
    util_assert(ERROR_SUCCESS == file_transfer_state.status);

    // Initialize the starting sector if it has not been set
    if (VFS_INVALID_SECTOR == file_transfer_state.start_sector) {
        file_transfer_state.start_sector = start_sector;
    }
    // Initialize the stream if it has not been set
    if (STREAM_TYPE_NONE == file_transfer_state.stream) {
        file_transfer_state.stream = stream;
    }

    // Check - Starting sector must be the same
    if (start_sector != file_transfer_state.start_sector) {
        vfs_user_printf("    error: starting sector changed from %i to %i\r\n", file_transfer_state.start_sector, start_sector);
        file_transfer_state.status = ERROR_ERROR_DURING_TRANSFER;
    }
    // Check - stream must be the same
    if (stream != file_transfer_state.stream) {
        vfs_user_printf("    error: changed types during tranfer from %i to %i\r\n", stream, file_transfer_state.stream);
        file_transfer_state.status = ERROR_ERROR_DURING_TRANSFER;
    }

    // Check - were there any errors with the open
    if (ERROR_SUCCESS == file_transfer_state.status) {
        file_transfer_state.status = status;
    }

    if (ERROR_SUCCESS == status) {
        file_transfer_state.file_next_sector = start_sector;
        file_transfer_state.stream_open = true;
    }
    transfer_check_for_completion();
}
Ejemplo n.º 14
0
// Callback to handle changes to the root directory.  Should be used with vfs_set_file_change_callback
static void file_change_handler(const vfs_filename_t filename, vfs_file_change_t change, vfs_file_t file, vfs_file_t new_file_data)
{
    vfs_user_printf("virtual_fs_user file_change_handler(name=%*s, change=%i)\r\n", 11, filename, change);

    if (VFS_FILE_CHANGED == change) {
        if (file == file_transfer_state.file_to_program) {
            stream_type_t stream;
            uint32_t size = vfs_file_get_size(new_file_data);
            vfs_sector_t sector = vfs_file_get_start_sector(new_file_data);
            vfs_user_printf("    file properties changed, size=%i\r\n", 11, size);
            stream = stream_type_from_name(filename);
            transfer_update_file_info(file, sector, size, stream);
        }
    }

    if (VFS_FILE_CREATED == change) {
        stream_type_t stream;
        if (!memcmp(filename, daplink_mode_file_name, sizeof(vfs_filename_t))) {
            if (daplink_is_interface()) {
                config_ram_set_hold_in_bl(true);
            } else {
                // Do nothing - bootloader will go to interface by default
            }
            vfs_user_remount();
        } else if (!memcmp(filename, "AUTO_RSTCFG", sizeof(vfs_filename_t))) {
            config_set_auto_rst(true);
            vfs_user_remount();
        } else if (!memcmp(filename, "HARD_RSTCFG", sizeof(vfs_filename_t))) {
            config_set_auto_rst(false);
            vfs_user_remount();
        } else if (!memcmp(filename, "ASSERT  ACT", sizeof(vfs_filename_t))) {
            // Test asserts
            util_assert(0);
        } else if (!memcmp(filename, "REFRESH ACT", sizeof(vfs_filename_t))) {
            // Remount to update the drive
            vfs_user_remount();
        } else if (STREAM_TYPE_NONE != stream_type_from_name(filename)) {
            stream = stream_type_from_name(filename);
            uint32_t size = vfs_file_get_size(new_file_data);
            vfs_user_printf("    found file to decode, type=%i\r\n", stream);
            vfs_sector_t sector = vfs_file_get_start_sector(new_file_data);
            transfer_update_file_info(file, sector, size, stream);
        } 
    }

    if (VFS_FILE_DELETED == change) {
        if (!memcmp(filename, assert_file, sizeof(vfs_filename_t))) {
            util_assert_clear();
        }
    }
}
Ejemplo n.º 15
0
error_t stream_close(void)
{
    error_t status;

    // Stream must not be closed already
    if (STREAM_STATE_CLOSED == state) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Check thread after checking state since the stream thread is
    // set only if stream_open has been called
    stream_thread_assert();
    // Close stream
    status = current_stream->close(&shared_state);
    state = STREAM_STATE_CLOSED;
    return status;
}
Ejemplo n.º 16
0
error_t flash_manager_uninit(void)
{
    error_t flash_uninit_error;
    error_t flash_write_error = ERROR_SUCCESS;
    flash_manager_printf("flash_manager_uninit()\r\n");

    if (STATE_CLOSED == state) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Write out current page
    if ((STATE_OPEN == state) && (!buf_empty)) {
        flash_write_error = intf->program_page(current_write_block_addr, buf, current_write_block_size);
        flash_manager_printf("    intf->program_page(addr=0x%x, size=0x%x) ret=%i\r\n",
                             current_write_block_addr, current_write_block_size, flash_write_error);
    }

    // Close flash interface (even if there was an error during program_page)
    flash_uninit_error = intf->uninit();
    flash_manager_printf("    intf->uninit() ret=%i\r\n", flash_uninit_error);
    // Reset variables to catch accidental use
    memset(buf, 0xFF, sizeof(buf));
    buf_empty = true;
    current_sector_valid = false;
    current_write_block_addr = 0;
    current_write_block_size = 0;
    current_sector_addr = 0;
    current_sector_size = 0;
    last_addr = 0;
    state = STATE_CLOSED;

    // Make sure an error from a page write or from an
    // uninit gets propagated
    if (flash_uninit_error != ERROR_SUCCESS) {
        return flash_uninit_error;
    }

    if (flash_write_error != ERROR_SUCCESS) {
        return flash_write_error;
    }

    return ERROR_SUCCESS;
}
Ejemplo n.º 17
0
error_t flash_decoder_open(void)
{
    flash_decoder_printf("flash_decoder_open()\r\n");

    // Stream must not be open already
    if (state != DECODER_STATE_CLOSED) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    memset(flash_buf, 0xff, sizeof(flash_buf));
    state = DECODER_STATE_OPEN;
    flash_type = FLASH_DECODER_TYPE_UNKNOWN;
    flash_buf_pos = 0;
    initial_addr = 0;
    current_addr = 0;
    flash_initialized = false;
    initial_addr_set = false;
    return ERROR_SUCCESS;
}
Ejemplo n.º 18
0
// Check if the current transfer is still in progress, done, or if an error has occurred
static void transfer_check_for_completion()
{
    bool file_fully_processed;
    bool size_nonzero;

    util_assert(!file_transfer_state.transfer_finished);

    // Check for completion of transfer
    file_fully_processed = file_transfer_state.size_processed >= file_transfer_state.file_size;
    size_nonzero = file_transfer_state.file_size > 0;

    if ((ERROR_SUCCESS_DONE == file_transfer_state.status) && file_fully_processed && size_nonzero) {
        // Full filesize has been transfered and the end of the stream has been reached.
        // Mark the transfer as finished and set result to success.
        vfs_user_printf("virtual_fs_user transfer_check_for_completion transfer successful\r\n");
        fail_reason = ERROR_SUCCESS;
        file_transfer_state.transfer_finished = true;
    } else if ((ERROR_SUCCESS_DONE_OR_CONTINUE == file_transfer_state.status) && file_fully_processed && size_nonzero) {
        // Full filesize has been transfered but the stream could not determine the end of the file.
        // Set the result to success but let the filetransfer time out. 
        vfs_user_printf("virtual_fs_user transfer_check_for_completion transfer successful, checking for more data\r\n");
        fail_reason = ERROR_SUCCESS;
    } else if ((ERROR_SUCCESS == file_transfer_state.status) || 
               (ERROR_SUCCESS_DONE == file_transfer_state.status) || 
               (ERROR_SUCCESS_DONE_OR_CONTINUE == file_transfer_state.status)) {
        fail_reason = ERROR_TRANSFER_IN_PROGRESS;
        // Transfer still in progress
    } else {
        // An error has occurred
        vfs_user_printf("virtual_fs_user transfer_check_for_completion error=%i,\r\n"
                        "    file_finished=%i, size_processed=%i file_size=%i\r\n",
                        file_transfer_state.status, file_fully_processed,
                        file_transfer_state.size_processed, file_transfer_state.file_size);
        fail_reason = file_transfer_state.status;
        file_transfer_state.transfer_finished = true;
    }

    // Always start remounting
    vfs_user_remount();
}
Ejemplo n.º 19
0
static void sync_assert_usb_thread(void)
{
    util_assert(os_tsk_self() == sync_thread);
}
Ejemplo n.º 20
0
error_t flash_decoder_get_flash(flash_decoder_type_t type, uint32_t addr, bool addr_valid, uint32_t *start_addr, const flash_intf_t **flash_intf)
{
    error_t status = ERROR_SUCCESS;
    uint32_t flash_start_local;
    const flash_intf_t *flash_intf_local = 0;

    if ((0 == start_addr) || (0 == flash_intf)) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    *start_addr = 0;
    *flash_intf = 0;
    flash_start_local = 0;
    flash_intf_local = 0;

    if (daplink_is_bootloader()) {
        if (FLASH_DECODER_TYPE_INTERFACE == type) {
            if (addr_valid && (DAPLINK_ROM_IF_START != addr)) {
                // Address is wrong so display error message
                status = ERROR_FD_INTF_UPDT_ADDR_WRONG;
                flash_start_local = 0;
                flash_intf_local = 0;
            } else {
                // Setup for update
                flash_start_local = DAPLINK_ROM_IF_START;
                flash_intf_local = flash_intf_iap_protected;
            }
        } else if (FLASH_DECODER_TYPE_TARGET == type) {
            // "Target" update in this case would be a 3rd party interface application
            flash_start_local = DAPLINK_ROM_IF_START;
            flash_intf_local = flash_intf_iap_protected;
        }
    } else if (daplink_is_interface()) {
        if (FLASH_DECODER_TYPE_BOOTLOADER == type) {
            if (addr_valid && (DAPLINK_ROM_BL_START != addr)) {
                // Address is wrong so display error message
                status = ERROR_FD_BL_UPDT_ADDR_WRONG;
                flash_start_local = 0;
                flash_intf_local = 0;
            } else {
                // Setup for update
                flash_start_local = DAPLINK_ROM_BL_START;
                flash_intf_local = flash_intf_iap_protected;
            }
        } else if (FLASH_DECODER_TYPE_TARGET == type) {
            flash_start_local = target_device.flash_start;
            flash_intf_local = flash_intf_target;
        }
    } else {
        status = ERROR_FD_UNSUPPORTED_UPDATE;
    }

    // Don't allow bootloader updates unless automation is allowed
    if (!config_get_automation_allowed() && (FLASH_DECODER_TYPE_BOOTLOADER == type)) {
        status = ERROR_FD_UNSUPPORTED_UPDATE;
    }

    if (ERROR_SUCCESS != status) {
        return status;
    }

    if (0 == flash_intf_local) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    *start_addr = flash_start_local;
    *flash_intf = flash_intf_local;
    return status;
}
Ejemplo n.º 21
0
static void stream_thread_assert(void)
{
    util_assert(osThreadGetId() == stream_thread_tid);
}
Ejemplo n.º 22
0
static uint32_t target_flash_program_page_min_size(uint32_t addr)
{
    uint32_t size = 256;
    util_assert(target_device.sector_size >= size);
    return size;
}
Ejemplo n.º 23
0
// Update the tranfer state with file information
static void transfer_update_file_info(vfs_file_t file, uint32_t start_sector, uint32_t size, stream_type_t stream)
{
    vfs_mngr_printf("vfs_manager transfer_update_file_info(file=%p, start_sector=%i, size=%i)\r\n", file, start_sector, size);

    if (TRASNFER_FINISHED == file_transfer_state.transfer_state) {
        util_assert(0);
        return;
    }

    // Initialize the directory entry if it has not been set
    if (VFS_FILE_INVALID == file_transfer_state.file_to_program) {
        file_transfer_state.file_to_program = file;

        if (file != VFS_FILE_INVALID) {
            vfs_mngr_printf("    file_to_program=%p\r\n", file);
        }
    }

    // Initialize the starting sector if it has not been set
    if (VFS_INVALID_SECTOR == file_transfer_state.start_sector) {
        file_transfer_state.start_sector = start_sector;

        if (start_sector != VFS_INVALID_SECTOR) {
            vfs_mngr_printf("    start_sector=%i\r\n", start_sector);
        }
    }

    // Initialize the stream if it has not been set
    if (STREAM_TYPE_NONE == file_transfer_state.stream) {
        file_transfer_state.stream = stream;

        if (stream != STREAM_TYPE_NONE) {
            vfs_mngr_printf("    stream=%i\r\n", stream);
        }
    }

    // Check - File size must be the same or bigger
    if (size < file_transfer_state.file_size) {
        vfs_mngr_printf("    error: file size changed from %i to %i\r\n", file_transfer_state.file_size, size);
        transfer_update_state(ERROR_ERROR_DURING_TRANSFER);
        return;
    }

    // Check - Starting sector must be the same  - this is optional for file info since it may not be present initially
    if ((VFS_INVALID_SECTOR != start_sector) && (start_sector != file_transfer_state.start_sector)) {
        vfs_mngr_printf("    error: starting sector changed from %i to %i\r\n", file_transfer_state.start_sector, start_sector);
        transfer_update_state(ERROR_ERROR_DURING_TRANSFER);
        return;
    }

    // Check - stream must be the same
    if (stream != file_transfer_state.stream) {
        vfs_mngr_printf("    error: changed types during transfer from %i to %i\r\n", stream, file_transfer_state.stream);
        transfer_update_state(ERROR_ERROR_DURING_TRANSFER);
        return;
    }

    // Update values - Size is the only value that can change and it can only increase.
    if (size > file_transfer_state.file_size) {
        file_transfer_state.file_size = size;
        vfs_mngr_printf("    updated size=%i\r\n", size);
    }

    transfer_update_state(ERROR_SUCCESS);
}
Ejemplo n.º 24
0
error_t flash_manager_data(uint32_t addr, const uint8_t *data, uint32_t size)
{
    uint32_t size_left;
    uint32_t copy_size;
    uint32_t pos;
    error_t status = ERROR_SUCCESS;
    flash_manager_printf("flash_manager_data(addr=0x%x size=0x%x)\r\n", addr, size);

    if (state != STATE_OPEN) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Setup the current sector if it is not setup already
    if (!current_sector_valid) {
        status = setup_next_sector(addr);

        if (ERROR_SUCCESS != status) {
            state = STATE_ERROR;
            return status;
        }
        current_sector_valid = true;
        last_addr = addr;
    }
    
    //non-increasing address support
    if (ROUND_DOWN(addr, current_write_block_size) != ROUND_DOWN(last_addr, current_write_block_size)) {    
        status = flush_current_block(addr);
        if (ERROR_SUCCESS != status) {
            state = STATE_ERROR;
            return status;
        }
    }
    
    if (ROUND_DOWN(addr, current_sector_size) != ROUND_DOWN(last_addr, current_sector_size)) {
        status = setup_next_sector(addr);
        if (ERROR_SUCCESS != status) {
            state = STATE_ERROR;
            return status;
        }
    }

    while (true) {
        // flush if necessary
        if (addr >= current_write_block_addr + current_write_block_size) {
            status = flush_current_block(addr);
            if (ERROR_SUCCESS != status) {
                state = STATE_ERROR;
                return status;
            }
        }

        // Check for end
        if (size <= 0) {
            break;
        }

        // Change sector if necessary
        if (addr >= current_sector_addr + current_sector_size) {
            status = setup_next_sector(addr);

            if (ERROR_SUCCESS != status) {
                state = STATE_ERROR;
                return status;
            }
            // check is at sector boundary
            if (addr != current_write_block_addr) {
                current_write_block_addr = addr & 0xFFFFFFF0;  // 16 bytes alignment
            }
        }

        // write buffer
        pos = addr - current_write_block_addr;
        size_left = current_write_block_size - pos;
        copy_size = MIN(size, size_left);
        memcpy(buf + pos, data, copy_size);
        buf_empty = copy_size == 0;
        // Update variables
        addr += copy_size;
        data += copy_size;
        size -= copy_size;
    }

    last_addr = addr;
    return status;
}
Ejemplo n.º 25
0
void vfs_mngr_periodic(uint32_t elapsed_ms)
{
    bool change_state;
    vfs_mngr_state_t vfs_state_local;
    vfs_mngr_state_t vfs_state_local_prev;
    sync_assert_usb_thread();
    sync_lock();

    // Return immediately if the desired state has been reached
    if (!changing_state()) {
        sync_unlock();
        return;
    }

    change_state = ready_for_state_change();

    if (time_usb_idle < MAX_EVENT_TIME_MS) {
        time_usb_idle += elapsed_ms;
    }

    sync_unlock();

    if (!change_state) {
        return;
    }

    vfs_mngr_printf("vfs_mngr_periodic()\r\n");
    vfs_mngr_printf("   time_usb_idle=%i\r\n", time_usb_idle);
    vfs_mngr_printf("   transfer_state=%i\r\n", file_transfer_state.transfer_state);
    // Transistion to new state
    vfs_state_local_prev = vfs_state;
    vfs_state = vfs_state_next;

    switch (vfs_state) {
        case VFS_MNGR_STATE_RECONNECTING:
            // Transition back to the connected state
            vfs_state_next = VFS_MNGR_STATE_CONNECTED;
            break;

        default:
            // No state change logic required in other states
            break;
    }

    vfs_state_local = vfs_state;
    time_usb_idle = 0;
    sync_unlock();
    // Processing when leaving a state
    vfs_mngr_printf("    state %i->%i\r\n", vfs_state_local_prev, vfs_state_local);

    switch (vfs_state_local_prev) {
        case VFS_MNGR_STATE_DISCONNECTED:
            // No action needed
            break;

        case VFS_MNGR_STATE_RECONNECTING:
            // No action needed
            break;

        case VFS_MNGR_STATE_CONNECTED:

            // Close ongoing transfer if there is one
            if (file_transfer_state.transfer_state != TRASNFER_FINISHED) {
                vfs_mngr_printf("    transfer timeout\r\n");
                file_transfer_state.transfer_timeout = true;
                transfer_update_state(ERROR_SUCCESS);
            }

            util_assert(TRASNFER_FINISHED == file_transfer_state.transfer_state);
            vfs_user_disconnecting();
            break;
    }

    // Processing when entering a state
    switch (vfs_state_local) {
        case VFS_MNGR_STATE_DISCONNECTED:
            USBD_MSC_MediaReady = 0;
            break;

        case VFS_MNGR_STATE_RECONNECTING:
            USBD_MSC_MediaReady = 0;
            break;

        case VFS_MNGR_STATE_CONNECTED:
            build_filesystem();
            USBD_MSC_MediaReady = 1;
            break;
    }

    return;
}
Ejemplo n.º 26
0
// Check if the current transfer is still in progress, done, or if an error has occurred
static void transfer_update_state(error_t status)
{
    bool transfer_timeout;
    bool transfer_started;
    bool transfer_can_be_finished;
    bool transfer_must_be_finished;
    bool out_of_order_sector;
    error_t local_status = status;
    util_assert((status != ERROR_SUCCESS_DONE) &&
                (status != ERROR_SUCCESS_DONE_OR_CONTINUE));

    if (TRASNFER_FINISHED == file_transfer_state.transfer_state) {
        util_assert(0);
        return;
    }

    // Update file info status.  The end of a file is never known for sure since
    // what looks like a complete file could be part of a file getting flushed to disk.
    // The criteria for an successful optional finish is
    // 1. A file has been detected
    // 2. The size of the file indicated in the root dir has been transferred
    // 3. The file size is greater than zero
    file_transfer_state.file_info_optional_finish =
        (file_transfer_state.file_to_program != VFS_FILE_INVALID) &&
        (file_transfer_state.size_transferred >= file_transfer_state.file_size) &&
        (file_transfer_state.file_size > 0);
    transfer_timeout = file_transfer_state.transfer_timeout;
    transfer_started = (VFS_FILE_INVALID != file_transfer_state.file_to_program) ||
                       (STREAM_TYPE_NONE != file_transfer_state.stream);
    // The transfer can be finished if both file and stream processing
    // can be considered complete
    transfer_can_be_finished = file_transfer_state.file_info_optional_finish &&
                               file_transfer_state.stream_optional_finish;
    // The transfer must be fnished if stream processing is for sure complete
    // and file processing can be considered complete
    transfer_must_be_finished = file_transfer_state.stream_finished &&
                                file_transfer_state.file_info_optional_finish;
    out_of_order_sector = false;

    if (file_transfer_state.last_ooo_sector != VFS_INVALID_SECTOR) {
        util_assert(file_transfer_state.start_sector != VFS_INVALID_SECTOR);
        uint32_t sector_offset = (file_transfer_state.last_ooo_sector -
                                  file_transfer_state.start_sector) * VFS_SECTOR_SIZE;

        if (sector_offset < file_transfer_state.size_processed) {
            // The out of order sector was within the range of data already
            // processed.
            out_of_order_sector = true;
        }
    }

    // Set the transfer state and set the status if necessary
    if (local_status != ERROR_SUCCESS) {
        file_transfer_state.transfer_state = TRASNFER_FINISHED;
    } else if (transfer_timeout) {
        if (out_of_order_sector) {
            local_status = ERROR_OOO_SECTOR;
        } else if (!transfer_started) {
            local_status = ERROR_SUCCESS;
        } else if (transfer_can_be_finished) {
            local_status = ERROR_SUCCESS;
        } else {
            local_status = ERROR_TRANSFER_TIMEOUT;
        }

        file_transfer_state.transfer_state = TRASNFER_FINISHED;
    } else if (transfer_must_be_finished) {
        file_transfer_state.transfer_state = TRASNFER_FINISHED;
    } else if (transfer_can_be_finished) {
        file_transfer_state.transfer_state = TRANSFER_CAN_BE_FINISHED;
    } else if (transfer_started) {
        file_transfer_state.transfer_state = TRANSFER_IN_PROGRESS;
    }

    if (TRASNFER_FINISHED == file_transfer_state.transfer_state) {
        vfs_mngr_printf("vfs_manager transfer_update_state(status=%i)\r\n", status);
        vfs_mngr_printf("    file=%p, start_sect= %i, size=%i\r\n",
                        file_transfer_state.file_to_program, file_transfer_state.start_sector,
                        file_transfer_state.file_size);
        vfs_mngr_printf("    stream=%i, size_processed=%i, opt_finish=%i, timeout=%i\r\n",
                        file_transfer_state.stream, file_transfer_state.size_processed,
                        file_transfer_state.file_info_optional_finish, transfer_timeout);

        // Close the file stream if it is open
        if (file_transfer_state.stream_open) {
            error_t close_status;
            close_status = stream_close();
            vfs_mngr_printf("    stream closed ret=%i\r\n", close_status);
            file_transfer_state.stream_open = false;

            if (ERROR_SUCCESS == local_status) {
                local_status = close_status;
            }
        }

        // Set the fail reason
        fail_reason = local_status;
        vfs_mngr_printf("    Transfer finished, status: %i=%s\r\n", fail_reason, error_get_string(fail_reason));
    }

    // If this state change is not from aborting a transfer
    // due to a remount then trigger a remount
    if (!transfer_timeout) {
        vfs_mngr_fs_remount();
    }
}
Ejemplo n.º 27
0
error_t flash_manager_data(uint32_t addr, const uint8_t *data, uint32_t size)
{
    uint32_t size_left;
    uint32_t copy_size;
    uint32_t pos;
    error_t status = ERROR_SUCCESS;
    flash_manager_printf("flash_manager_data(addr=0x%x size=0x%x)\r\n", addr, size);

    if (state != STATE_OPEN) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Enforce that addresses are sequential.  Currently flash manager
    // only supports sequential addresses.  In the future flash manager
    // could be updated to support this.
    if (addr < last_addr) {
        util_assert(0);
        state = STATE_ERROR;
        return ERROR_INTERNAL;
    }

    // Setup the current sector if it is not setup already
    if (!current_sector_valid) {
        status = setup_next_sector(addr);

        if (ERROR_SUCCESS != status) {
            state = STATE_ERROR;
            return status;
        }
        current_sector_valid = true;
    }

    while (true) {
        // flush if necessary
        if (addr >= current_write_block_addr + current_write_block_size) {
            // Write out current buffer
            status = intf->program_page(current_write_block_addr, buf, current_write_block_size);
            flash_manager_printf("    intf->program_page(addr=0x%x, size=0x%x) ret=%i\r\n", current_write_block_addr, current_write_block_size, status);

            if (ERROR_SUCCESS != status) {
                state = STATE_ERROR;
                return status;
            }

            // Setup for next page
            memset(buf, 0xFF, current_write_block_size);
            buf_empty = true;
            current_write_block_addr += current_write_block_size;
        }

        // Check for end
        if (size <= 0) {
            break;
        }

        // Change sector if necessary
        if (addr >= current_sector_addr + current_sector_size) {
            status = setup_next_sector(addr);

            if (ERROR_SUCCESS != status) {
                state = STATE_ERROR;
                return status;
            }
        }

        // write buffer
        pos = addr - current_write_block_addr;
        size_left = current_write_block_size - pos;
        copy_size = MIN(size, size_left);
        memcpy(buf + pos, data, copy_size);
        buf_empty = copy_size == 0;
        // Update variables
        addr += copy_size;
        data += copy_size;
        size -= copy_size;
    }

    last_addr = addr;
    return status;
}
Ejemplo n.º 28
0
void HardFault_Handler()
{
    util_assert(0);
    NVIC_SystemReset();
    while (1); // Wait for reset
}
Ejemplo n.º 29
0
error_t flash_decoder_write(uint32_t addr, const uint8_t *data, uint32_t size)
{
    error_t status;
    flash_decoder_printf("flash_decoder_write(addr=0x%x, size=0x%x)\r\n", addr, size);

    if (DECODER_STATE_OPEN != state) {
        util_assert(0);
        return ERROR_INTERNAL;
    }

    // Set the initial address the first time through
    if (!initial_addr_set) {
        initial_addr = addr;
        current_addr = initial_addr;
        flash_decoder_printf("     initial_addr=0x%x\r\n", initial_addr);
        initial_addr_set = true;
    }

    if (!flash_initialized) {
        uint32_t copy_size;
        bool flash_type_known = false;
        bool sequential;
        // Check if the data is sequential
        sequential = addr == current_addr;
        current_addr += size;

        // Buffer data until the flash type is known
        if (sequential) {
            // Copy data into buffer
            copy_size = MIN(size, sizeof(flash_buf) - flash_buf_pos);
            memcpy(&flash_buf[flash_buf_pos], data, copy_size);
            flash_buf_pos += copy_size;
            flash_decoder_printf("    buffering %i bytes\r\n", copy_size);
            // Update vars so they no longer include the buffered data
            data += copy_size;
            size -= copy_size;
            addr += copy_size;

            // If enough data has been buffered then determine the type
            if (flash_buf_pos >= sizeof(flash_buf)) {
                util_assert(sizeof(flash_buf) == flash_buf_pos);
                // Determine flash type and get info for it
                flash_type = flash_decoder_detect_type(flash_buf, flash_buf_pos, initial_addr, true);
                flash_decoder_printf("    Buffering complete, setting flash_type=%i\r\n", flash_type);
                flash_type_known = true;
            }
        } else {
            flash_type = FLASH_DECODER_TYPE_TARGET;
            flash_decoder_printf("    Non sequential addr, setting flash_type=%i\r\n", flash_type);
            flash_type_known = true;
        }

        // If flash type is known initialize the flash manager
        if (flash_type_known) {
            const flash_intf_t *flash_intf;
            uint32_t flash_start_addr;
            status = flash_decoder_get_flash(flash_type, initial_addr, true, &flash_start_addr, &flash_intf);

            if (ERROR_SUCCESS != status) {
                state = DECODER_STATE_ERROR;
                return status;
            }

            flash_decoder_printf("    flash_start_addr=0x%x\r\n", flash_start_addr);
            // Initialize flash manager
            util_assert(!flash_initialized);
            status = flash_manager_init(flash_intf);
            flash_decoder_printf("    flash_manager_init ret %i\r\n", status);

            if (ERROR_SUCCESS != status) {
                state = DECODER_STATE_ERROR;
                return status;
            }

            flash_initialized = true;
        }

        // If flash has been initalized then write out buffered data
        if (flash_initialized) {
            status = flash_manager_data(initial_addr, flash_buf, flash_buf_pos);
            flash_decoder_printf("    Flushing buffer initial_addr=0x%x, flash_buf_pos=%i, flash_manager_data ret=%i\r\n",
                                 initial_addr, flash_buf_pos, status);

            if (ERROR_SUCCESS != status) {
                state = DECODER_STATE_ERROR;
                return status;
            }
        }
    }

    // Write data as normal if flash has been initialized
    if (flash_initialized) {
        status = flash_manager_data(addr, data, size);
        flash_decoder_printf("    Writing data, addr=0x%x, size=0x%x, flash_manager_data ret %i\r\n",
                             addr, size, status);

        if (ERROR_SUCCESS != status) {
            state = DECODER_STATE_ERROR;
            return status;
        }
    }

    // Check if this is the end of data
    if (flash_decoder_is_at_end(addr, data, size)) {
        flash_decoder_printf("    End of transfer detected - addr 0x%08x, size 0x%08x\r\n",
                             addr, size);
        state = DECODER_STATE_DONE;
        return ERROR_SUCCESS_DONE;
    }

    return ERROR_SUCCESS;
}