# BeShell-SD Card Example App
这是一个演示 BeShell-SD Card (SD 卡驱动) 用法的示例工程。
## 功能特性
本示例工程演示了以下功能:
### SD 卡功能
| 示例文件 | 说明 |
|---------|------|
| `basic-setup.js` | SD 卡基础初始化和挂载 |
| `file-operations.js` | 文件读写、复制、删除操作 |
| `directory-ops.js` | 目录创建、遍历、递归删除 |
| `file-browser.js` | 交互式文件浏览器 |
| `data-logger.js` | 传感器数据记录到 SD 卡 |
| `image-viewer.js` | 图片文件扫描和信息显示 |
## 项目结构
```
beshell-sdcard-app/
├── CMakeLists.txt # 项目 CMake 配置
├── sdkconfig.defaults # 默认 SDK 配置
├── README.md # 本文件
├── main/
│ ├── main.cpp # C++ 入口文件
│ ├── CMakeLists.txt # main 组件 CMake 配置
│ └── idf_component.yml # 组件依赖配置
├── img/
│ ├── partitions-4MB.csv # 4MB Flash 分区表
│ ├── partitions-8MB.csv # 8MB Flash 分区表
│ └── partitions-16MB.csv # 16MB Flash 分区表
└── js/
├── main.js # JS 入口文件
└── example/ # 示例脚本目录
├── basic-setup.js
├── file-operations.js
├── directory-ops.js
├── file-browser.js
├── data-logger.js
└── image-viewer.js
```
## 硬件要求
- ESP32 / ESP32-S3 / ESP32-C3 等芯片
- SD 卡模块或 SD 卡槽
- SD 卡 (FAT32 格式)
- 至少 4MB Flash
- USB 转串口用于烧录和调试
### 硬件连接 (SPI 模式)
```
ESP32 SD Card
----- -------
GPIO 5 --> CS
GPIO 18 --> SCK
GPIO 19 --> MISO
GPIO 23 --> MOSI
3.3V --> VCC
GND --> GND
```
**注意**:
- 某些 SD 卡模块需要 5V 供电,ESP32 的 GPIO 是 3.3V
- 建议使用带电平转换的 SD 卡模块
- SPI 引脚可能因 ESP32 型号而异
## SD 卡准备
1. 将 SD 卡格式化为 FAT32 文件系统
2. 可以预先创建一些测试文件和目录
3. 插入 SD 卡到模块
## 快速开始
### 1. 修改 SPI 配置
根据你的硬件连接修改示例中的配置:
```javascript
const SPI_HOST = 2 // SPI2 (HSPI)
const PIN_CS = 5 // CS 引脚
```
### 2. 构建项目
```bash
idf.py build
```
### 3. 烧录固件
```bash
idf.py flash
```
### 4. 查看串口输出
```bash
idf.py monitor
```
### 5. 运行示例
在串口终端中,输入以下命令运行示例:
```
run /example/basic-setup.js
```
## 示例详解
### 基础设置
```javascript
import { SDCard } from "sdcard"
let sd = new SDCard()
sd.setup({
spi: 2, // SPI 主机
cs: 5, // CS 引脚
mount: "/sdcard", // 挂载路径
khz: 20000 // SPI 时钟频率 (kHz)
})
```
### 文件操作
```javascript
// 写入文件
let fhandle = fs.open("/sdcard/test.txt", "w")
fs.write(fhandle, new TextEncoder().encode("Hello SD Card!"))
fs.close(fhandle)
// 读取文件
fhandle = fs.open("/sdcard/test.txt", "r")
let buffer = new Uint8Array(100)
fs.read(fhandle, buffer)
fs.close(fhandle)
console.log(new TextDecoder().decode(buffer))
```
### 目录操作
```javascript
// 创建目录
fs.mkdir("/sdcard/mydir")
// 列出目录
let files = fs.listDirSync("/sdcard")
files.forEach(f => console.log(f))
// 删除目录
fs.rmdir("/sdcard/mydir")
```
### 数据记录
```javascript
// 追加写入日志
let fhandle = fs.open("/sdcard/logs/data.csv", "a")
let line = `${Date.now()},${sensorValue}\n`
fs.write(fhandle, new TextEncoder().encode(line))
fs.close(fhandle)
```
## API 参考
### SDCard 类
#### constructor()
创建 SDCard 对象。
#### setup(config)
初始化 SD 卡。
- `config.spi`: SPI 主机号 (0-2)
- `config.cs`: CS 引脚号
- `config.mount`: 挂载路径
- `config.khz`: SPI 时钟频率 (kHz)
### 文件系统 API (fs 模块)
#### fs.open(path, mode)
打开文件。
- `mode`: "r" (读), "w" (写), "a" (追加)
#### fs.read(handle, buffer)
读取文件内容到缓冲区。
#### fs.write(handle, data)
写入数据到文件。
#### fs.close(handle)
关闭文件。
#### fs.stat(path)
获取文件/目录信息。
#### fs.mkdir(path)
创建目录。
#### fs.rmdir(path)
删除空目录。
#### fs.unlink(path)
删除文件。
#### fs.listDirSync(path)
同步列出目录内容。
## 性能提示
1. **缓冲区大小**: 读写时使用较大的缓冲区 (如 4KB) 可以提高性能
2. **文件打开时间**: 保持文件打开状态进行多次写入,而不是频繁打开关闭
3. **SPI 频率**: 根据 SD 卡质量调整 SPI 频率 (默认 20MHz)
4. **长文件名**: 启用 `CONFIG_FATFS_LFN_STACK` 支持长文件名
## 故障排除
### SD 卡初始化失败
1. 检查 SPI 连接 (CS, SCK, MISO, MOSI)
2. 确认 SD 卡已正确插入
3. 检查 SD 卡是否格式化为 FAT32
4. 尝试降低 SPI 频率
5. 使用其他 SD 卡测试
### 文件读写错误
1. 检查挂载路径是否正确
2. 确认文件路径存在
3. 检查 SD 卡是否有足够空间
4. 确认文件没有被其他程序占用
## 依赖组件
- [beshell](https://github.com/become-cool/beshell) - BeShell 核心框架
- [beshell-drv-sdcard](https://github.com/become-cool/beshell-drv-sdcard) - SD 卡驱动组件
## 许可证
LGPL
## 相关链接
- [BeShell 文档](https://beshell.become.cool)
- [ESP-IDF SD Card 文档](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/sdmmc.html)
- [FATFS 文档](http://elm-chan.org/fsw/ff/00index_e.html)
To create a project from this example, run:
idf.py create-project-from-example "become-cool/beshell-drv-sdcard=1.0.1:beshell-sdcard-app"