Skip to content

Commit

Permalink
Merge pull request #1 from ARMmbed/master
Browse files Browse the repository at this point in the history
merge changes in head repo
  • Loading branch information
MarianSavchuk authored Mar 5, 2019
2 parents 487ab90 + e263c64 commit d393e15
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 103 deletions.
13 changes: 10 additions & 3 deletions source/daplink/drag-n-drop/flash_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ static uint32_t initial_addr;
static uint32_t current_addr;
static bool flash_initialized;
static bool initial_addr_set;
static bool flash_type_target_bin;

static bool flash_decoder_is_at_end(uint32_t addr, const uint8_t *data, uint32_t size);

Expand All @@ -65,7 +66,9 @@ flash_decoder_type_t flash_decoder_detect_type(const uint8_t *data, uint32_t siz
util_assert(size >= FLASH_DECODER_MIN_SIZE);
// Check if this is a daplink image
memcpy(&info, data + DAPLINK_INFO_OFFSET, sizeof(info));

if(!addr_valid){ //reset until we know the binary type
flash_type_target_bin = false;
}
if (DAPLINK_HIC_ID == info.hic_id) {
if (DAPLINK_BUILD_KEY_IF == info.build_key) {
// Interface update
Expand All @@ -80,6 +83,9 @@ flash_decoder_type_t flash_decoder_detect_type(const uint8_t *data, uint32_t siz

// Check if a valid vector table for the target can be found
if (validate_bin_nvic(data)) {
if(!addr_valid){ //binary is a bin type
flash_type_target_bin = true;
}
return FLASH_DECODER_TYPE_TARGET;
}

Expand Down Expand Up @@ -341,9 +347,10 @@ static bool flash_decoder_is_at_end(uint32_t addr, const uint8_t *data, uint32_t
case FLASH_DECODER_TYPE_INTERFACE:
end_addr = DAPLINK_ROM_IF_START + DAPLINK_ROM_IF_SIZE;
break;

case FLASH_DECODER_TYPE_TARGET:
if (g_board_info.target_cfg) {
//only if we are sure it is a bin for the target; without check unordered hex files will cause to terminate flashing
if (flash_type_target_bin && g_board_info.target_cfg) {
end_addr = g_board_info.target_cfg->flash_end;
}
else {
Expand Down
72 changes: 42 additions & 30 deletions source/daplink/drag-n-drop/flash_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ static const flash_intf_t *intf;
static state_t state = STATE_CLOSED;

static bool flash_intf_valid(const flash_intf_t *flash_intf);
static error_t flush_current_block(uint32_t addr);
static error_t setup_next_sector(uint32_t addr);

error_t flash_manager_init(const flash_intf_t *flash_intf)
Expand Down Expand Up @@ -124,15 +125,6 @@ error_t flash_manager_data(uint32_t addr, const uint8_t *data, uint32_t size)
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);
Expand All @@ -142,27 +134,34 @@ error_t flash_manager_data(uint32_t addr, const uint8_t *data, uint32_t size)
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) {

// Write out current buffer if there is data in it
if (!buf_empty) {
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;
}
buf_empty = true;
status = flush_current_block(addr);
if (ERROR_SUCCESS != status) {
state = STATE_ERROR;
return status;
}

// Setup for next page
memset(buf, 0xFF, current_write_block_size);
current_write_block_addr = ROUND_DOWN(addr,current_write_block_size);
}

// Check for end
Expand Down Expand Up @@ -207,13 +206,11 @@ error_t flash_manager_uninit(void)
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);
// Flush last buffer if its not empty
if (STATE_OPEN == state) {
flash_write_error = flush_current_block(0);
flash_manager_printf(" last flush_current_block ret=%i\r\n",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);
Expand Down Expand Up @@ -284,6 +281,21 @@ static bool flash_intf_valid(const flash_intf_t *flash_intf)
return true;
}

static error_t flush_current_block(uint32_t addr){
// Write out current buffer if there is data in it
error_t status = ERROR_SUCCESS;
if (!buf_empty) {
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);
buf_empty = true;
}

// Setup for next block
memset(buf, 0xFF, current_write_block_size);
current_write_block_addr = ROUND_DOWN(addr,current_write_block_size);
return status;
}

static error_t setup_next_sector(uint32_t addr)
{
uint32_t min_prog_size;
Expand Down
138 changes: 68 additions & 70 deletions source/daplink/drag-n-drop/intelhex.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,75 +121,7 @@ hexfile_parse_status_t parse_hex_blob(const uint8_t *hex_blob, const uint32_t he
// junk we dont care about could also just run the validate_checksum on &line
case '\r':
case '\n':
if (0 == validate_checksum(&line)) {
status = HEX_PARSE_CKSUM_FAIL;
goto hex_parser_exit;
} else {
if (!record_processed) {
record_processed = 1;
// address byteswap...
line.address = swap16(line.address);

switch (line.record_type) {
case DATA_RECORD:
// keeping a record of the last hex record
memcpy(shadow_line.buf, line.buf, sizeof(hex_line_t));

// verify this is a continous block of memory or need to exit and dump
if (((next_address_to_write & 0xffff0000) | line.address) != next_address_to_write) {
load_unaligned_record = 1;
status = HEX_PARSE_UNALIGNED;
goto hex_parser_exit;
}

// move from line buffer back to input buffer
memcpy(bin_buf, line.data, line.byte_count);
bin_buf += line.byte_count;
*bin_buf_cnt = (uint32_t)(*bin_buf_cnt) + line.byte_count;
// Save next address to write
next_address_to_write = ((next_address_to_write & 0xffff0000) | line.address) + line.byte_count;
break;

case EOF_RECORD:
// pad rest of the buffer with 0xff
//memset(bin_buf, 0xff, (bin_buf_size - (uint32_t)(*bin_buf_cnt)));
//*bin_buf_cnt = bin_buf_size;
status = HEX_PARSE_EOF;
goto hex_parser_exit;

case EXT_SEG_ADDR_RECORD:
// Could have had data in the buffer so must exit and try to program
// before updating bin_buf_address with next_address_to_write
memset(bin_buf, 0xff, (bin_buf_size - (uint32_t)(*bin_buf_cnt)));
// figure the start address for the buffer before returning
*bin_buf_address = next_address_to_write - (uint32_t)(*bin_buf_cnt);
*hex_parse_cnt = (uint32_t)(hex_blob_size - (end - hex_blob));
// update the address msb's
next_address_to_write = (next_address_to_write & 0x00000000) | ((line.data[0] << 12) | (line.data[1] << 4));
// Need to exit and program if buffer has been filled
status = HEX_PARSE_UNALIGNED;
return status;

case EXT_LINEAR_ADDR_RECORD:
// Could have had data in the buffer so must exit and try to program
// before updating bin_buf_address with next_address_to_write
// Good catch Gaute!!
memset(bin_buf, 0xff, (bin_buf_size - (uint32_t)(*bin_buf_cnt)));
// figure the start address for the buffer before returning
*bin_buf_address = next_address_to_write - (uint32_t)(*bin_buf_cnt);
*hex_parse_cnt = (uint32_t)(hex_blob_size - (end - hex_blob));
// update the address msb's
next_address_to_write = (next_address_to_write & 0x00000000) | ((line.data[0] << 24) | (line.data[1] << 16));
// Need to exit and program if buffer has been filled
status = HEX_PARSE_UNALIGNED;
return status;

default:
break;
}
}
}

//ignore new lines
break;

// found start of a new record. reset state variables
Expand All @@ -204,7 +136,73 @@ hexfile_parse_status_t parse_hex_blob(const uint8_t *hex_blob, const uint32_t he
default:
if (low_nibble) {
line.buf[idx] |= ctoh((uint8_t)(*hex_blob)) & 0xf;
idx++;
if (++idx >= (line.byte_count + 5)) { //all data in
if (0 == validate_checksum(&line)) {
status = HEX_PARSE_CKSUM_FAIL;
goto hex_parser_exit;
} else {
if (!record_processed) {
record_processed = 1;
// address byteswap...
line.address = swap16(line.address);

switch (line.record_type) {
case DATA_RECORD:
// keeping a record of the last hex record
memcpy(shadow_line.buf, line.buf, sizeof(hex_line_t));

// verify this is a continous block of memory or need to exit and dump
if (((next_address_to_write & 0xffff0000) | line.address) != next_address_to_write) {
load_unaligned_record = 1;
status = HEX_PARSE_UNALIGNED;
goto hex_parser_exit;
}

// move from line buffer back to input buffer
memcpy(bin_buf, line.data, line.byte_count);
bin_buf += line.byte_count;
*bin_buf_cnt = (uint32_t)(*bin_buf_cnt) + line.byte_count;
// Save next address to write
next_address_to_write = ((next_address_to_write & 0xffff0000) | line.address) + line.byte_count;
break;

case EOF_RECORD:
status = HEX_PARSE_EOF;
goto hex_parser_exit;

case EXT_SEG_ADDR_RECORD:
// Could have had data in the buffer so must exit and try to program
// before updating bin_buf_address with next_address_to_write
memset(bin_buf, 0xff, (bin_buf_size - (uint32_t)(*bin_buf_cnt)));
// figure the start address for the buffer before returning
*bin_buf_address = next_address_to_write - (uint32_t)(*bin_buf_cnt);
*hex_parse_cnt = (uint32_t)(hex_blob_size - (end - hex_blob));
// update the address msb's
next_address_to_write = (next_address_to_write & 0x00000000) | ((line.data[0] << 12) | (line.data[1] << 4));
// Need to exit and program if buffer has been filled
status = HEX_PARSE_UNALIGNED;
return status;

case EXT_LINEAR_ADDR_RECORD:
// Could have had data in the buffer so must exit and try to program
// before updating bin_buf_address with next_address_to_write
// Good catch Gaute!!
memset(bin_buf, 0xff, (bin_buf_size - (uint32_t)(*bin_buf_cnt)));
// figure the start address for the buffer before returning
*bin_buf_address = next_address_to_write - (uint32_t)(*bin_buf_cnt);
*hex_parse_cnt = (uint32_t)(hex_blob_size - (end - hex_blob));
// update the address msb's
next_address_to_write = (next_address_to_write & 0x00000000) | ((line.data[0] << 24) | (line.data[1] << 16));
// Need to exit and program if buffer has been filled
status = HEX_PARSE_UNALIGNED;
return status;

default:
break;
}
}
}
}
} else {
if (idx < sizeof(hex_line_t)) {
line.buf[idx] = ctoh((uint8_t)(*hex_blob)) << 4;
Expand Down

0 comments on commit d393e15

Please sign in to comment.