Skip to content

Commit 1de52ea

Browse files
committed
Added support for compressed firmware
1 parent 5bd7227 commit 1de52ea

13 files changed

+1626
-6
lines changed

Makefile

+5-2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk
7979
include $(CHIBIOS)/os/hal/hal.mk
8080
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk
8181
include $(CHIBIOS)/os/kernel/kernel.mk
82+
include heatshrink/heatshrink.mk
8283

8384
# Define linker script file here
8485
LDSCRIPT= ld_bootloader.ld
@@ -94,7 +95,8 @@ CSRC = $(PORTSRC) \
9495
$(BOARDSRC) \
9596
main.c \
9697
crc.c \
97-
buffer.c
98+
buffer.c \
99+
$(HEATSHRINKSRC)
98100

99101
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
100102
# setting.
@@ -125,7 +127,8 @@ ASMSRC = $(PORTASM)
125127

126128
INCDIR = $(PORTINC) $(KERNINC) \
127129
$(HALINC) $(PLATFORMINC) $(BOARDINC) \
128-
$(CHIBIOS)/os/various
130+
$(CHIBIOS)/os/various \
131+
$(HEATSHRINKINC)
129132

130133
#
131134
# Project, sources and paths

heatshrink/LICENSE

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Copyright (c) 2013-2015, Scott Vokes <[email protected]>
2+
All rights reserved.
3+
4+
Permission to use, copy, modify, and/or distribute this software for any
5+
purpose with or without fee is hereby granted, provided that the above
6+
copyright notice and this permission notice appear in all copies.
7+
8+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

heatshrink/README.md

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# heatshrink
2+
3+
A data compression/decompression library for embedded/real-time systems.
4+
5+
6+
## Key Features:
7+
8+
- **Low memory usage (as low as 50 bytes)**
9+
It is useful for some cases with less than 50 bytes, and useful
10+
for many general cases with < 300 bytes.
11+
- **Incremental, bounded CPU use**
12+
You can chew on input data in arbitrarily tiny bites.
13+
This is a useful property in hard real-time environments.
14+
- **Can use either static or dynamic memory allocation**
15+
The library doesn't impose any constraints on memory management.
16+
- **ISC license**
17+
You can use it freely, even for commercial purposes.
18+
19+
20+
## Getting Started:
21+
22+
There is a standalone command-line program, `heatshrink`, but the
23+
encoder and decoder can also be used as libraries, independent of each
24+
other. To do so, copy `heatshrink_common.h`, `heatshrink_config.h`, and
25+
either `heatshrink_encoder.c` or `heatshrink_decoder.c` (and their
26+
respective header) into your project. For projects that use both,
27+
static libraries are built that use static and dynamic allocation.
28+
29+
Dynamic allocation is used by default, but in an embedded context, you
30+
probably want to statically allocate the encoder/decoder. Set
31+
`HEATSHRINK_DYNAMIC_ALLOC` to 0 in `heatshrink_config.h`.
32+
33+
34+
### Basic Usage
35+
36+
1. Allocate a `heatshrink_encoder` or `heatshrink_decoder` state machine
37+
using their `alloc` function, or statically allocate one and call their
38+
`reset` function to initialize them. (See below for configuration
39+
options.)
40+
41+
2. Use `sink` to sink an input buffer into the state machine. The
42+
`input_size` pointer argument will be set to indicate how many bytes of
43+
the input buffer were actually consumed. (If 0 bytes were conusmed, the
44+
buffer is full.)
45+
46+
3. Use `poll` to move output from the state machine into an output
47+
buffer. The `output_size` pointer argument will be set to indicate how
48+
many bytes were output, and the function return value will indicate
49+
whether further output is available. (The state machine may not output
50+
any data until it has received enough input.)
51+
52+
Repeat steps 2 and 3 to stream data through the state machine. Since
53+
it's doing data compression, the input and output sizes can vary
54+
significantly. Looping will be necessary to buffer the input and output
55+
as the data is processed.
56+
57+
4. When the end of the input stream is reached, call `finish` to notify
58+
the state machine that no more input is available. The return value from
59+
`finish` will indicate whether any output remains. if so, call `poll` to
60+
get more.
61+
62+
Continue calling `finish` and `poll`ing to flush remaining output until
63+
`finish` indicates that the output has been exhausted.
64+
65+
Sinking more data after `finish` has been called will not work without
66+
calling `reset` on the state machine.
67+
68+
69+
## Configuration
70+
71+
heatshrink has a couple configuration options, which impact its resource
72+
usage and how effectively it can compress data. These are set when
73+
dynamically allocating an encoder or decoder, or in `heatshrink_config.h`
74+
if they are statically allocated.
75+
76+
- `window_sz2`, `-w` in the CLI: Set the window size to 2^W bytes.
77+
78+
The window size determines how far back in the input can be searched for
79+
repeated patterns. A `window_sz2` of 8 will only use 256 bytes (2^8),
80+
while a `window_sz2` of 10 will use 1024 bytes (2^10). The latter uses
81+
more memory, but may also compress more effectively by detecting more
82+
repetition.
83+
84+
The `window_sz2` setting currently must be between 4 and 15.
85+
86+
- `lookahead_sz2`, `-l` in the CLI: Set the lookahead size to 2^L bytes.
87+
88+
The lookahead size determines the max length for repeated patterns that
89+
are found. If the `lookahead_sz2` is 4, a 50-byte run of 'a' characters
90+
will be represented as several repeated 16-byte patterns (2^4 is 16),
91+
whereas a larger `lookahead_sz2` may be able to represent it all at
92+
once. The number of bits used for the lookahead size is fixed, so an
93+
overly large lookahead size can reduce compression by adding unused
94+
size bits to small patterns.
95+
96+
The `lookahead_sz2` setting currently must be between 3 and the
97+
`window_sz2` - 1.
98+
99+
- `input_buffer_size` - How large an input buffer to use for the
100+
decoder. This impacts how much work the decoder can do in a single
101+
step, and a larger buffer will use more memory. An extremely small
102+
buffer (say, 1 byte) will add overhead due to lots of suspend/resume
103+
function calls, but should not change how well data compresses.
104+
105+
106+
### Recommended Defaults
107+
108+
For embedded/low memory contexts, a `window_sz2` in the 8 to 10 range is
109+
probably a good default, depending on how tight memory is. Smaller or
110+
larger window sizes may make better trade-offs in specific
111+
circumstances, but should be checked with representative data.
112+
113+
The `lookahead_sz2` should probably start near the `window_sz2`/2, e.g.
114+
-w 8 -l 4 or -w 10 -l 5. The command-line program can be used to measure
115+
how well test data works with different settings.
116+
117+
118+
## More Information and Benchmarks:
119+
120+
heatshrink is based on [LZSS], since it's particularly suitable for
121+
compression in small amounts of memory. It can use an optional, small
122+
[index] to make compression significantly faster, but otherwise can run
123+
in under 100 bytes of memory. The index currently adds 2^(window size+1)
124+
bytes to memory usage for compression, and temporarily allocates 512
125+
bytes on the stack during index construction (if the index is enabled).
126+
127+
For more information, see the [blog post] for an overview, and the
128+
`heatshrink_encoder.h` / `heatshrink_decoder.h` header files for API
129+
documentation.
130+
131+
[blog post]: http://spin.atomicobject.com/2013/03/14/heatshrink-embedded-data-compression/
132+
[index]: http://spin.atomicobject.com/2014/01/13/lightweight-indexing-for-embedded-systems/
133+
[LZSS]: http://en.wikipedia.org/wiki/Lempel-Ziv-Storer-Szymanski
134+
135+
136+
## Build Status
137+
138+
[![Build Status](https://travis-ci.org/atomicobject/heatshrink.png)](http://travis-ci.org/atomicobject/heatshrink)

heatshrink/heatshrink.mk

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
HEATSHRINKSRC = heatshrink/heatshrink_decoder.c \
2+
heatshrink/heatshrink_encoder.c
3+
4+
HEATSHRINKINC = heatshrink

heatshrink/heatshrink_common.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef HEATSHRINK_H
2+
#define HEATSHRINK_H
3+
4+
#define HEATSHRINK_AUTHOR "Scott Vokes <[email protected]>"
5+
#define HEATSHRINK_URL "https://github.com/atomicobject/heatshrink"
6+
7+
/* Version 0.4.1 */
8+
#define HEATSHRINK_VERSION_MAJOR 0
9+
#define HEATSHRINK_VERSION_MINOR 4
10+
#define HEATSHRINK_VERSION_PATCH 1
11+
12+
#define HEATSHRINK_MIN_WINDOW_BITS 4
13+
#define HEATSHRINK_MAX_WINDOW_BITS 15
14+
15+
#define HEATSHRINK_MIN_LOOKAHEAD_BITS 3
16+
17+
#define HEATSHRINK_LITERAL_MARKER 0x01
18+
#define HEATSHRINK_BACKREF_MARKER 0x00
19+
20+
#endif

heatshrink/heatshrink_config.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef HEATSHRINK_CONFIG_H
2+
#define HEATSHRINK_CONFIG_H
3+
4+
/* Should functionality assuming dynamic allocation be used? */
5+
#ifndef HEATSHRINK_DYNAMIC_ALLOC
6+
#define HEATSHRINK_DYNAMIC_ALLOC 0
7+
#endif
8+
9+
#if HEATSHRINK_DYNAMIC_ALLOC
10+
/* Optional replacement of malloc/free */
11+
#define HEATSHRINK_MALLOC(SZ) malloc(SZ)
12+
#define HEATSHRINK_FREE(P, SZ) free(P)
13+
#else
14+
/* Required parameters for static configuration */
15+
#define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 32
16+
#define HEATSHRINK_STATIC_WINDOW_BITS 13
17+
#define HEATSHRINK_STATIC_LOOKAHEAD_BITS 5
18+
#endif
19+
20+
/* Turn on logging for debugging. */
21+
#define HEATSHRINK_DEBUGGING_LOGS 0
22+
23+
/* Use indexing for faster compression. (This requires additional space.) */
24+
#define HEATSHRINK_USE_INDEX 1
25+
26+
#endif

0 commit comments

Comments
 (0)