Add buffering support for flash drivers.
Some devices can get a significant boost in performance by writing to flash memories one page at a time. Generic function to do this are provided at the target layer and may be used by flash drivers.
This commit is contained in:
parent
36f749fed9
commit
45328ea124
|
@ -133,6 +133,12 @@ struct target_flash {
|
|||
struct target_flash *next;
|
||||
int align;
|
||||
uint8_t erased;
|
||||
|
||||
/* For buffered flash */
|
||||
size_t buf_size;
|
||||
flash_write_func write_buf;
|
||||
uint32_t buf_addr;
|
||||
void *buf;
|
||||
};
|
||||
|
||||
struct target_s {
|
||||
|
@ -215,6 +221,9 @@ void target_add_commands(target *t, const struct command_s *cmds, const char *na
|
|||
void target_add_ram(target *t, uint32_t start, uint32_t len);
|
||||
void target_add_flash(target *t, struct target_flash *f);
|
||||
const char *target_mem_map(target *t);
|
||||
int target_flash_write_buffered(struct target_flash *f,
|
||||
uint32_t dest, const void *src, size_t len);
|
||||
int target_flash_done_buffered(struct target_flash *f);
|
||||
|
||||
static inline uint32_t target_mem_read32(target *t, uint32_t addr)
|
||||
{
|
||||
|
|
50
src/target.c
50
src/target.c
|
@ -57,6 +57,8 @@ void target_list_free(void)
|
|||
}
|
||||
while (target_list->flash) {
|
||||
void * next = target_list->flash->next;
|
||||
if (target_list->flash->buf)
|
||||
free(target_list->flash->buf);
|
||||
free(target_list->flash);
|
||||
target_list->flash = next;
|
||||
}
|
||||
|
@ -216,3 +218,51 @@ int target_flash_done(target *t)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int target_flash_write_buffered(struct target_flash *f,
|
||||
uint32_t dest, const void *src, size_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (f->buf == NULL) {
|
||||
/* Allocate flash sector buffer */
|
||||
f->buf = malloc(f->buf_size);
|
||||
f->buf_addr = -1;
|
||||
}
|
||||
while (len) {
|
||||
uint32_t offset = dest % f->buf_size;
|
||||
uint32_t base = dest - offset;
|
||||
if (base != f->buf_addr) {
|
||||
if (f->buf_addr != (uint32_t)-1) {
|
||||
/* Write sector to flash if valid */
|
||||
ret |= f->write_buf(f, f->buf_addr,
|
||||
f->buf, f->buf_size);
|
||||
}
|
||||
/* Setup buffer for a new sector */
|
||||
f->buf_addr = base;
|
||||
memset(f->buf, f->erased, f->buf_size);
|
||||
}
|
||||
/* Copy chunk into sector buffer */
|
||||
size_t sectlen = MIN(f->buf_size - offset, len);
|
||||
memcpy(f->buf + offset, src, sectlen);
|
||||
dest += sectlen;
|
||||
src += sectlen;
|
||||
len -= sectlen;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int target_flash_done_buffered(struct target_flash *f)
|
||||
{
|
||||
int ret = 0;
|
||||
if ((f->buf != NULL) &&(f->buf_addr != (uint32_t)-1)) {
|
||||
/* Write sector to flash if valid */
|
||||
ret = f->write_buf(f, f->buf_addr, f->buf, f->buf_size);
|
||||
f->buf_addr = -1;
|
||||
free(f->buf);
|
||||
f->buf = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue