Mercurial > ecos-v3_0-branch
changeset 2700:99efb5fe625e
* src/synth.c: Implemented simulation of proper NOR flash writes.
General cleanup.
| author | asl |
|---|---|
| date | Tue, 23 Dec 2008 18:27:45 +0000 |
| parents | 8d3a60779c64 |
| children | 8fede7f6c559 |
| files | packages/devs/flash/synthv2/current/ChangeLog packages/devs/flash/synthv2/current/src/synth.c |
| diffstat | 2 files changed, 78 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/devs/flash/synthv2/current/ChangeLog +++ b/packages/devs/flash/synthv2/current/ChangeLog @@ -1,3 +1,8 @@ +2008-12-23 Simon Kallweit <simon.kallweit@intefo.ch> + + * src/synth.c: Implemented simulation of proper NOR flash writes. + General cleanup. + 2008-12-18 Simon Kallweit <simon.kallweit@intefo.ch> * src/synth.c: Fixed error check of mmap call.
--- a/packages/devs/flash/synthv2/current/src/synth.c +++ b/packages/devs/flash/synthv2/current/src/synth.c @@ -67,15 +67,16 @@ static int synth_flash_init(struct cyg_flash_dev *dev) { - struct cyg_flash_synth_priv *priv = (struct cyg_flash_synth_priv*)dev->priv; + struct cyg_flash_synth_priv *priv = + (struct cyg_flash_synth_priv *) dev->priv; cyg_flashaddr_t base; - int flags=CYG_HAL_SYS_MAP_SHARED; + int flags = CYG_HAL_SYS_MAP_SHARED; - priv->flashfd = - cyg_hal_sys_open(priv->filename, - CYG_HAL_SYS_O_RDWR, - CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG| - CYG_HAL_SYS_S_IRWXO); + priv->flashfd = cyg_hal_sys_open( + priv->filename, + CYG_HAL_SYS_O_RDWR, + CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO); + if (priv->flashfd == -ENOENT) { long w, bytesleft; char buf[128]; @@ -84,46 +85,43 @@ synth_flash_init(struct cyg_flash_dev *d priv->filename, CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO); - CYG_ASSERT( priv->flashfd >= 0, - "Opening of the file for the synth flash failed!"); - // fill with 0xff - memset( buf, 0xff, sizeof(buf) ); + CYG_ASSERT(priv->flashfd >= 0, + "Opening of the file for the synth flash failed!"); + + // Fill with 0xff + memset(buf, 0xff, sizeof(buf)); bytesleft = priv->block_size * priv->blocks + priv->boot_block_size * priv->boot_blocks; - while (bytesleft > 0) { int bytesneeded; - bytesneeded = bytesleft < sizeof(buf) ? - bytesleft : sizeof(buf); - - w = cyg_hal_sys_write( priv->flashfd, buf, - bytesneeded ); - CYG_ASSERT(w == bytesneeded, - "initialization of flash file failed"); + bytesneeded = bytesleft < sizeof(buf) ? bytesleft : sizeof(buf); + w = cyg_hal_sys_write(priv->flashfd, buf, bytesneeded); + CYG_ASSERT(w == bytesneeded, "initialization of flash file failed"); bytesleft -= bytesneeded; - } // while + } } - CYG_ASSERT( priv->flashfd >= 0, - "Opening of the file for the synth flash failed!"); - if ( priv->flashfd <= 0 ) { + + CYG_ASSERT(priv->flashfd >= 0, + "Opening of the file for the synth flash failed!"); + + if (priv->flashfd <= 0) return CYG_FLASH_ERR_HWR; - } - if (dev->start != 0) { + if (dev->start != 0) flags |= CYG_HAL_SYS_MAP_FIXED; - } - base = (cyg_flashaddr_t)cyg_hal_sys_mmap( - (void *)dev->start, + + base = (cyg_flashaddr_t) cyg_hal_sys_mmap( + (void *) dev->start, priv->blocks * priv->block_size + priv->boot_block_size * priv->boot_blocks, CYG_HAL_SYS_PROT_READ, flags, priv->flashfd, 0l); - CYG_ASSERT( base != -1, "mmap of flash file failed!" ); - if (base == -1) { + CYG_ASSERT(base != -1, "mmap of flash file failed!"); + if (base == -1) return CYG_FLASH_ERR_HWR; - } + dev->start = base; dev->end = base + (priv->blocks * priv->block_size) + (priv->boot_blocks * priv->boot_block_size) - 1; @@ -150,30 +148,26 @@ synth_flash_init(struct cyg_flash_dev *d return CYG_FLASH_ERR_OK; } -/* This helps speed up the erase. */ -static char empty[4096]; -static cyg_bool empty_inited = false; - // Return the size of the block which is at the given address. // __inline__ so that we know it will be in RAM, not ROM. static __inline__ size_t flash_block_size(struct cyg_flash_dev *dev, const cyg_flashaddr_t addr) { - int i; - size_t offset; + int i; + cyg_flashaddr_t offset; - - CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "Not inside device"); + CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "Not inside device"); - offset = addr - dev->start; - for (i=0; i < dev->num_block_infos; i++) { - if (offset < (dev->block_info[i].blocks * dev->block_info[i].block_size)) - return dev->block_info[i].block_size; - offset = offset - - (dev->block_info[i].blocks * dev->block_info[i].block_size); - } - CYG_FAIL("Programming error"); - return 0; + offset = addr - dev->start; + for (i=0; i < dev->num_block_infos; i++) { + if (offset < (dev->block_info[i].blocks * + dev->block_info[i].block_size)) + return dev->block_info[i].block_size; + offset = offset - + (dev->block_info[i].blocks * dev->block_info[i].block_size); + } + CYG_FAIL("Programming error"); + return 0; } static int @@ -181,14 +175,17 @@ synth_flash_erase_block(struct cyg_flash cyg_flashaddr_t block_base) { const struct cyg_flash_synth_priv *priv = dev->priv; - int offset = (int)block_base; + cyg_flashaddr_t offset = block_base; size_t remaining; int write_size; + + // This helps speed up the erasing + static cyg_uint8 empty[4096]; + static cyg_bool empty_inited; offset -= dev->start; - cyg_hal_sys_lseek(priv->flashfd, offset, - CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET); if (!empty_inited) { memset(empty, 0xff, sizeof(empty)); @@ -202,6 +199,7 @@ synth_flash_erase_block(struct cyg_flash cyg_hal_sys_write(priv->flashfd, empty, write_size); remaining -= write_size; } + return CYG_FLASH_ERR_OK; } @@ -211,22 +209,39 @@ synth_flash_program (struct cyg_flash_de const void* data, size_t len) { const struct cyg_flash_synth_priv *priv = dev->priv; - int offset = base; + cyg_flashaddr_t offset = base; + cyg_uint8 *buf = (cyg_uint8 *) data; + + // This helps speed up the programming + static cyg_uint8 tmp[4096]; + offset -= dev->start; - cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET); - cyg_hal_sys_write(priv->flashfd, data, len); - + while (len > 0) { + int i; + int write_size = MIN(len, sizeof(tmp)); + // Writing to NOR flash only sets bits from 1 to 0, not vice-versa + cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_read(priv->flashfd, tmp, write_size); + for (i = 0; i < write_size; i++) + tmp[i] = tmp[i] & buf[i]; + cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_write(priv->flashfd, tmp, write_size); + // Process next chunk + buf += write_size; + offset += write_size; + len -= write_size; + } + return CYG_FLASH_ERR_OK; } #define QUERY "Linux Synthetic Flash" static size_t -synth_flash_query(struct cyg_flash_dev *dev, void * data, - size_t len) +synth_flash_query(struct cyg_flash_dev *dev, void * data, size_t len) { - memcpy(data,QUERY,sizeof(QUERY)); + memcpy(data, QUERY, sizeof(QUERY)); return sizeof(QUERY); }
