lib_ringfs_func.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Copyright © 2014 Kosma Moczek <kosma@cloudyourcar.com>
  3. * This program is free software. It comes without any warranty, to the extent
  4. * permitted by applicable law. You can redistribute it and/or modify it under
  5. * the terms of the Do What The Fuck You Want To Public License, Version 2, as
  6. * published by Sam Hocevar. See the COPYING file for more details.
  7. */
  8. #include <stdio.h>
  9. #include "lib_ringfs.h"
  10. #include "lib_ringfs_func.h"
  11. #include "lib_ringfs_ram.h"
  12. #include "lib_ringfs_w25q.h"
  13. #include "func_spi_w25qxx.h"
  14. #include "obj_hal_w25qxx.h"
  15. #include "obj_soft_w25qxx.h"
  16. /* Flash implementation & ops. */
  17. /* Data record format. */
  18. struct log_entry {
  19. int level;
  20. char message[16];
  21. };
  22. #define LOG_ENTRY_VERSION 1
  23. struct ringfs rfs_obj;
  24. int lib_ringfs_push(void *object, size_t size)
  25. {
  26. if(ringfs_append(&rfs_obj, object) == 0)
  27. {
  28. ringfs_end(&rfs_obj);
  29. return size;
  30. }
  31. return 0;
  32. }
  33. int lib_ringfs_pop(void *object, size_t size)
  34. {
  35. if(ringfs_del(&rfs_obj, (void *)object) == 0)
  36. {
  37. return size;
  38. }
  39. return 0;
  40. }
  41. uint32_t lib_ringfs_obj_cnt_estimate(void)
  42. {
  43. return (uint32_t)ringfs_count_estimate(&rfs_obj);
  44. }
  45. uint32_t lib_ringfs_obj_cnt_exact(void)
  46. {
  47. return (uint32_t)ringfs_count_exact(&rfs_obj);
  48. }
  49. /* Let's roll! */
  50. int lib_ringfs_init(int object_size)
  51. {
  52. /* Initialize your Flash driver before using the filesystem. */
  53. #if USE_LIB_RINGFS_RAM==1
  54. init_flash_driver_ram();
  55. /* Always call ringfs_init first. */
  56. ringfs_init(&rfs_obj, &rfs_disk_ram, LOG_ENTRY_VERSION, object_size);
  57. #elif USE_LIB_RINGFS_W25Q==1
  58. init_flash_driver_w25q();
  59. /* Always call ringfs_init first. */
  60. ringfs_init(&rfs_obj, &rfs_disk_w25q, LOG_ENTRY_VERSION, object_size);
  61. #endif
  62. /* Scan and/or format before any data operations. */
  63. printf("# scanning for filesystem...\n");
  64. if (ringfs_scan(&rfs_obj) == 0) {
  65. printf("# found existing filesystem, usage: %d/%d\n",
  66. ringfs_count_estimate(&rfs_obj),
  67. ringfs_capacity(&rfs_obj));
  68. } else {
  69. printf("# no valid filesystem found, formatting.\n");
  70. ringfs_format(&rfs_obj);
  71. }
  72. //把光标位置移动到写入位置;
  73. ringfs_end(&rfs_obj);
  74. return 0;
  75. }
  76. int lib_ringfs_log_test(void)
  77. {
  78. static uint32_t obj_idx = 0;
  79. int obj_cnt = ringfs_count_exact(&rfs_obj);
  80. printf("\n\n\n# ringfs has %d objects\n", obj_cnt);
  81. /* Append data using ringfs_append. Oldest data is removed as needed. */
  82. printf("# inserting some objects\n");
  83. ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "foo" });
  84. ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "bar" });
  85. ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "baz" });
  86. ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "xyzzy" });
  87. ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "test" });
  88. ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "hello" });
  89. /* Objects are retrieved using ringfs_fetch. They are not physically removed
  90. * until you call ringfs_discard. This is useful, for example, when transmitting
  91. * queued objects over the network: you don't physically remove the objects
  92. * from the ring buffer until you receive an ACK. */
  93. printf("# reading 2 objects\n");
  94. for (int i=0; i<2; i++) {
  95. struct log_entry entry;
  96. RFS_ASSERT(ringfs_fetch(&rfs_obj, &entry) == 0);
  97. printf("## level=%d message=%.16s\n", entry.level, entry.message);
  98. }
  99. if(0)
  100. {
  101. printf("# discarding read objects\n");
  102. ringfs_discard(&rfs_obj);
  103. }
  104. printf("# rewinding read head back\n");
  105. ringfs_rewind(&rfs_obj);
  106. /* If you decide you can't remove the objects yet, just call ringfs_rewind() and
  107. * they will be available again for subsequent reads. */
  108. printf("# reading 2 objects\n");
  109. for (int i=0; i<2; i++) {
  110. struct log_entry entry;
  111. if(ringfs_fetch(&rfs_obj, &entry) == 0)
  112. {
  113. printf("## level=%d message=%.16s\n", entry.level, entry.message);
  114. }
  115. }
  116. printf("# popping 2 objects\n");
  117. for (int i=0; i<2; i++) {
  118. struct log_entry entry;
  119. RFS_ASSERT(ringfs_pop(&rfs_obj, &entry) == 0);
  120. printf("## level=%d message=%.16s\n", entry.level, entry.message);
  121. }
  122. /* ...and here they are again. */
  123. printf("# reading 2 objects\n");
  124. for (int i=0; i<2; i++) {
  125. struct log_entry entry;
  126. if(ringfs_fetch(&rfs_obj, &entry) == 0)
  127. {
  128. printf("## level=%d message=%.16s\n", entry.level, entry.message);
  129. }
  130. }
  131. return 0;
  132. }
  133. void lib_ringfs_test(void const *argument)
  134. {
  135. //UNUSED(argument);
  136. lib_ringfs_init(sizeof(struct log_entry));
  137. while(1)
  138. {
  139. lib_ringfs_log_test();
  140. };
  141. //return 0;
  142. }
  143. /* vim: set ts=4 sw=4 et: */