Skip to content

Commit

Permalink
- Commit for version 0.0.2
Browse files Browse the repository at this point in the history
- Fixed warning in ssfrs_ut.c.
- Updated version number.
- Updated readme.
  • Loading branch information
supurloop committed Feb 25, 2021
1 parent 91ec8a9 commit 9c94f88
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
94 changes: 92 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,21 @@ The framework implements a number of common embedded system functions:
6. A JSON parser/generator interface.
7. A 16-bit Fletcher checksum interface.
8. A finite state machine framework.
9. A Reed-Solomon FEC encoder/decoder interface.

To give you an idea of the framework size here are some program memory estimates for each component compiled on an MSP430 with Level 3 optimization:
Byte FIFO, linked list, memory pool, Base64, Hex ASCII are each about 1000 bytes.
JSON parser/generator is about 7300-8800 bytes depending on configuration.
Finite state machine is about 2000 bytes.
Fletcher checksum is about 88 bytes.

The complete framework, assuming every function of every interface is used, is about 15000 bytes of program memory.
The complete framework, assuming every function of every interface is used, is about 20000 bytes of program memory.
Many programs will only use a fraction of the functions in all the interfaces and should see the amount of program memory reduced further.

Little RAM is used internally by the framework, most RAM usage occurs outside the framwork when declaring or initializing different objects.

Microprocessors with >4KB RAM and >32KB program memory should easily be able to utilize this framework.
Microprocessors with >4KB RAM and >32KB program memory should easily be able to utilize all of this framework.
And, as noted above, portions of the framework will work on much smaller micros.

## Porting

Expand Down Expand Up @@ -498,6 +500,94 @@ After 10 seconds the SSF_SM_EVENT_STATUS_LED_TIMER_IDLE timer expires and trigge

The framework automatically stops all timers associated with a state machine when a state transition occurs. This is why it is not necessary to explicitly stop the SSF_SM_EVENT_STATUS_LED_TIMER_TOGGLE timer.

### Reed-Solomon FEC Encoder/Decoder Interface

The Reed-Solomon FEC encoder/decoder interface is a memory efficient (both program and RAM) implementation of the same error correction algorithm that the Voyager probes use to communicate reliably with Earth.

Reed-Solomon can be used to increase the effective receive sensitivity of radios purely in software!

The encoder takes a message and outputs a block of Reed-Solomom ECC bytes. To use, simply transmit the original message followed by the ECC bytes.
The decoder takes a received message, that includes both the message and ECC bytes, and then attempts to correct back to the original message.

The implementation allows larger messages to be processed in chunks which allows trade offs between RAM utilization and encoding/decoding speed.
Using Reed-Solomon still requires the use of CRCs to verify the integrity of the original message after error correction is applied because the error correction can "successfully" correct to the wrong message.

Here's a simple example:

```
/* ssfport.h */
...
/* --------------------------------------------------------------------------------------------- */
/* Configure ssfrs's Reed-Solomon interface */
/* --------------------------------------------------------------------------------------------- */
...
/* The maximum total size in bytes of a message to be encoded or decoded */
#define SSF_RS_MAX_MESSAGE_SIZE (1024)
...
/* The maximum number of bytes that will be encoded with up to SSF_RS_MAX_SYMBOLS bytes */
#define SSF_RS_MAX_CHUNK_SIZE (127u)
...
/* The maximum number of chunks that a message will be broken up into for encoding and decoding */
#if SSF_RS_MAX_MESSAGE_SIZE % SSF_RS_MAX_CHUNK_SIZE == 0
#define SSF_RS_MAX_CHUNKS (SSF_RS_MAX_MESSAGE_SIZE / SSF_RS_MAX_CHUNK_SIZE)
#else
#define SSF_RS_MAX_CHUNKS ((SSF_RS_MAX_MESSAGE_SIZE / SSF_RS_MAX_CHUNK_SIZE) + 1)
#endif
...
/* The maximum number of symbols in bytes that will encode up to SSF_RS_MAX_CHUNK_SIZE bytes */
/* Reed-Solomon can correct SSF_RS_MAX_SYMBOLS/2 bytes with errors in a message */
#define SSF_RS_MAX_SYMBOLS (8ul)
/* main.c */
...
void main(void)
{
uint8_t msg[SSF_RS_MAX_MESSAGE_SIZE];
uint8_t ecc[SSF_RS_MAX_SYMBOLS * SSF_RS_MAX_CHUNKS];
uint8_t msgRx[SSF_RS_MAX_MESSAGE_SIZE + (SSF_RS_MAX_SYMBOLS * SSF_RS_MAX_CHUNKS)];
uint16_t eccLen;
uint16_t msgLen;
memset(msg, 0xaa, sizeof(msg));
SSFRSEncode(msg, (uint16_t) sizeof(msg), ecc, (uint16_t)sizeof(ecc), &eccLen,
SSF_RS_MAX_SYMBOLS, SSF_RS_MAX_CHUNK_SIZE);
/* Pretend to transmit the message and ecc bytes by combining them into a buffer */
memcpy(msgRx, msg, SSF_RS_MAX_MESSAGE_SIZE);
memcpy(&msgRx[SSF_RS_MAX_MESSAGE_SIZE], ecc, eccLen);
/* Pretend to receive and decode the message which has incurred an error */
msgRx[0] = 0x55;
/* Perform error correction on the received message */
if (SSFRSDecode(msgRx, (uint16_t) sizeof(msgRx), &msgLen, SSF_RS_MAX_SYMBOLS,
SSF_RS_MAX_CHUNK_SIZE))
{
/* msgRx[0] has been fixed and is now 0xaa again */
/* msgLen is SSF_RS_MAX_MESSAGE_SIZE */
/* Note: A CRC should verify the integrity of the message after error correction. */
/* It has been omitted in this example for clarity. */
}
else
{
/* Error correction failed */
}
...
```
The encode call will always succeed. It will populate the ecc buffer with up to SSF_RS_MAX_CHUNKS * SSF_RS_MAX_SYMBOLS of ECC data depending on the actual length of the input message.
eccLen is the actual number of EEC bytes put into the ecc buffer.

Next the example copies the message and the ecc bytes to a contiguous buffer and modifies the first byte to simulate an error.

The decode will return true if it finds a solution and will correct the message in place.
After the decode completes the first byte is restored to 0xaa, and msgLen is SSF_RS_MAX_MESSAGE_SIZE.

For clarity, the example omits integrity checking the message after error correction occurs.
In a real system check the message integrity after error correction is applied because the Reed-Solomon algorithm can "successfully" find the wrong solution.

## Conclusion

I built this framework for primarily myself, although I hope you can find a good use for it.
Expand Down
1 change: 1 addition & 0 deletions ssfrs_ut.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "ssfrs.h"
#include "ssfport.h"
#include "ssfassert.h"
Expand Down
3 changes: 2 additions & 1 deletion ssfversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
/* Version History */
/* */
/* 0.0.1 - Initial beta release. */
/* 0.0.2 - Add Reed-Solomon GF(2^8) implementation. */
/* --------------------------------------------------------------------------------------------- */
#define SSF_VERSION "0.0.1"
#define SSF_VERSION "0.0.2"

#endif /* SSF_VERSION_H_INCLUDE */

0 comments on commit 9c94f88

Please sign in to comment.