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