device_test.c 9.7 KB

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