BeRTOS
|
00001 00044 #include "kblock_ram.h" 00045 #include <string.h> 00046 00047 00048 static int kblockram_load(KBlock *b, block_idx_t index) 00049 { 00050 KBlockRam *r = KBLOCKRAM_CAST(b); 00051 memcpy(r->b.priv.buf, r->membuf + index * r->b.blk_size, r->b.blk_size); 00052 return 0; 00053 } 00054 00055 static int kblockram_store(struct KBlock *b, block_idx_t index) 00056 { 00057 KBlockRam *r = KBLOCKRAM_CAST(b); 00058 memcpy(r->membuf + index * r->b.blk_size, r->b.priv.buf, r->b.blk_size); 00059 return 0; 00060 } 00061 00062 static size_t kblockram_readBuf(struct KBlock *b, void *buf, size_t offset, size_t size) 00063 { 00064 KBlockRam *r = KBLOCKRAM_CAST(b); 00065 memcpy(buf, (uint8_t *)r->b.priv.buf + offset, size); 00066 return size; 00067 } 00068 00069 static size_t kblockram_readDirect(struct KBlock *b, block_idx_t index, void *buf, size_t offset, size_t size) 00070 { 00071 KBlockRam *r = KBLOCKRAM_CAST(b); 00072 memcpy(buf, r->membuf + index * r->b.blk_size + offset, size); 00073 return size; 00074 } 00075 00076 static size_t kblockram_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size) 00077 { 00078 KBlockRam *r = KBLOCKRAM_CAST(b); 00079 memcpy((uint8_t *)r->b.priv.buf + offset, buf, size); 00080 return size; 00081 } 00082 00083 static size_t kblockram_writeDirect(struct KBlock *b, block_idx_t index, const void *buf, size_t offset, size_t size) 00084 { 00085 KBlockRam *r = KBLOCKRAM_CAST(b); 00086 ASSERT(buf); 00087 ASSERT(index < b->blk_cnt); 00088 00089 memcpy(r->membuf + index * r->b.blk_size + offset, buf, size); 00090 return size; 00091 } 00092 00093 static int kblockram_dummy(UNUSED_ARG(struct KBlock *,b)) 00094 { 00095 return 0; 00096 } 00097 00098 static const KBlockVTable kblockram_hwbuffered_vt = 00099 { 00100 .readDirect = kblockram_readDirect, 00101 00102 .readBuf = kblockram_readBuf, 00103 .writeBuf = kblockram_writeBuf, 00104 .load = kblockram_load, 00105 .store = kblockram_store, 00106 00107 .error = kblockram_dummy, 00108 .clearerr = (kblock_clearerr_t)kblockram_dummy, 00109 .close = kblockram_dummy, 00110 }; 00111 00112 00113 static const KBlockVTable kblockram_swbuffered_vt = 00114 { 00115 .readDirect = kblockram_readDirect, 00116 .writeDirect = kblockram_writeDirect, 00117 00118 .readBuf = kblock_swReadBuf, 00119 .writeBuf = kblock_swWriteBuf, 00120 .load = kblock_swLoad, 00121 .store = kblock_swStore, 00122 00123 .error = kblockram_dummy, 00124 .clearerr = (kblock_clearerr_t)kblockram_dummy, 00125 .close = kblockram_dummy, 00126 }; 00127 00128 static const KBlockVTable kblockram_unbuffered_vt = 00129 { 00130 .readDirect = kblockram_readDirect, 00131 .writeDirect = kblockram_writeDirect, 00132 00133 .error = kblockram_dummy, 00134 .clearerr = (kblock_clearerr_t)kblockram_dummy, 00135 .close = kblockram_dummy, 00136 }; 00137 00138 void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size, bool buffered, bool hwbuffered) 00139 { 00140 ASSERT(buf); 00141 ASSERT(size); 00142 ASSERT(block_size); 00143 00144 memset(ram, 0, sizeof(*ram)); 00145 00146 DB(ram->b.priv.type = KBT_KBLOCKRAM); 00147 ram->b.blk_size = block_size; 00148 ram->b.priv.flags |= KB_PARTIAL_WRITE; 00149 00150 if (buffered) 00151 { 00152 ram->b.priv.flags |= KB_BUFFERED; 00153 ram->b.blk_cnt = (size / block_size) - 1; 00154 ram->b.priv.buf = buf; 00155 // First page used as page buffer 00156 ram->membuf = (uint8_t *)buf + block_size; 00157 00158 if (hwbuffered) 00159 ram->b.priv.vt = &kblockram_hwbuffered_vt; 00160 else 00161 ram->b.priv.vt = &kblockram_swbuffered_vt; 00162 00163 kblockram_load(&ram->b, 0); 00164 } 00165 else 00166 { 00167 ram->b.blk_cnt = (size / block_size); 00168 ram->membuf = (uint8_t *)buf; 00169 ram->b.priv.vt = &kblockram_unbuffered_vt; 00170 } 00171 }