X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=kern%2Fkfile.c;h=1ec3266488e4970d1ec611c4d8e6594d4cd8a5b1;hb=2535cb94ec2183791128f8bbd109ca69a960cf78;hp=ba7851013ce6acc6ebb6d57ee3a9b7d9bfe7bd80;hpb=8cc951f12053c29db61a938869ac525d99f437d4;p=bertos.git diff --git a/kern/kfile.c b/kern/kfile.c index ba785101..1ec32664 100644 --- a/kern/kfile.c +++ b/kern/kfile.c @@ -31,8 +31,7 @@ * --> * * \brief Virtual KFile I/O interface. - * This module implement a standard fd.seek and a kfile - * test function. + * This module implements some generic I/O interfaces for kfile. * * \version $Id$ * \author Francesco Sacchi @@ -40,263 +39,183 @@ * */ -#include -#include +#include "kfile.h" +#include + +#include +#include #include -#include +/* + * Sanity check for config parameters required by this module. + */ +#if !defined(CONFIG_KFILE_GETS) || ((CONFIG_KFILE_GETS != 0) && CONFIG_KFILE_GETS != 1) + #error CONFIG_KFILE_GETS must be set to either 0 or 1 in appconfig.h +#endif +#if !defined(CONFIG_PRINTF) + #error CONFIG_PRINTF missing in appconfig.h +#endif + /** - * Move \a fd file seek position of \a offset bytes - * from current position. - * This is a generic implementation of seek function, you should redefine - * it in your local module. + * Generic putc() implementation using \a fd->write. */ -int32_t kfile_seek(struct _KFile *fd, kfile_off_t offset, KSeekMode whence) +int kfile_putc(int _c, struct KFile *fd) { - uint32_t seek_pos; - - switch(whence) - { - - case KSM_SEEK_SET: - seek_pos = 0; - break; - case KSM_SEEK_END: - seek_pos = fd->size - 1; - break; - case KSM_SEEK_CUR: - seek_pos = fd->seek_pos; - break; - default: - ASSERT(0); - return -1; - break; - - } + unsigned char c = (unsigned char)_c; - /* Bound check */ - if (seek_pos + offset > fd->size) - { - ASSERT(0); - return -1; - } - - fd->seek_pos = seek_pos + offset; - kprintf("Flash seek to [%lu]\n", fd->seek_pos); - - return fd->seek_pos; + if (kfile_write(fd, &c, sizeof(c)) == sizeof(c)) + return (int)((unsigned char)_c); + else + return EOF; } -#if CONFIG_TEST - /** - * Program memory read/write subtest. - * Try to write/read in the same \a f file location \a _size bytes. - * \return true if all is ok, false otherwise - * \note Restore file position at exit (if no error) - * \note Test buffer \a buf must be filled with - * the following statement: - *
- * buf[i] = i & 0xff
- * 
+ * Generic getc() implementation using \a fd->read. */ -static bool kfile_rwTest(KFile *f, uint8_t *buf, size_t _size) +int kfile_getc(struct KFile *fd) { - int32_t size = _size; - - // Write test buffer - if (f->write(f, buf, size) != size) - return false; - f->seek(f, -size, KSM_SEEK_CUR); - - // Reset test buffer - memset(buf, 0, size); + unsigned char c; - // Read flash in test buffer - if (f->read(f, buf, size) != size) - return false; - f->seek(f, -size, KSM_SEEK_CUR); - - // Check test result - for (size_t i = 0; i < size; i++) - if (buf[i] != (i & 0xff)) - return false; - - return true; + if (kfile_read(fd, &c, sizeof(c)) == sizeof(c)) + return (int)((unsigned char)c); + else + return EOF; } +#if CONFIG_PRINTF /** - * Test for program memory read/write. - * This function write and read \p test_buf long \p _size - * on \p fd handler. If you want not overwrite exist data - * you should pass an \p save_buf where test store exist data, - * otherwise su must pass NULL. - * - * \note some device (like flash memeory) not allow write on - * existing data, and so this test use ASSERT macro to warn you if - * you are writing on same fd.seek_pos. - * + * Formatted write. */ -bool kfile_test(uint8_t *test_buf, size_t _size , uint8_t *save_buf, size_t save_buf_size) +int kfile_printf(struct KFile *fd, const char *format, ...) { - KFile fd; - int32_t size = _size; - - /* - * Part of test buf size that you would write. - * This var is useded in test 3 to check fd.write - * when write outside size limit. Normaly we want - * perform a write until is space to write, otherwise - * we return. - */ - int32_t len = size/2; - - /* - * Open fd handler - */ - fd.open(&fd, NULL, 0); - kprintf("Opened fd handler..\n"); - - /* - * If necessary, user could save content, - * for later restore. - */ - if (save_buf != NULL) - { - fd.read(&fd, save_buf, save_buf_size); - kprintf("Saved content..form [%lu] to [%lu]\n", fd.seek_pos, fd.seek_pos + save_buf_size); - } + va_list ap; + int len; - /* TEST 1 BEGIN. */ - kprintf("Test 1: write from pos 0 to [%lu]\n", fd.size); + va_start(ap, format); + len = _formatted_write(format, (void (*)(char, void *))kfile_putc, fd, ap); + va_end(ap); - /* - * Seek to addr 0 - */ - if (fd.seek(&fd, 0, KSM_SEEK_SET) != 0) - goto kfile_test_end; - - kprintf("Seek to [%lu], expected[0]\n", fd.seek_pos); - - /* - * Test flash read/write to address 0..size - */ - if (!kfile_rwTest(&fd, test_buf, size)) - goto kfile_test_end; - - kprintf("Test 1: ok!\n"); + return len; +} +#endif /* CONFIG_PRINTF */ - /* - * Restore previous read content - */ - if (save_buf != NULL) +/** + * Write a string to kfile \a fd. + * \return 0 if OK, EOF in case of error. + */ +int kfile_print(struct KFile *fd, const char *s) +{ + while (*s) { - fd.seek(&fd, 0, KSM_SEEK_SET); - - if (fd.write(&fd, save_buf, save_buf_size) != size) - goto kfile_test_end; - - kprintf("Restore content..form [%lu] to [%lu]\n", fd.seek_pos, fd.seek_pos + save_buf_size); + if (kfile_putc(*s++, fd) == EOF) + return EOF; } - /* TEST 1 END. */ - - /* TEST 2 BEGIN. */ - kprintf("Test 2: write from pos [%lu] to [%lu]\n", fd.size/2 , size); - - /* - * Go to half test size. - */ - fd.seek(&fd, (fd.size/ 2), KSM_SEEK_SET); - - kprintf("Seek to [%lu], expected[%lu]\n", fd.seek_pos, fd.size/2); + return 0; +} - /* - * If necessary, user could save content, - * for later restore. - */ - if (save_buf != NULL) - { - fd.read(&fd, save_buf, save_buf_size); - fd.seek(&fd, -size, KSM_SEEK_CUR); - kprintf("Saved content..form [%lu] to [%lu]\n", fd.seek_pos, fd.seek_pos + save_buf_size); - } +#if CONFIG_KFILE_GETS +/** + * Read a line long at most as size and put it + * in buf. + * \return number of chars read or EOF in case + * of error. + */ +int kfile_gets(struct KFile *fd, char *buf, int size) +{ + return kfile_gets_echo(fd, buf, size, false); +} - /* - * Test flash read/write to address FLASHEND/2 ... FLASHEND/2 + size - */ - if (!kfile_rwTest(&fd, test_buf, size)) - goto kfile_test_end; - kprintf("Test 2: ok!\n"); +/** + * Read a line long at most as size and put it + * in buf, with optional echo. + * + * \return number of chars read, or EOF in case + * of error. + */ +int kfile_gets_echo(struct KFile *fd, char *buf, int size, bool echo) +{ + int i = 0; + int c; - /* - * Restore previous read content - */ - if (save_buf != NULL) + for (;;) { - fd.seek(&fd, -size, KSM_SEEK_CUR); - - if (fd.write(&fd, save_buf, save_buf_size) != size) - goto kfile_test_end; - - kprintf("Restore content..form [%lu] to [%lu]\n", fd.seek_pos, fd.seek_pos + save_buf_size); + if ((c = kfile_getc(fd)) == EOF) + { + buf[i] = '\0'; + return -1; + } + + /* FIXME */ + if (c == '\r' || c == '\n' || i >= size-1) + { + buf[i] = '\0'; + if (echo) + kfile_print(fd, "\r\n"); + break; + } + buf[i++] = c; + if (echo) + kfile_putc(c, fd); } - /* TEST 2 END. */ + return i; +} +#endif /* !CONFIG_KFILE_GETS */ - /* TEST 3 BEGIN. */ - kprintf("Test 3: write outside of fd.size limit [%lu]\n", fd.size); - /* - * Go to the Flash end - */ - fd.seek(&fd, -len, KSM_SEEK_END); - kprintf("Seek to [%lu], expected[%lu]\n", fd.seek_pos, fd.size - len); +/** + * Move \a fd file seek position of \a offset bytes from \a whence. + * + * This is a generic implementation of seek function, you can redefine + * it in your local module if needed. + */ +kfile_off_t kfile_genericSeek(struct KFile *fd, kfile_off_t offset, KSeekMode whence) +{ + uint32_t seek_pos; - /* - * If necessary, user could save content, - * for later restore. - */ - if (save_buf != NULL) + switch (whence) { - ASSERT(len > save_buf_size); - fd.read(&fd, save_buf, len); - fd.seek(&fd, -len, KSM_SEEK_CUR); - kprintf("Saved content..form [%lu] to [%lu]\n", fd.seek_pos, fd.seek_pos + len); + case KSM_SEEK_SET: + seek_pos = 0; + break; + case KSM_SEEK_END: + seek_pos = fd->size; + break; + case KSM_SEEK_CUR: + seek_pos = fd->seek_pos; + break; + default: + ASSERT(0); + return EOF; + break; } - /* - * Test flash read/write to address (FLASHEND - size) ... FLASHEND - */ - if (!kfile_rwTest(&fd, test_buf, size)) - goto kfile_test_end; - - kprintf("Test 3: ok !\n"); - - /* - * Restore previous read content - */ - if (save_buf != NULL) + /* Bound check */ + if (seek_pos + offset > fd->size) { - fd.seek(&fd, -len, KSM_SEEK_END); - - if (fd.write(&fd, save_buf, len) != len) - goto kfile_test_end; - - kprintf("Restore content..form [%lu] to [%lu]\n", fd.seek_pos, fd.seek_pos + len); + ASSERT(0); + return EOF; } - /* TEST 3 END. */ + fd->seek_pos = seek_pos + offset; - fd.close(&fd); - return true; + return fd->seek_pos; +} -kfile_test_end: - fd.close(&fd); - return false; +/** + * Reopen file \a fd. + * This is a generic implementation that only flush file + * and reset seek_pos to 0. + */ +struct KFile * kfile_genericReopen(struct KFile *fd) +{ + kfile_flush(fd); + kfile_seek(fd, 0, KSM_SEEK_SET); + return fd; } -#endif /* CONFIG_TEST */ +