资料介绍
软件简介
TinyFrame
TinyFrame is a simple library for building and parsing data frames to be sent over a serial interface (e.g. UART, telnet, socket). The code is written to build with --std=gnu99
and mostly compatible with --std=gnu89
.
The library provides a high level interface for passing messages between the two peers. Multi-message sessions, response listeners, checksums, timeouts are all handled by the library.
TinyFrame is suitable for a wide range of applications, including inter-microcontroller communication, as a protocol for FTDI-based PC applications or for messaging through UDP packets.
The library lets you register listeners (callback functions) to wait for (1) any frame, (2) a particular frame Type, or (3) a specific message ID. This high-level API is general enough to implement most communication patterns.
TinyFrame is re-entrant and supports creating multiple instances with the limitation that their structure (field sizes and checksum type) is the same. There is a support for adding multi-threaded access to a shared instance using a mutex.
TinyFrame also comes with (optional) helper functions for building and parsing message payloads, those are provided in the utils/
folder.
Ports
TinyFrame has been ported to mutiple languages:
- The reference C implementation is in this repo
- Python port - MightyPork/PonyFrame
- Rust port - cpsdqs/tinyframe-rs
- JavaScript port - cpsdqs/tinyframe-js
Please note most of the ports are experimental and may exhibit various bugs or missing features. Testers are welcome :)
Functional overview
The basic functionality of TinyFrame is explained here. For particlars, such as the API functions, it's recommended to read the doc comments in the header file.
Structure of a frame
Each frame consists of a header and a payload. Both parts can be protected by a checksum, ensuring a frame with a malformed header (e.g. with a corrupted length field) or a corrupted payload is rejected.
The frame header contains a frame ID and a message type. Frame ID is incremented with each new message. The highest bit of the ID field is fixed to 1 and 0 for the two peers, avoiding a conflict.
Frame ID can be re-used in a response to tie the two messages together. Values of the type field are user defined.
All fields in the frame have a configurable size. By changing a field in the config file, such as TF_LEN_BYTES
(1, 2 or 4), the library seamlessly switches between uint8_t
, uint16_t
and uint32_t
for all functions working with the field.
,-----+-----+-----+------+------------+- - - -+-------------,
| SOF | ID | LEN | TYPE | HEAD_CKSUM | DATA | DATA_CKSUM |
| 0-1 | 1-4 | 1-4 | 1-4 | 0-4 | ... | 0-4 | <- size (bytes)
'-----+-----+-----+------+------------+- - - -+-------------'
SOF ......... start of frame, usually 0x01 (optional, configurable)
ID ......... the frame ID (MSb is the peer bit)
LEN ......... number of data bytes in the frame
TYPE ........ message type (used to run Type Listeners, pick any values you like)
HEAD_CKSUM .. header checksum
DATA ........ LEN bytes of data
DATA_CKSUM .. data checksum (left out if LEN is 0)
Message listeners
TinyFrame is based on the concept of message listeners. A listener is a callback function waiting for a particular message Type or ID to be received.
There are 3 listener types, in the order of precedence:
- ID listeners - waiting for a response
- Type listeners - waiting for a message of the given Type field
- Generic listeners - fallback
ID listeners can be registered automatically when sending a message. All listeners can also be registered and removed manually.
ID listeners are used to receive the response to a request. When registerign an ID listener, it's possible to attach custom user data to it that will be made available to the listener callback. This data (void *
) can be any kind of application context variable.
ID listeners can be assigned a timeout. When a listener expires, before it's removed, the callback is fired with NULL payload data in order to let the user free()
any attached userdata. This happens only if the userdata is not NULL.
Listener callbacks return values of the TF_Result
enum:
-
TF_CLOSE
- message accepted, remove the listener -
TF_STAY
- message accepted, stay registered -
TF_RENEW
- sameasTF_STAY
, but the ID listener's timeout is renewed -
TF_NEXT
- message NOT accepted, keep the listener and pass the message to the next listener capable of handling it.
Data buffers, multi-part frames
TinyFrame uses two data buffers: a small transmit buffer and a larger receive buffer. The transmit buffer is used to prepare bytes to send, either all at once, or in a circular fashion if the buffer is not large enough. The buffer must only contain the entire frame header, so e.g. 32 bytes should be sufficient for short messages.
Using the *_Multipart()
sending functions, it's further possible to split the frame header and payload to multiple function calls, allowing the applciation to e.g. generate the payload on-the-fly.
In contrast to the transmit buffer, the receive buffer must be large enough to contain an entire frame. This is because the final checksum must be verified before the frame is handled.
If frames larger than the possible receive buffer size are required (e.g. in embedded systems with small RAM), it's recommended to implement a multi-message transport mechanism at a higher level and send the data in chunks.
Usage Hints
-
All TinyFrame functions, typedefs and macros start with the
TF_
prefix. - Both peers must include the library with the same config parameters
-
See
TF_Integration.example.c
andTF_Config.example.c
for reference how to configure and integrate the library. - DO NOT modify the library files, if possible. This makes it easy to upgrade.
-
Start by calling
TF_Init()
withTF_MASTER
orTF_SLAVE
as the argument. This creates a handle. UseTF_InitStatic()
to avoid the use of malloc(). -
If multiple instances are used, you can tag them using the
tf.userdata
/tf.usertag
field. -
Implement
TF_WriteImpl()
- declared at the bottom of the header file asextern
. This function is used byTF_Send()
and others to write bytes to your UART (or other physical layer). A frame can be sent in it's entirety, or in multiple parts, depending on its size. - Use TF_AcceptChar(tf, byte) to give read data to TF. TF_Accept(tf, bytes, count) will accept mulitple bytes.
-
If you wish to use timeouts, periodically call
TF_Tick()
. The calling period determines the length of 1 tick. This is used to time-out the parser in case it gets stuck in a bad state (such as receiving a partial frame) and can also time-out ID listeners. -
Bind Type or Generic listeners using
TF_AddTypeListener()
orTF_AddGenericListener()
. -
Send a message using
TF_Send()
,TF_Query()
,TF_SendSimple()
,TF_QuerySimple()
. Query functions take a listener callback (function pointer) that will be added as an ID listener and wait for a response. -
Use the
*_Multipart()
variant of the above sending functions for payloads generated in multiple function calls. The payload is sent afterwards by callingTF_Multipart_Payload()
and the frame is closed byTF_Multipart_Close()
. -
If custom checksum implementation is needed, select
TF_CKSUM_CUSTOM8
, 16 or 32 and implement the three checksum functions. -
To reply to a message (when your listener gets called), use
TF_Respond()
with the msg object you received, replacing thedata
pointer (andlen
) with a response. -
At any time you can manually reset the message parser using
TF_ResetParser()
. It can also be reset automatically after a timeout configured in the config file.
Gotchas to look out for
-
If any userdata is attached to an ID listener with a timeout, when the listener times out, it will be called with NULL
msg->data
to let the user free the userdata. Therefore it's needed to checkmsg->data
before proceeding to handle the message. - If a multi-part frame is being sent, the Tx part of the library is locked to prevent concurrent access. The frame must be fully sent and closed before attempting to send anything else.
-
If multiple threads are used, don't forget to implement the mutex callbacks to avoid concurrent access to the Tx functions. The default implementation is not entirely thread safe, as it can't rely on platform-specific resources like mutexes or atomic access. Set
TF_USE_MUTEX
to1
in the config file.
Examples
You'll find various examples in the demo/
folder. Each example has it's own Makefile, read it to see what options are available.
The demos are written for Linux, some using sockets and clone()
for background processing. They try to simulate real TinyFrame behavior in an embedded system with asynchronous Rx and Tx. If you can't run the demos, the source files are still good as examples.
- LABVIEW NPOI库文件下载 192次下载
- 用于OHOS最简单的UI验证库教程 1次下载
- altium designer元件库下载 703次下载
- STM32f10x官方固件库资料 151次下载
- STM32固件库使用手册的中文版 0次下载
- STM32f10x官方固件库资料 65次下载
- AD常用3D封装库(STEP)下载 370次下载
- AD 2D标准封装库下载 22次下载
- 面向NoSQL数据库的JSON文档异常检测模型 20次下载
- 如何使用Multisim扩展PSpice元件库详细方法说明 0次下载
- 如何使用简单好用的PubSubClient库来做一个最简单的MQTT客户端
- protel99建库规则大全 0次下载
- AN1246中文手册之如何在Microchip图形库中创建控件
- 最简单的触摸屏接线方法 57次下载
- 通用封装库(protel/AD版本通用)资料下载 0次下载
- 基于Rust的Log日志库介绍 3121次阅读
- nuere-简单小巧快速的字符串解析库 460次阅读
- STM32 HAL库串口收发如何使用 5547次阅读
- Linux中的静态库和共享库 850次阅读
- 库迁移器的高级模式 751次阅读
- 四种方式来让您以简单模式访问迁移器 843次阅读
- 云数据库和自建数据库的区别及应用 4412次阅读
- 数据库入门书籍推荐 3.7w次阅读
- 多维数据库有哪些 7031次阅读
- 用JDBC连接MySQL数据库并进行简单的增删改查操作 6256次阅读
- 谷歌开源TFGAN轻量级的工具库 目的是让训练和评估GAN变得更加简单 4811次阅读
- cassandra数据库迁移与扩容 5558次阅读
- Android中实现简单的新闻列表 3769次阅读
- STM32标准库改为HAL库的程序实现 3.4w次阅读
- 盘点几种深度学习库 3063次阅读
下载排行
本周
- 1使用单片机实现七人表决器的程序和仿真资料免费下载
- 2.96 MB | 44次下载 | 免费
- 2Keysight B1500A 半导体器件分析仪用户手册、说明书 (中文)
- 19.00 MB | 4次下载 | 免费
- 3BT134双向可控硅手册
- 1.74 MB | 2次下载 | 1 积分
- 4一种新型高效率的服务器电源系统
- 0.85 MB | 1次下载 | 1 积分
- 5PR735,使用UCC28060的600W交错式PFC转换器
- 540.03KB | 1次下载 | 免费
- 6WTS-100(1.1) UWB 信标定位系统 彩页
- 540.48 KB | 1次下载 | 免费
- 7DV2004S1/ES1/HS1快速充电开发系统
- 2.08MB | 1次下载 | 免费
- 8MATLAB绘图合集
- 27.12 MB | 1次下载 | 5 积分
本月
- 1使用单片机实现七人表决器的程序和仿真资料免费下载
- 2.96 MB | 44次下载 | 免费
- 2UC3842/3/4/5电源管理芯片中文手册
- 1.75 MB | 15次下载 | 免费
- 3DMT0660数字万用表产品说明书
- 0.70 MB | 13次下载 | 免费
- 4ST7789V2单芯片控制器/驱动器英文手册
- 3.07 MB | 11次下载 | 1 积分
- 5TPS54202H降压转换器评估模块用户指南
- 1.02MB | 8次下载 | 免费
- 6STM32F101x8/STM32F101xB手册
- 1.69 MB | 8次下载 | 1 积分
- 7TPS92682-Q1帧定义和示例
- 891.71KB | 6次下载 | 免费
- 8HY12P65/HY12P66数字万用表芯片规格书
- 0.69 MB | 6次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935119次下载 | 10 积分
- 2开源硬件-PMP21529.1-4 开关降压/升压双向直流/直流转换器 PCB layout 设计
- 1.48MB | 420061次下载 | 10 积分
- 3Altium DXP2002下载入口
- 未知 | 233084次下载 | 10 积分
- 4电路仿真软件multisim 10.0免费下载
- 340992 | 191367次下载 | 10 积分
- 5十天学会AVR单片机与C语言视频教程 下载
- 158M | 183335次下载 | 10 积分
- 6labview8.5下载
- 未知 | 81581次下载 | 10 积分
- 7Keil工具MDK-Arm免费下载
- 0.02 MB | 73807次下载 | 10 积分
- 8LabVIEW 8.6下载
- 未知 | 65987次下载 | 10 积分
评论
查看更多