3 Commits
Author SHA1 Message Date
MightyPork aadbb0f89e add TF_VERSION define 2017-12-12 20:22:40 +01:00
MightyPork a27798188d Updated code with new improvements - mutex locks 2017-12-12 20:19:02 +01:00
MightyPork 970d6f7ced fix corrupt indentation 2017-11-21 23:17:12 +01:00
4 changed files with 116 additions and 49 deletions
+4 -2
View File
@@ -1,4 +1,6 @@
// //
// TinyFrame configuration file.
//
// Rename to TF_Config.h // Rename to TF_Config.h
// //
@@ -19,7 +21,7 @@
// | 1 | ? | ? | ? | ? | ... | ? | <- size (bytes) // | 1 | ? | ? | ? | ? | ... | ? | <- size (bytes)
// '-----+----+-----+------+------------+- - - -+------------' // '-----+----+-----+------+------------+- - - -+------------'
// !!! BOTH SIDES MUST USE THE SAME SETTINGS !!! // !!! BOTH PEERS MUST USE THE SAME SETTINGS !!!
// Adjust sizes as desired (1,2,4) // Adjust sizes as desired (1,2,4)
#define TF_ID_BYTES 1 #define TF_ID_BYTES 1
@@ -52,7 +54,7 @@ typedef uint8_t TF_COUNT;
#define TF_MAX_PAYLOAD_RX 1024 #define TF_MAX_PAYLOAD_RX 1024
// Size of the sending buffer. Larger payloads will be split to pieces and sent // Size of the sending buffer. Larger payloads will be split to pieces and sent
// in multiple calls to the write function. This can be lowered to reduce RAM usage. // in multiple calls to the write function. This can be lowered to reduce RAM usage.
#define TF_SENDBUF_LEN 1024 #define TF_SENDBUF_LEN 128
// --- Listener counts - determine sizes of the static slot tables --- // --- Listener counts - determine sizes of the static slot tables ---
+28
View File
@@ -0,0 +1,28 @@
#include "TinyFrame.h"
/**
* This is an example of integrating TinyFrame into the application.
*
* TF_WriteImpl() is required, the mutex functions are weak and can
* be removed if not used. They are called from all TF_Send/Respond functions.
*
* Also remember to periodically call TF_Tick() if you wish to use the
* listener timeout feature.
*/
void TF_WriteImpl(const uint8_t *buff, size_t len)
{
// send to UART
}
/** Claim the TX interface before composing and sending a frame */
void TF_ClaimTx(void)
{
// take mutex
}
/** Free the TX interface after composing and sending a frame */
void TF_ReleaseTx(void)
{
// release mutex
}
+65 -47
View File
@@ -1,7 +1,6 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "TinyFrame.h" #include "TinyFrame.h"
#include <string.h> #include <string.h>
//#include "demo/utils.h"
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Compatibility with ESP8266 SDK // Compatibility with ESP8266 SDK
@@ -31,6 +30,7 @@ typedef struct _IdListener_struct_ {
TF_TICKS timeout; // nr of ticks remaining to disable this listener TF_TICKS timeout; // nr of ticks remaining to disable this listener
TF_TICKS timeout_max; // the original timeout is stored here TF_TICKS timeout_max; // the original timeout is stored here
void *userdata; void *userdata;
void *userdata2;
} IdListener; } IdListener;
typedef struct _TypeListener_struct_ { typedef struct _TypeListener_struct_ {
@@ -233,6 +233,7 @@ static void _TF_FN cleanup_id_listener(TF_COUNT i, IdListener *lst)
// Make user clean up their data - only if not NULL // Make user clean up their data - only if not NULL
if (lst->userdata != NULL) { if (lst->userdata != NULL) {
msg.userdata = lst->userdata; msg.userdata = lst->userdata;
msg.userdata2 = lst->userdata2;
msg.data = NULL; // this is a signal that the listener should clean up msg.data = NULL; // this is a signal that the listener should clean up
lst->fn(&msg); // return value is ignored here - use TF_STAY or TF_CLOSE lst->fn(&msg); // return value is ignored here - use TF_STAY or TF_CLOSE
} }
@@ -281,6 +282,7 @@ bool _TF_FN TF_AddIdListener(TF_Msg *msg, TF_Listener cb, TF_TICKS timeout)
lst->fn = cb; lst->fn = cb;
lst->id = msg->frame_id; lst->id = msg->frame_id;
lst->userdata = msg->userdata; lst->userdata = msg->userdata;
lst->userdata2 = msg->userdata2;
lst->timeout_max = lst->timeout = timeout; lst->timeout_max = lst->timeout = timeout;
if (i >= tf.count_id_lst) { if (i >= tf.count_id_lst) {
tf.count_id_lst = (TF_COUNT) (i + 1); tf.count_id_lst = (TF_COUNT) (i + 1);
@@ -403,8 +405,10 @@ static void _TF_FN TF_HandleReceivedMessage(void)
ilst = &tf.id_listeners[i]; ilst = &tf.id_listeners[i];
if (ilst->fn && ilst->id == msg.frame_id) { if (ilst->fn && ilst->id == msg.frame_id) {
msg.userdata = ilst->userdata; // pass userdata pointer to the callback msg.userdata = ilst->userdata; // pass userdata pointer to the callback
msg.userdata2 = ilst->userdata2;
res = ilst->fn(&msg); res = ilst->fn(&msg);
ilst->userdata = msg.userdata; // put it back (may have changed the pointer or set to NULL) ilst->userdata = msg.userdata; // put it back (may have changed the pointer or set to NULL)
ilst->userdata2 = msg.userdata2; // put it back (may have changed the pointer or set to NULL)
if (res != TF_NEXT) { if (res != TF_NEXT) {
if (res == TF_CLOSE) { if (res == TF_CLOSE) {
@@ -418,6 +422,7 @@ static void _TF_FN TF_HandleReceivedMessage(void)
} }
} }
msg.userdata = NULL; msg.userdata = NULL;
msg.userdata2 = NULL;
// clean up for the following listeners that don't use userdata // clean up for the following listeners that don't use userdata
// Type listeners // Type listeners
@@ -509,63 +514,63 @@ void _TF_FN TF_AcceptChar(unsigned char c)
case TFState_ID: case TFState_ID:
CKSUM_ADD(tf.cksum, c); CKSUM_ADD(tf.cksum, c);
COLLECT_NUMBER(tf.id, TF_ID) { COLLECT_NUMBER(tf.id, TF_ID) {
// Enter LEN state // Enter LEN state
tf.state = TFState_LEN; tf.state = TFState_LEN;
tf.rxi = 0; tf.rxi = 0;
} }
break; break;
case TFState_LEN: case TFState_LEN:
CKSUM_ADD(tf.cksum, c); CKSUM_ADD(tf.cksum, c);
COLLECT_NUMBER(tf.len, TF_LEN) { COLLECT_NUMBER(tf.len, TF_LEN) {
// Enter TYPE state // Enter TYPE state
tf.state = TFState_TYPE; tf.state = TFState_TYPE;
tf.rxi = 0; tf.rxi = 0;
} }
break; break;
case TFState_TYPE: case TFState_TYPE:
CKSUM_ADD(tf.cksum, c); CKSUM_ADD(tf.cksum, c);
COLLECT_NUMBER(tf.type, TF_TYPE) { COLLECT_NUMBER(tf.type, TF_TYPE) {
#if TF_CKSUM_TYPE == TF_CKSUM_NONE #if TF_CKSUM_TYPE == TF_CKSUM_NONE
tf.state = TFState_DATA; tf.state = TFState_DATA;
tf.rxi = 0; tf.rxi = 0;
#else #else
// enter HEAD_CKSUM state // enter HEAD_CKSUM state
tf.state = TFState_HEAD_CKSUM; tf.state = TFState_HEAD_CKSUM;
tf.rxi = 0; tf.rxi = 0;
tf.ref_cksum = 0; tf.ref_cksum = 0;
#endif #endif
} }
break; break;
case TFState_HEAD_CKSUM: case TFState_HEAD_CKSUM:
COLLECT_NUMBER(tf.ref_cksum, TF_CKSUM) { COLLECT_NUMBER(tf.ref_cksum, TF_CKSUM) {
// Check the header checksum against the computed value // Check the header checksum against the computed value
CKSUM_FINALIZE(tf.cksum); CKSUM_FINALIZE(tf.cksum);
if (tf.cksum != tf.ref_cksum) { if (tf.cksum != tf.ref_cksum) {
TF_ResetParser(); TF_ResetParser();
break; break;
} }
if (tf.len == 0) { if (tf.len == 0) {
TF_HandleReceivedMessage(); TF_HandleReceivedMessage();
TF_ResetParser(); TF_ResetParser();
break; break;
} }
// Enter DATA state // Enter DATA state
tf.state = TFState_DATA; tf.state = TFState_DATA;
tf.rxi = 0; tf.rxi = 0;
CKSUM_RESET(tf.cksum); // Start collecting the payload CKSUM_RESET(tf.cksum); // Start collecting the payload
if (tf.len >= TF_MAX_PAYLOAD_RX) { if (tf.len >= TF_MAX_PAYLOAD_RX) {
// ERROR - frame too long. Consume, but do not store. // ERROR - frame too long. Consume, but do not store.
tf.discard_data = true; tf.discard_data = true;
} }
} }
break; break;
case TFState_DATA: case TFState_DATA:
@@ -579,8 +584,8 @@ void _TF_FN TF_AcceptChar(unsigned char c)
if (tf.rxi == tf.len) { if (tf.rxi == tf.len) {
#if TF_CKSUM_TYPE == TF_CKSUM_NONE #if TF_CKSUM_TYPE == TF_CKSUM_NONE
// All done // All done
TF_HandleReceivedMessage(); TF_HandleReceivedMessage();
TF_ResetParser(); TF_ResetParser();
#else #else
// Enter DATA_CKSUM state // Enter DATA_CKSUM state
tf.state = TFState_DATA_CKSUM; tf.state = TFState_DATA_CKSUM;
@@ -591,15 +596,15 @@ void _TF_FN TF_AcceptChar(unsigned char c)
break; break;
case TFState_DATA_CKSUM: case TFState_DATA_CKSUM:
COLLECT_NUMBER(tf.ref_cksum, TF_CKSUM) { COLLECT_NUMBER(tf.ref_cksum, TF_CKSUM) {
// Check the header checksum against the computed value // Check the header checksum against the computed value
CKSUM_FINALIZE(tf.cksum); CKSUM_FINALIZE(tf.cksum);
if (!tf.discard_data && tf.cksum == tf.ref_cksum) { if (!tf.discard_data && tf.cksum == tf.ref_cksum) {
TF_HandleReceivedMessage(); TF_HandleReceivedMessage();
} }
TF_ResetParser(); TF_ResetParser();
} }
break; break;
} }
@@ -734,6 +739,8 @@ static bool _TF_FN TF_SendFrame(TF_Msg *msg, TF_Listener listener, TF_TICKS time
size_t sent = 0; size_t sent = 0;
TF_CKSUM cksum = 0; TF_CKSUM cksum = 0;
TF_ClaimTx();
len = TF_ComposeHead(tf.sendbuf, len = TF_ComposeHead(tf.sendbuf,
&msg->frame_id, &msg->frame_id,
msg->type, msg->type,
@@ -769,6 +776,8 @@ static bool _TF_FN TF_SendFrame(TF_Msg *msg, TF_Listener listener, TF_TICKS time
len += TF_ComposeTail(tf.sendbuf+len, &cksum); len += TF_ComposeTail(tf.sendbuf+len, &cksum);
TF_WriteImpl((const uint8_t *) tf.sendbuf, len); TF_WriteImpl((const uint8_t *) tf.sendbuf, len);
TF_ReleaseTx();
return true; return true;
} }
@@ -852,3 +861,12 @@ void _TF_FN TF_Tick(void)
} }
} }
void __attribute__((weak)) TF_ClaimTx(void)
{
// do nothing
}
void __attribute__((weak)) TF_ReleaseTx(void)
{
// do nothing
}
+19
View File
@@ -1,6 +1,17 @@
#ifndef TinyFrameH #ifndef TinyFrameH
#define TinyFrameH #define TinyFrameH
/**
* TinyFrame protocol library
*
* (c) Ondřej Hruška 2017, MIT License
* no liability/warranty, free for any use, must retain this notice & license
*
* Upstream URL: https://github.com/MightyPork/TinyFrame
*/
#define TF_VERSION "1.2.0"
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include <stdint.h> // for uint8_t etc #include <stdint.h> // for uint8_t etc
#include <stdbool.h> // for bool #include <stdbool.h> // for bool
@@ -105,6 +116,7 @@ typedef struct _TF_MSG_STRUCT_ {
const uint8_t *data; //!< buffer of received data or data to send. NULL = listener timed out, free userdata! const uint8_t *data; //!< buffer of received data or data to send. NULL = listener timed out, free userdata!
TF_LEN len; //!< length of the buffer TF_LEN len; //!< length of the buffer
void *userdata; //!< here's a place for custom data; this data will be stored with the listener void *userdata; //!< here's a place for custom data; this data will be stored with the listener
void *userdata2;
} TF_Msg; } TF_Msg;
/** /**
@@ -118,6 +130,7 @@ static inline void TF_ClearMsg(TF_Msg *msg)
msg->data = NULL; msg->data = NULL;
msg->len = 0; msg->len = 0;
msg->userdata = NULL; msg->userdata = NULL;
msg->userdata2 = NULL;
} }
/** /**
@@ -269,4 +282,10 @@ extern void TF_WriteImpl(const uint8_t *buff, size_t len);
*/ */
void TF_Tick(void); void TF_Tick(void);
/** Claim the TX interface before composing and sending a frame */
extern void TF_ClaimTx(void);
/** Free the TX interface after composing and sending a frame */
extern void TF_ReleaseTx(void);
#endif #endif