app4.c 9.8 KB

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