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