Update preset.
[bertos.git] / bertos / io / kblock_ram.c
index 6707561dafe20b7b537c63e315ca67c9c90dcb2e..b936e90236d7b69f3c736fac2eca28ccc224c2f9 100644 (file)
  * invalidate any other reasons why the executable file might be covered by
  * the GNU General Public License.
  *
- * Copyright 2009 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
  *
  * -->
  *
  * \author Francesco Sacchi <batt@develer.com>
  *
- * \brief KBlock interface
+ * \brief KBlock interface on RAM memory
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * $WIZ$ module_name = "kfile_ram"
+ * $WIZ$ module_depends = "kblock"
  */
 
 
 static int kblockram_load(KBlock *b, block_idx_t index)
 {
        KBlockRam *r = KBLOCKRAM_CAST(b);
-       memcpy(r->b.priv.pagebuf, r->membuf + index * r->b.blk_size, r->b.blk_size);
+       memcpy(r->b.priv.buf, r->membuf + index * r->b.blk_size, r->b.blk_size);
        return 0;
 }
 
 static int kblockram_store(struct KBlock *b, block_idx_t index)
 {
        KBlockRam *r = KBLOCKRAM_CAST(b);
-       memcpy(r->membuf + index * r->b.blk_size, r->b.priv.pagebuf, r->b.blk_size);
+       memcpy(r->membuf + index * r->b.blk_size, r->b.priv.buf, r->b.blk_size);
        return 0;
 }
 
 static size_t kblockram_readBuf(struct KBlock *b, void *buf, size_t offset, size_t size)
 {
        KBlockRam *r = KBLOCKRAM_CAST(b);
-       memcpy(buf, (uint8_t *)r->b.priv.pagebuf + offset, size);
+       memcpy(buf, (uint8_t *)r->b.priv.buf + offset, size);
        return size;
 }
 
-static size_t kblockram_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size)
+static size_t kblockram_readDirect(struct KBlock *b, block_idx_t index, void *buf, size_t offset, size_t size)
 {
        KBlockRam *r = KBLOCKRAM_CAST(b);
-       memcpy((uint8_t *)r->b.priv.pagebuf + offset, buf, size);
+       memcpy(buf, r->membuf + index * r->b.blk_size + offset, size);
        return size;
 }
 
-static void * kblockram_map(struct KBlock *b, size_t offset, UNUSED_ARG(size_t, size))
+static size_t kblockram_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size)
 {
-       return (uint8_t *)b->priv.pagebuf + offset;
+       KBlockRam *r = KBLOCKRAM_CAST(b);
+       memcpy((uint8_t *)r->b.priv.buf + offset, buf, size);
+       return size;
 }
 
-
-static int kblockram_unmap(UNUSED_ARG(struct KBlock *, b), UNUSED_ARG(size_t, offset), UNUSED_ARG(size_t, size))
+static size_t kblockram_writeDirect(struct KBlock *b, block_idx_t index, const void *buf, size_t offset, size_t size)
 {
-       return 0;
-}
+       KBlockRam *r = KBLOCKRAM_CAST(b);
+       ASSERT(buf);
+       ASSERT(index < b->blk_cnt);
 
-static int kblockram_error(struct KBlock *b)
-{
-       return b->priv.flags;
+       memcpy(r->membuf + index * r->b.blk_size + offset, buf, size);
+       return size;
 }
 
 static int kblockram_dummy(UNUSED_ARG(struct KBlock *,b))
@@ -89,33 +95,77 @@ static int kblockram_dummy(UNUSED_ARG(struct KBlock *,b))
        return 0;
 }
 
-static KBlockVTable kblockram_vt =
+static const KBlockVTable kblockram_hwbuffered_vt =
 {
+       .readDirect = kblockram_readDirect,
+
        .readBuf = kblockram_readBuf,
        .writeBuf = kblockram_writeBuf,
        .load = kblockram_load,
        .store = kblockram_store,
-       .map = kblockram_map,
-       .unmap = kblockram_unmap,
-       .error = kblockram_error,
-       .clearerr = kblockram_dummy,
+
+       .error = kblockram_dummy,
+       .clearerr = (kblock_clearerr_t)kblockram_dummy,
        .close = kblockram_dummy,
 };
 
-void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size)
+
+static const KBlockVTable kblockram_swbuffered_vt =
+{
+       .readDirect = kblockram_readDirect,
+       .writeDirect = kblockram_writeDirect,
+
+       .readBuf = kblock_swReadBuf,
+       .writeBuf = kblock_swWriteBuf,
+       .load = kblock_swLoad,
+       .store = kblock_swStore,
+
+       .error = kblockram_dummy,
+       .clearerr = (kblock_clearerr_t)kblockram_dummy,
+       .close = kblockram_dummy,
+};
+
+static const KBlockVTable kblockram_unbuffered_vt =
+{
+       .readDirect = kblockram_readDirect,
+       .writeDirect = kblockram_writeDirect,
+
+       .error = kblockram_dummy,
+       .clearerr = (kblock_clearerr_t)kblockram_dummy,
+       .close = kblockram_dummy,
+};
+
+void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size, bool buffered, bool hwbuffered)
 {
        ASSERT(buf);
        ASSERT(size);
        ASSERT(block_size);
 
        memset(ram, 0, sizeof(*ram));
-       
-       // First page used as page buffer
-       ram->b.blk_cnt = (size / block_size) - 1;
-       ram->b.priv.pagebuf = buf;
-       ram->b.priv.pagebuf_size = block_size;
-       
-       ram->membuf = (uint8_t *)buf + block_size;
-       ram->b.blk_size = block_size;   
-       ram->b.vt = &kblockram_vt;
+
+       DB(ram->b.priv.type = KBT_KBLOCKRAM);
+       ram->b.blk_size = block_size;
+       ram->b.priv.flags |= KB_PARTIAL_WRITE;
+
+       if (buffered)
+       {
+               ram->b.priv.flags |= KB_BUFFERED;
+               ram->b.blk_cnt = (size / block_size) - 1;
+               ram->b.priv.buf = buf;
+               // First page used as page buffer
+               ram->membuf = (uint8_t *)buf + block_size;
+
+               if (hwbuffered)
+                       ram->b.priv.vt = &kblockram_hwbuffered_vt;
+               else
+                       ram->b.priv.vt = &kblockram_swbuffered_vt;
+
+               kblockram_load(&ram->b, 0);
+       }
+       else
+       {
+               ram->b.blk_cnt = (size / block_size);
+               ram->membuf = (uint8_t *)buf;
+               ram->b.priv.vt = &kblockram_unbuffered_vt;
+       }
 }