1+ /*
2+ * Copyright (c) 2006-2018, RT-Thread Development Team
3+ *
4+ * SPDX-License-Identifier: Apache-2.0
5+ *
6+ * Change Logs:
7+ * Date Author Notes
8+ * 2018-09-25 misonyo first edition.
9+ */
10+ /*
11+ * 程序清单:这是一个通过SD卡设备的使用例程
12+ * 例程导出了 sd_sample 命令到控制终端
13+ * 命令调用格式:sd_sample sd0
14+ * 命令解释:命令第二个参数是要使用的SD设备的名称,为空则使用例程默认的SD设备。
15+ * 程序功能:程序会产生一个块大小的随机数,然后写入SD卡中,然后在读取这部分写入的数据。
16+ * 对比写入和读出的数据是否一致,一致则表示程序运行正确。
17+ */
18+
19+ #include <rtthread.h>
20+ #include <rtdevice.h>
21+ #include <stdlib.h>
22+
23+ #define SD_DEVICE_NAME "sd0"
24+
25+ void fill_buffer (rt_uint8_t * buff , rt_uint32_t buff_length )
26+ {
27+ rt_uint32_t index ;
28+ /* 往缓冲区填充随机数 */
29+ for (index = 0 ; index < buff_length ; index ++ )
30+ {
31+ buff [index ] = ((rt_uint8_t )rand ()) & 0xff ;
32+ }
33+ }
34+
35+ static rt_err_t sd_sample (int argc , char * argv [])
36+ {
37+ rt_err_t result ;
38+ rt_device_t sd_device ;
39+ char sd_name [RT_NAME_MAX ];
40+ rt_uint8_t * write_buff , * read_buff ;
41+ struct rt_device_blk_geometry geo ;
42+ rt_uint8_t block_num ;
43+ /* 判断命令行参数是否给定了设备名称 */
44+ if (argc == 2 )
45+ {
46+ rt_strncpy (sd_name , argv [1 ], RT_NAME_MAX );
47+ }
48+ else
49+ {
50+ rt_strncpy (sd_name , SD_DEVICE_NAME , RT_NAME_MAX );
51+ }
52+ /* 查找设备获取设备句柄 */
53+ sd_device = rt_device_find (sd_name );
54+ if (sd_device == RT_NULL )
55+ {
56+ rt_kprintf ("find device %s failed!\n" , sd_name );
57+ return RT_ERROR ;
58+ }
59+ /* 打开设备 */
60+ result = rt_device_open (sd_device , RT_DEVICE_OFLAG_RDWR );
61+ if ( result != RT_EOK )
62+ {
63+ rt_kprintf ("open device %s failed!\n" , sd_name );
64+ return result ;
65+ }
66+
67+ rt_memset (& geo , 0 , sizeof (geo ));
68+ /* 获取块设备信息 */
69+ result = rt_device_control (sd_device , RT_DEVICE_CTRL_BLK_GETGEOME , & geo );
70+ if ( result != RT_EOK )
71+ {
72+ rt_kprintf ("control device %s failed!\n" , sd_name );
73+ return result ;
74+ }
75+ rt_kprintf ("device information:\n" );
76+ rt_kprintf ("sector size : %d byte\n" , geo .bytes_per_sector );
77+ rt_kprintf ("sector count : %d \n" , geo .sector_count );
78+ rt_kprintf ("block size : %d byte\n" , geo .block_size );
79+ /* 准备读写缓冲区空间,大小为一个块 */
80+ read_buff = rt_malloc (geo .block_size );
81+ if ( read_buff == RT_NULL )
82+ {
83+ rt_kprintf ("no memory for read buffer!\n" );
84+ return RT_ERROR ;
85+ }
86+ write_buff = rt_malloc (geo .block_size );
87+ if ( write_buff == RT_NULL )
88+ {
89+ rt_kprintf ("no memory for write buffer!\n" );
90+ rt_free (read_buff );
91+ return RT_ERROR ;
92+ }
93+
94+ /* 填充写数据缓冲区,为写操作做准备 */
95+ fill_buffer (write_buff , geo .block_size );
96+
97+ /* 把写数据缓冲的数据写入SD卡中,大小为一个块,size参数以块为单位 */
98+ block_num = rt_device_write (sd_device , 0 , write_buff , 1 );
99+ if (1 != block_num )
100+ {
101+ rt_kprintf ("write device %s failed!\n" ,sd_name );
102+ }
103+
104+ /* 从SD卡中读出数据,并保存在读数据缓冲区中 */
105+ block_num = rt_device_read (sd_device , 0 , read_buff , 1 );
106+ if (1 != block_num )
107+ {
108+ rt_kprintf ("read %s device failed!\n" ,sd_name );
109+ }
110+
111+ /* 比较写数据缓冲区和读数据缓冲区的内容是否完全一致 */
112+ if (rt_memcmp (write_buff , read_buff , geo .block_size ) == 0 )
113+ {
114+ rt_kprintf ("Block test OK!\n" );
115+ }
116+ else
117+ {
118+ rt_kprintf ("Block test Fail!\n" );
119+ }
120+ /* 释放缓冲区空间 */
121+ rt_free (read_buff );
122+ rt_free (write_buff );
123+
124+ return RT_EOK ;
125+ }
126+ /* 导出到 msh 命令列表中 */
127+ MSH_CMD_EXPORT (sd_sample , sd device sample );
0 commit comments