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

6.0 KiB
Raw Blame History

Eskin Finger SDK

E-Skin 手指力传感器 Rust SDK提供串口通信、寄存器读写、流式采集能力支持 Rust / C/C++ / Python 调用。

目录结构

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

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++

构建动态库

# 安装依赖Ubuntu
sudo apt install pkg-config libudev-dev

# 构建
cargo build --release
# 输出: target/release/libeskin_finger_sdk.so

编译 C++ 示例

g++ example/cpp/main.cpp -I include -L target/release -leskin_finger_sdk -o example_cpp
LD_LIBRARY_PATH=target/release ./example_cpp

C++ 代码示例

#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

构建 & 准备

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 指向正确的路径。

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 帧

[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 帧

[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 设备返回错误

测试

cargo test                   # 全部测试
cargo test protocol::tests   # 仅协议层

架构

User / C / Python
       ↓ FFI
  DeviceWrapper (handle)
       ↓
  EskinDeviceInner
       ↓ read_register / write_register
  EskinProtocolCodec (encode/decode + CRC8)
       ↓
  SerialTransport (write/read bytes)
       ↓
  Hardware (UART)

详细设计见 docs/PROGRESS.mddocs/ARCHITECTURE.md


依赖

  • serialport — 串口访问(需要 pkg-config + libudev-dev
  • crc — CRC-8/X25 校验
  • crossbeam-channel — 高性能线程间通信
  • chrono — 时间戳
  • serde / serde_json — 序列化(可选)