Files
eskin-finger-sdk/README.md
lenn 96f1e7db1e feat: add EskinDeviceFunc FFI bindings and update Python/README
- Add FFI wrappers for all EskinDeviceFunc trait methods:
  eskin_read_hdw_version, eskin_read_matrix_row/col,
  eskin_read_device_config1/2, eskin_write_device_config1/2,
  eskin_write_matrix_row/col
- Extract sdk_error_to_code() helper for SdkError -> SdkErrorCode conversion
- Update C header (include/eskin_ffi.h) with new function declarations
- Update Python FFI bindings (example/python/eskin_ffi.py) with new methods
- Update README with Python usage instructions and full FFI interface table
2026-05-07 10:00:04 +08:00

235 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Eskin Finger SDK
E-Skin 手指力传感器 Rust SDK提供串口通信、寄存器读写、流式采集能力支持 Rust / C/C++ / Python 调用。
## 目录结构
```text
src/
lib.rs — Rust 库入口
device.rs — 设备管理open/close/read/write
stream.rs — 流式采集PollingSampleCollector
protocol.rs — 协议帧编解码CRC-8/X25
register.rs — 寄存器地址定义与解析
transport.rs — 串口传输抽象
channel.rs — 线程间 Channel
config.rs — 配置与设备信息
error.rs — 错误类型
types.rs — 数据类型定义
ffi/mod.rs — C FFI 导出函数
include/
eskin_ffi.h — C/C++ 头文件
example/
cpp/main.cpp — C++ 使用示例
python/ — Python 使用示例
```
---
## 快速开始Rust
```rust
use eskin_finger_sdk::config::DeviceConfig;
use eskin_finger_sdk::device::{EskinDevice, EskinDeviceInner};
use eskin_finger_sdk::transport::SerialPortTransport;
let transport = SerialPortTransport::new("/dev/ttyUSB0", 921600);
let config = DeviceConfig::default();
let mut device = EskinDeviceInner::new(config, Box::new(transport));
device.open().unwrap();
// 读寄存器(原始字节)
let data = device.read_register(0x0000, 4).unwrap();
println!("Serial: {:?}", data);
// 写寄存器
let count = device.write_register(0x0030, &[0x01, 0x00, 0x00, 0x00]).unwrap();
println!("Wrote {} bytes", count);
device.close().unwrap();
```
---
## 使用 C/C++
### 构建动态库
```bash
# 安装依赖Ubuntu
sudo apt install pkg-config libudev-dev
# 构建
cargo build --release
# 输出: target/release/libeskin_finger_sdk.so
```
### 编译 C++ 示例
```bash
g++ example/cpp/main.cpp -I include -L target/release -leskin_finger_sdk -o example_cpp
LD_LIBRARY_PATH=target/release ./example_cpp
```
### C++ 代码示例
```cpp
#include "eskin_ffi.h"
#include <cstdio>
int main() {
EskinDeviceHandle dev = eskin_open("/dev/ttyUSB0", nullptr);
if (!dev) return 1;
uint8_t buf[256];
uint32_t actual;
if (eskin_read_register(dev, 0x0000, 4, buf, sizeof(buf), &actual) == ESkinSuccess) {
printf("Serial: %02X %02X %02X %02X\n", buf[0], buf[1], buf[2], buf[3]);
}
eskin_close(dev);
return 0;
}
```
---
## 使用 Python
### 构建 & 准备
```bash
cargo build --release
# 将生成的 .so 文件复制到 python 示例目录下
cp target/release/libeskin_finger_sdk.so example/python/
cd example/python
python3 example.py
```
> **注意:** Python 示例默认从当前目录加载 `libeskin_finger_sdk.so`,请确保 `.so` 文件已复制到 `example/python/` 目录下,或修改 `example.py` 中的 `LIB_PATH` 指向正确的路径。
```python
from eskin_ffi import EskinDevice
with EskinDevice("libeskin_finger_sdk.so") as dev:
dev.open("/dev/ttyUSB0")
# 读取硬件版本
print(f"Hardware version: {dev.read_hdw_version()}")
# 读取矩阵尺寸
print(f"Matrix: {dev.read_matrix_row()} x {dev.read_matrix_col()}")
# 读寄存器
data = dev.read_register(0x0000, 4)
print(f"Serial: {data.hex()}")
# 写寄存器
dev.write_register(0x0030, bytes([0x01, 0x00, 0x00, 0x00]))
```
---
## FFI 接口一览
| 函数 | 说明 |
|------|------|
| `eskin_version()` | 获取 SDK 版本 |
| `eskin_open(path, config)` | 打开串口设备,返回 handle |
| `eskin_close(handle)` | 关闭设备,释放 handle |
| `eskin_read_register(handle, addr, length, buf, buf_len, actual_len)` | 读寄存器原始字节 |
| `eskin_write_register(handle, addr, data, data_len, return_count)` | 写寄存器原始字节 |
| `eskin_read_hdw_version(handle, buf, buf_len, actual_len)` | 读取硬件版本号 |
| `eskin_read_matrix_row(handle, out)` | 读取矩阵行数 |
| `eskin_read_matrix_col(handle, out)` | 读取矩阵列数 |
| `eskin_read_device_config1(handle, out)` | 读取设备配置寄存器1 |
| `eskin_read_device_config2(handle, out)` | 读取设备配置寄存器2 |
| `eskin_write_device_config1(handle, enable, return_count)` | 写入设备配置寄存器1 |
| `eskin_write_device_config2(handle, enable, return_count)` | 写入设备配置寄存器2 |
| `eskin_write_matrix_row(handle, row, return_count)` | 写入矩阵行数 |
| `eskin_write_matrix_col(handle, col, return_count)` | 写入矩阵列数 |
---
## 协议格式
### Request 帧
```text
[start:2B] [data_len:2B LE] [dev_addr:1B] [reserved:1B] [func:1B]
[start_addr:4B LE] [read/write_len:2B LE] [payload:NB] [crc:1B]
start = [0x55, 0xAA]
func: READ=0xFB, WRITE=0x79
```
### Response 帧
```text
[start:2B] [data_len:2B LE] [dev_addr:1B] [reserved:1B] [func:1B]
[start_addr:4B LE] [read/write_len:2B LE] [payload:NB] [status:1B] [crc:1B]
start = [0x55, 0xAA] (注: 0xAA55 LE)
func: RESPONSE_READ=0xFF, RESPONSE_WRITE=0xF9
status: 0x00=Success
```
---
## 错误码
| 名称 | 值 | 说明 |
|------|----|------|
| `Success` | 0 | 成功 |
| `InvalidPointer` | 1 | 空指针 |
| `DeviceNotFound` | 2 | 设备未找到 |
| `DeviceAlreadyOpen` | 3 | 设备已打开 |
| `NotInitialized` | 4 | 未初始化 |
| `AlreadyStreaming` | 5 | 已在采集中 |
| `NotStreaming` | 6 | 未在采集 |
| `Timeout` | 9 | 读超时 |
| `ChannelClosed` | 10 | 通道断开 |
| `CrcError` | 14 | CRC 校验失败 |
| `FrameError` | 15 | 帧格式错误 |
| `DeviceError` | 17 | 设备返回错误 |
---
## 测试
```bash
cargo test # 全部测试
cargo test protocol::tests # 仅协议层
```
---
## 架构
```text
User / C / Python
↓ FFI
DeviceWrapper (handle)
EskinDeviceInner
↓ read_register / write_register
EskinProtocolCodec (encode/decode + CRC8)
SerialTransport (write/read bytes)
Hardware (UART)
```
详细设计见 `docs/PROGRESS.md``docs/ARCHITECTURE.md`
---
## 依赖
- `serialport` — 串口访问(需要 `pkg-config` + `libudev-dev`
- `crc` — CRC-8/X25 校验
- `crossbeam-channel` — 高性能线程间通信
- `chrono` — 时间戳
- `serde` / `serde_json` — 序列化(可选)