app4.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*----------------------------------------------------------------------/
  2. / Low level disk I/O module function checker
  3. /-----------------------------------------------------------------------/
  4. / WARNING: The data on the target drive will be lost!
  5. */
  6. #ifdef PRINTF_STDLIB
  7. #include <stdio.h>
  8. #endif
  9. #ifdef PRINTF_CUSTOM
  10. #include "tinystdio.h"
  11. #endif
  12. #include <string.h>
  13. #include "ff.h"
  14. #include "diskio.h"
  15. static
  16. DWORD pn (
  17. DWORD pns
  18. )
  19. {
  20. static DWORD lfsr;
  21. UINT n;
  22. if (pns) {
  23. lfsr = pns;
  24. for (n = 0; n < 32; n++) pn(0);
  25. }
  26. if (lfsr & 1) {
  27. lfsr >>= 1;
  28. lfsr ^= 0x80200003;
  29. } else {
  30. lfsr >>= 1;
  31. }
  32. return lfsr;
  33. }
  34. int test_diskio (
  35. BYTE pdrv, /* Physical drive number to be checked (all data on the drive will be lost) */
  36. UINT ncyc, /* Number of test cycles */
  37. DWORD* buff, /* Pointer to the working buffer */
  38. UINT sz_buff /* Size of the working buffer in unit of byte */
  39. )
  40. {
  41. UINT n, cc, ns;
  42. DWORD sz_drv, lba, lba2, pns = 1;
  43. WORD sz_sect, sz_eblk;
  44. BYTE *pbuff = (BYTE*)buff;
  45. DSTATUS ds;
  46. DRESULT dr;
  47. printf("test_diskio(%u, %u, 0x%08X, 0x%08X)\n", pdrv, ncyc, (UINT)buff, sz_buff);
  48. if (sz_buff < _MAX_SS + 4) {
  49. printf("Insufficient work area to test.\n");
  50. return 1;
  51. }
  52. for (cc = 1; cc <= ncyc; cc++) {
  53. printf("**** Test cycle %u of %u start ****\n", cc, ncyc);
  54. /* Initialization */
  55. printf(" disk_initalize(%u)", pdrv);
  56. ds = disk_initialize(pdrv);
  57. if (ds & STA_NOINIT) {
  58. printf(" - failed.\n");
  59. return 2;
  60. } else {
  61. printf(" - ok.\n");
  62. }
  63. /* Get drive size */
  64. printf("**** Get drive size ****\n");
  65. printf(" disk_ioctl(%u, GET_SECTOR_COUNT, 0x%08X)", pdrv, (UINT)&sz_drv);
  66. sz_drv = 0;
  67. dr = disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_drv);
  68. if (dr == RES_OK) {
  69. printf(" - ok.\n");
  70. } else {
  71. printf(" - failed.\n");
  72. return 3;
  73. }
  74. if (sz_drv < 128) {
  75. printf("Failed: Insufficient drive size to test.\n");
  76. return 4;
  77. }
  78. printf(" Number of sectors on the drive %u is %lu.\n", pdrv, sz_drv);
  79. #if _MAX_SS != _MIN_SS
  80. /* Get sector size */
  81. printf("**** Get sector size ****\n");
  82. printf(" disk_ioctl(%u, GET_SECTOR_SIZE, 0x%X)", pdrv, (UINT)&sz_sect);
  83. sz_sect = 0;
  84. dr = disk_ioctl(pdrv, GET_SECTOR_SIZE, &sz_sect);
  85. if (dr == RES_OK) {
  86. printf(" - ok.\n");
  87. } else {
  88. printf(" - failed.\n");
  89. return 5;
  90. }
  91. printf(" Size of sector is %u bytes.\n", sz_sect);
  92. #else
  93. sz_sect = _MAX_SS;
  94. #endif
  95. /* Get erase block size */
  96. printf("**** Get block size ****\n");
  97. printf(" disk_ioctl(%u, GET_BLOCK_SIZE, 0x%X)", pdrv, (UINT)&sz_eblk);
  98. sz_eblk = 0;
  99. dr = disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_eblk);
  100. if (dr == RES_OK) {
  101. printf(" - ok.\n");
  102. } else {
  103. printf(" - failed.\n");
  104. }
  105. if (dr == RES_OK || sz_eblk >= 2) {
  106. printf(" Size of the erase block is %u sectors.\n", sz_eblk);
  107. } else {
  108. printf(" Size of the erase block is unknown.\n");
  109. }
  110. /* Single sector write test */
  111. printf("**** Single sector write test 1 ****\n");
  112. lba = 0;
  113. for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n] = (BYTE)pn(0);
  114. printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
  115. dr = disk_write(pdrv, pbuff, lba, 1);
  116. if (dr == RES_OK) {
  117. printf(" - ok.\n");
  118. } else {
  119. printf(" - failed.\n");
  120. return 6;
  121. }
  122. printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
  123. dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
  124. if (dr == RES_OK) {
  125. printf(" - ok.\n");
  126. } else {
  127. printf(" - failed.\n");
  128. return 7;
  129. }
  130. memset(pbuff, 0, sz_sect);
  131. printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
  132. dr = disk_read(pdrv, pbuff, lba, 1);
  133. if (dr == RES_OK) {
  134. printf(" - ok.\n");
  135. } else {
  136. printf(" - failed.\n");
  137. return 8;
  138. }
  139. for (n = 0, pn(pns); n < sz_sect && pbuff[n] == (BYTE)pn(0); n++) ;
  140. if (n == sz_sect) {
  141. printf(" Data matched.\n");
  142. } else {
  143. printf("Failed: Read data differs from the data written.\n");
  144. return 10;
  145. }
  146. pns++;
  147. /* Multiple sector write test */
  148. printf("**** Multiple sector write test ****\n");
  149. lba = 1; ns = sz_buff / sz_sect;
  150. if (ns > 4) ns = 4;
  151. for (n = 0, pn(pns); n < (UINT)(sz_sect * ns); n++) pbuff[n] = (BYTE)pn(0);
  152. printf(" disk_write(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);
  153. dr = disk_write(pdrv, pbuff, lba, ns);
  154. if (dr == RES_OK) {
  155. printf(" - ok.\n");
  156. } else {
  157. printf(" - failed.\n");
  158. return 11;
  159. }
  160. printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
  161. dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
  162. if (dr == RES_OK) {
  163. printf(" - ok.\n");
  164. } else {
  165. printf(" - failed.\n");
  166. return 12;
  167. }
  168. memset(pbuff, 0, sz_sect * ns);
  169. printf(" disk_read(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);
  170. dr = disk_read(pdrv, pbuff, lba, ns);
  171. if (dr == RES_OK) {
  172. printf(" - ok.\n");
  173. } else {
  174. printf(" - failed.\n");
  175. return 13;
  176. }
  177. for (n = 0, pn(pns); n < (UINT)(sz_sect * ns) && pbuff[n] == (BYTE)pn(0); n++) ;
  178. if (n == (UINT)(sz_sect * ns)) {
  179. printf(" Data matched.\n");
  180. } else {
  181. printf("Failed: Read data differs from the data written.\n");
  182. return 14;
  183. }
  184. pns++;
  185. /* Single sector write test (misaligned memory address) */
  186. printf("**** Single sector write test 2 ****\n");
  187. lba = 5;
  188. for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n+3] = (BYTE)pn(0);
  189. printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+3), lba);
  190. dr = disk_write(pdrv, pbuff+3, lba, 1);
  191. if (dr == RES_OK) {
  192. printf(" - ok.\n");
  193. } else {
  194. printf(" - failed.\n");
  195. return 15;
  196. }
  197. printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
  198. dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
  199. if (dr == RES_OK) {
  200. printf(" - ok.\n");
  201. } else {
  202. printf(" - failed.\n");
  203. return 16;
  204. }
  205. memset(pbuff+5, 0, sz_sect);
  206. printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+5), lba);
  207. dr = disk_read(pdrv, pbuff+5, lba, 1);
  208. if (dr == RES_OK) {
  209. printf(" - ok.\n");
  210. } else {
  211. printf(" - failed.\n");
  212. return 17;
  213. }
  214. for (n = 0, pn(pns); n < sz_sect && pbuff[n+5] == (BYTE)pn(0); n++) ;
  215. if (n == sz_sect) {
  216. printf(" Data matched.\n");
  217. } else {
  218. printf("Failed: Read data differs from the data written.\n");
  219. return 18;
  220. }
  221. pns++;
  222. /* 4GB barrier test */
  223. printf("**** 4GB barrier test ****\n");
  224. if (sz_drv >= 128 + 0x80000000 / (sz_sect / 2)) {
  225. lba = 6; lba2 = lba + 0x80000000 / (sz_sect / 2);
  226. for (n = 0, pn(pns); n < (UINT)(sz_sect * 2); n++) pbuff[n] = (BYTE)pn(0);
  227. printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
  228. dr = disk_write(pdrv, pbuff, lba, 1);
  229. if (dr == RES_OK) {
  230. printf(" - ok.\n");
  231. } else {
  232. printf(" - failed.\n");
  233. return 19;
  234. }
  235. printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);
  236. dr = disk_write(pdrv, pbuff+sz_sect, lba2, 1);
  237. if (dr == RES_OK) {
  238. printf(" - ok.\n");
  239. } else {
  240. printf(" - failed.\n");
  241. return 20;
  242. }
  243. printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
  244. dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
  245. if (dr == RES_OK) {
  246. printf(" - ok.\n");
  247. } else {
  248. printf(" - failed.\n");
  249. return 21;
  250. }
  251. memset(pbuff, 0, sz_sect * 2);
  252. printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
  253. dr = disk_read(pdrv, pbuff, lba, 1);
  254. if (dr == RES_OK) {
  255. printf(" - ok.\n");
  256. } else {
  257. printf(" - failed.\n");
  258. return 22;
  259. }
  260. printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);
  261. dr = disk_read(pdrv, pbuff+sz_sect, lba2, 1);
  262. if (dr == RES_OK) {
  263. printf(" - ok.\n");
  264. } else {
  265. printf(" - failed.\n");
  266. return 23;
  267. }
  268. for (n = 0, pn(pns); pbuff[n] == (BYTE)pn(0) && n < (UINT)(sz_sect * 2); n++) ;
  269. if (n == (UINT)(sz_sect * 2)) {
  270. printf(" Data matched.\n");
  271. } else {
  272. printf("Failed: Read data differs from the data written.\n");
  273. return 24;
  274. }
  275. } else {
  276. printf(" Test skipped.\n");
  277. }
  278. pns++;
  279. printf("**** Test cycle %u of %u completed ****\n\n", cc, ncyc);
  280. }
  281. return 0;
  282. }
  283. int main (int argc, char* argv[])
  284. {
  285. int rc;
  286. DWORD buff[512]; /* 2048 byte working buffer */
  287. /* Check function/compatibility of the physical drive #0 */
  288. rc = test_diskio(0, 1, buff, sizeof buff);
  289. if (rc) {
  290. printf("Sorry the function/compatibility test failed.\nFatFs will not work on this disk driver.\n");
  291. } else {
  292. printf("Congratulations! The disk I/O layer works well.\n");
  293. }
  294. return rc;
  295. }