lenn a7b7192341 feat: add FFI layer, protocol tests, mock transport, README
- FFI: eskin_open/close/read_register/write_register for C/C++/Python
- Protocol: encode/decode tests with golden bytes verification
- Stream: implement PollingSampleCollector producing FingerSample
- Register: add parse_combined_forces/parse_module_errors
- Transport: add MockSerialTransport for testing
- Include: add C header file eskin_ffi.h
- Examples: C++ and Python usage examples
- README: full usage guide for Rust/C++/Python
- Exclude docs/ from repo (internal only)
2026-05-06 00:54:44 +08:00
2026-05-04 22:42:00 +08:00
2026-05-04 22:42:00 +08:00

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
cd example/python
LD_LIBRARY_PATH=../../target/release python3 example.py
from eskin_ffi import EskinDevice

with EskinDevice("target/release/libeskin_finger_sdk.so") as dev:
    dev.open("/dev/ttyUSB0")

    # 读寄存器
    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) 写寄存器原始字节

协议格式

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 — 序列化(可选)
Description
No description provided
Readme 182 KiB
0.1.0 Latest
2026-05-07 10:13:58 +08:00
Languages
Rust 74.7%
C++ 12%
Python 11.4%
CMake 1.9%