Skip to content

Commit

Permalink
target_flash: Implemented tracking for what Flash operation is in pro…
Browse files Browse the repository at this point in the history
…gress and the state of each Flash block

The idea here is that flash->operation will track what state the block is in (being erased, being written, idle)
to allow special steps to be taken during preparation and conclusion of operations on the block based
on what was done to it. This allows introducing special behaviour for such cases.

Co-authored-by: dragonmux <[email protected]>
Co-authored-by: Maciej 'vesim' Kuliński <[email protected]>
Co-authored-by: Rafael Silva <[email protected]>
  • Loading branch information
3 people committed Jul 14, 2023
1 parent cfe8a1c commit 85350c7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 12 deletions.
37 changes: 26 additions & 11 deletions src/target/target_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,36 +85,51 @@ static bool target_exit_flash_mode(target_s *target)
return result;
}

static bool flash_prepare(target_flash_s *flash)
static bool flash_prepare(target_flash_s *flash, flash_operation_e operation)
{
if (flash->ready)
/* Check if we're already prepared for this operation */
if (flash->operation == operation)
return true;

bool result = true;
if (flash->prepare)
result = flash->prepare(flash);

if (result == true)
flash->ready = true;
/* Terminate any ongoing Flash operation */
if (flash->operation != FLASH_OPERATION_NONE)
result = flash_done(flash);

/* If that succeeded, set up the new operating state */
if (result) {
flash->operation = operation;
/* Prepare flash for operation, unless we failed to terminate the previous one */
if (flash->prepare)
result = flash->prepare(flash);

/* If the preparation step failed, revert back to the post-done state */
if (!result)
flash->operation = FLASH_OPERATION_NONE;
}

return result;
}

static bool flash_done(target_flash_s *flash)
{
if (!flash->ready)
/* Check if we're already done */
if (flash->operation == FLASH_OPERATION_NONE)
return true;

bool result = true;
/* Terminate flash operation */
if (flash->done)
result = flash->done(flash);

/* Free the operation buffer */
if (flash->buf) {
free(flash->buf);
flash->buf = NULL;
}

flash->ready = false;
/* Mark the Flash as idle again */
flash->operation = FLASH_OPERATION_NONE;

return result;
}
Expand Down Expand Up @@ -145,7 +160,7 @@ bool target_flash_erase(target_s *target, target_addr_t addr, size_t len)
const target_addr_t local_start_addr = addr & ~(flash->blocksize - 1U);
const target_addr_t local_end_addr = local_start_addr + flash->blocksize;

if (!flash_prepare(flash))
if (!flash_prepare(flash, FLASH_OPERATION_ERASE))
return false;

result &= flash->erase(flash, local_start_addr, flash->blocksize);
Expand Down Expand Up @@ -183,7 +198,7 @@ static bool flash_buffered_flush(target_flash_s *flash)
flash->buf_addr_low < flash->buf_addr_high) {
/* Write buffer to flash */

if (!flash_prepare(flash))
if (!flash_prepare(flash, FLASH_OPERATION_WRITE))
return false;

const target_addr_t aligned_addr = flash->buf_addr_low & ~(flash->writesize - 1U);
Expand Down
8 changes: 7 additions & 1 deletion src/target/target_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
extern target_s *target_list;
target_s *target_new(void);

typedef enum flash_operation {
FLASH_OPERATION_NONE,
FLASH_OPERATION_ERASE,
FLASH_OPERATION_WRITE,
} flash_operation_e;

typedef struct target_ram target_ram_s;

struct target_ram {
Expand All @@ -53,7 +59,7 @@ struct target_flash {
size_t writesize; /* Write operation size, must be <= blocksize/writebufsize */
size_t writebufsize; /* Size of write buffer, this is calculated and not set in target code */
uint8_t erased; /* Byte erased state */
bool ready; /* True if flash is in flash mode/prepared */
uint8_t operation; /* Current Flash operation (none means it's idle/unprepared) */
flash_prepare_func prepare; /* Prepare for flash operations */
flash_erase_func erase; /* Erase a range of flash */
flash_write_func write; /* Write to flash */
Expand Down

0 comments on commit 85350c7

Please sign in to comment.