device_test.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * File : device_test.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2011, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://openlab.rt-thread.com/license/LICENSE.
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2011-01-01 aozima the first version
  13. */
  14. #include <rtthread.h>
  15. static rt_err_t _block_device_test(rt_device_t device)
  16. {
  17. rt_err_t result;
  18. struct rt_device_blk_geometry geometry;
  19. rt_uint8_t * read_buffer = RT_NULL;
  20. rt_uint8_t * write_buffer = RT_NULL;
  21. rt_kprintf("\r\n");
  22. if( (device->flag & RT_DEVICE_FLAG_RDWR) == RT_DEVICE_FLAG_RDWR )
  23. {
  24. // device can read and write.
  25. // step 1: open device
  26. result = device->open(device,RT_DEVICE_FLAG_RDWR);
  27. if( result == RT_EOK )
  28. {
  29. device->open_flag |= RT_DEVICE_OFLAG_RDWR | RT_DEVICE_OFLAG_OPEN;
  30. }
  31. else
  32. {
  33. return result;
  34. }
  35. // step 2: get device info
  36. rt_memset(&geometry, 0, sizeof(geometry));
  37. result = rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
  38. if( result != RT_EOK )
  39. {
  40. rt_kprintf("device : %s cmd RT_DEVICE_CTRL_BLK_GETGEOME failed.\r\n");
  41. return result;
  42. }
  43. rt_kprintf("device info:\r\n");
  44. rt_kprintf("sector size : %d byte\r\n",geometry.bytes_per_sector);
  45. rt_kprintf("sector count : %d \r\n",geometry.sector_count);
  46. rt_kprintf("block size : %d byte\r\n",geometry.block_size);
  47. rt_kprintf("\r\n");
  48. read_buffer = rt_malloc(geometry.bytes_per_sector);
  49. if( read_buffer == RT_NULL )
  50. {
  51. rt_kprintf("no memory for read_buffer!\r\n");
  52. goto __return;
  53. }
  54. write_buffer = rt_malloc(geometry.bytes_per_sector);
  55. if( write_buffer == RT_NULL )
  56. {
  57. rt_kprintf("no memory for write_buffer!\r\n");
  58. goto __return;
  59. }
  60. //step 3: I/O R/W test
  61. {
  62. rt_uint32_t i,err_count,sector_no;
  63. rt_uint8_t * data_point;
  64. // the first sector
  65. sector_no = 0;
  66. data_point = write_buffer;
  67. *data_point++ = (rt_uint8_t)sector_no;
  68. for(i=1; i<geometry.bytes_per_sector; i++)
  69. {
  70. *data_point++ = (rt_uint8_t)i;
  71. }
  72. i = device->write(device,sector_no,write_buffer,1);
  73. if( i != 1 )
  74. {
  75. rt_kprintf("write device :%s ",device->parent.name);
  76. rt_kprintf("the first sector failed.\r\n");
  77. goto __return;
  78. }
  79. i = device->read(device,sector_no,read_buffer,1);
  80. if( i != 1 )
  81. {
  82. rt_kprintf("read device :%s ",device->parent.name);
  83. rt_kprintf("the first sector failed.\r\n");
  84. goto __return;
  85. }
  86. err_count = 0;
  87. data_point = read_buffer;
  88. if( (*data_point++) != (rt_uint8_t)sector_no)
  89. {
  90. err_count++;
  91. }
  92. for(i=1; i<geometry.bytes_per_sector; i++)
  93. {
  94. if( (*data_point++) != (rt_uint8_t)i )
  95. {
  96. err_count++;
  97. }
  98. }
  99. if( err_count > 0 )
  100. {
  101. rt_kprintf("verify device :%s ",device->parent.name);
  102. rt_kprintf("the first sector failed.\r\n");
  103. goto __return;
  104. }
  105. // the second sector
  106. sector_no = 1;
  107. data_point = write_buffer;
  108. *data_point++ = (rt_uint8_t)sector_no;
  109. for(i=1; i<geometry.bytes_per_sector; i++)
  110. {
  111. *data_point++ = (rt_uint8_t)i;
  112. }
  113. i = device->write(device,sector_no,write_buffer,1);
  114. if( i != 1 )
  115. {
  116. rt_kprintf("write device :%s ",device->parent.name);
  117. rt_kprintf("the second sector failed.\r\n");
  118. goto __return;
  119. }
  120. i = device->read(device,sector_no,read_buffer,1);
  121. if( i != 1 )
  122. {
  123. rt_kprintf("read device :%s ",device->parent.name);
  124. rt_kprintf("the second sector failed.\r\n");
  125. goto __return;
  126. }
  127. err_count = 0;
  128. data_point = read_buffer;
  129. if( (*data_point++) != (rt_uint8_t)sector_no)
  130. {
  131. err_count++;
  132. }
  133. for(i=1; i<geometry.bytes_per_sector; i++)
  134. {
  135. if( (*data_point++) != (rt_uint8_t)i )
  136. {
  137. err_count++;
  138. }
  139. }
  140. if( err_count > 0 )
  141. {
  142. rt_kprintf("verify device :%s ",device->parent.name);
  143. rt_kprintf("the second sector failed.\r\n");
  144. goto __return;
  145. }
  146. // the end sector
  147. sector_no = geometry.sector_count-1;
  148. data_point = write_buffer;
  149. *data_point++ = (rt_uint8_t)sector_no;
  150. for(i=1; i<geometry.bytes_per_sector; i++)
  151. {
  152. *data_point++ = (rt_uint8_t)i;
  153. }
  154. i = device->write(device,sector_no,write_buffer,1);
  155. if( i != 1 )
  156. {
  157. rt_kprintf("write device :%s ",device->parent.name);
  158. rt_kprintf("the end sector failed.\r\n");
  159. goto __return;
  160. }
  161. i = device->read(device,sector_no,read_buffer,1);
  162. if( i != 1 )
  163. {
  164. rt_kprintf("read device :%s ",device->parent.name);
  165. rt_kprintf("the end sector failed.\r\n");
  166. goto __return;
  167. }
  168. err_count = 0;
  169. data_point = read_buffer;
  170. if( (*data_point++) != (rt_uint8_t)sector_no)
  171. {
  172. err_count++;
  173. }
  174. for(i=1; i<geometry.bytes_per_sector; i++)
  175. {
  176. if( (*data_point++) != (rt_uint8_t)i )
  177. {
  178. err_count++;
  179. }
  180. }
  181. if( err_count > 0 )
  182. {
  183. rt_kprintf("verify device :%s ",device->parent.name);
  184. rt_kprintf("the end sector failed.\r\n");
  185. goto __return;
  186. }
  187. rt_kprintf("device I/O R/W test pass!\r\n");
  188. }//step 3: I/O R/W test
  189. // step 4: speed test
  190. {
  191. rt_uint32_t tick_start,tick_end;
  192. rt_uint32_t i;
  193. rt_kprintf("\r\n");
  194. rt_kprintf("device I/O speed test.\r\n");
  195. rt_kprintf("RT_TICK_PER_SECOND:%d\r\n",RT_TICK_PER_SECOND);
  196. if( geometry.sector_count < 10 )
  197. {
  198. rt_kprintf("device sector_count < 10,speed test abort!\r\n");
  199. }
  200. else
  201. {
  202. // sign sector read
  203. tick_start = rt_tick_get();
  204. for(i=0; i<200; i++)
  205. {
  206. device->read(device,i%10,read_buffer,1);
  207. }
  208. tick_end = rt_tick_get();
  209. rt_kprintf("read 200 sector from %d to %d,",tick_start,tick_end);
  210. rt_kprintf("%d byte/s\r\n",(geometry.bytes_per_sector*200UL*RT_TICK_PER_SECOND)/(tick_end-tick_start) );
  211. // sign sector write
  212. tick_start = rt_tick_get();
  213. for(i=0; i<200; i++)
  214. {
  215. device->write(device,i%10,read_buffer,1);
  216. }
  217. tick_end = rt_tick_get();
  218. rt_kprintf("write 200 sector from %d to %d,",tick_start,tick_end);
  219. rt_kprintf("%d byte/s\r\n",(geometry.bytes_per_sector*200UL*RT_TICK_PER_SECOND)/(tick_end-tick_start) );
  220. }
  221. }// step 4: speed test
  222. return RT_EOK;
  223. }// device can read and write.
  224. else
  225. {
  226. // device read only
  227. return RT_EOK;
  228. }// device read only
  229. __return:
  230. if( read_buffer != RT_NULL )
  231. {
  232. rt_free(read_buffer);
  233. }
  234. if( write_buffer != RT_NULL )
  235. {
  236. rt_free(write_buffer);
  237. }
  238. return RT_ERROR;
  239. }
  240. int device_test(const char * device_name)
  241. {
  242. rt_device_t device = RT_NULL;
  243. // step 1:find device
  244. device = rt_device_find(device_name);
  245. if( device == RT_NULL)
  246. {
  247. rt_kprintf("device %s: not found!\r\n");
  248. return RT_ERROR;
  249. }
  250. // step 2:init device
  251. if (!(device->flag & RT_DEVICE_FLAG_ACTIVATED))
  252. {
  253. rt_err_t result;
  254. result = device->init(device);
  255. if (result != RT_EOK)
  256. {
  257. rt_kprintf("To initialize device:%s failed. The error code is %d\r\n",
  258. device->parent.name, result);
  259. return result;
  260. }
  261. else
  262. {
  263. device->flag |= RT_DEVICE_FLAG_ACTIVATED;
  264. }
  265. }
  266. // step 3: device test
  267. switch( device->type )
  268. {
  269. case RT_Device_Class_Block :
  270. rt_kprintf("block device!\r\n");
  271. return _block_device_test(device);
  272. default:
  273. rt_kprintf("unkown device type : %02X",device->type);
  274. return RT_ERROR;
  275. }
  276. }
  277. #ifdef RT_USING_FINSH
  278. #include <finsh.h>
  279. FINSH_FUNCTION_EXPORT(device_test, e.g:device_test("sd0"));
  280. #endif