Skip to content

Commit 084cd95

Browse files
committed
Add SBU_LoadLZSS.ino sketch + support for LZSS encoding
Remove symlink + cleanup code
1 parent 8755881 commit 084cd95

File tree

7 files changed

+1473
-1034
lines changed

7 files changed

+1473
-1034
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <MKRNB.h>
2+
#include <SBU.h>
3+
#include <FlashStorage.h>
4+
5+
#include "lzss.h"
6+
7+
FlashClass mcu_flash;
8+
9+
static char const BINARY[] =
10+
{
11+
#include "Binary.h"
12+
};
13+
14+
static char const CHECK_FILE[] =
15+
{
16+
"OK"
17+
};
18+
19+
static constexpr char CHECK_FILE_NAME[] = "UPDATE.OK";
20+
constexpr char UPDATE_FILE_NAME[] = "UPDATE.BIN.LZSS";
21+
22+
NBFileUtils fileUtils;
23+
bool update_available = false;
24+
25+
void setup() {
26+
Serial.begin(9600);
27+
while (!Serial) { }
28+
29+
unsigned long const start = millis();
30+
for (unsigned long now = millis(); !Serial && ((now - start) < 5000); now = millis()) { };
31+
32+
Serial.print("Accessing SARA Filesystem... ");
33+
if (!fileUtils.begin(false)) {
34+
Serial.println("failed.");
35+
return;
36+
37+
}
38+
Serial.println("OK");
39+
40+
uint32_t bytes_to_write = sizeof(BINARY);
41+
Serial.print("Size of BINARY.H: ");
42+
Serial.println(bytes_to_write);
43+
44+
Serial.print("Encoding \"BINARY.H\" into \"UPDATE.BIN.LZSS\" and writing it into the Sara-R410M module ... ");
45+
46+
/*
47+
* Set the lzss parameter in the following way:
48+
* - 0, false : you want to perform a LZSS encoding (.H -> .LZSS)
49+
* - SKETCH_START, true: you want to perform a LZSS decoding (.LZSS -> .H)
50+
*/
51+
lzss_init(0, false);
52+
53+
//Encode into .lzss and write to the Sara modem
54+
int bytes_written = lzss_encode(BINARY, bytes_to_write);
55+
56+
if (bytes_written == 0) {
57+
Serial.println("something went wrong!");
58+
} else {
59+
Serial.println("OK!");
60+
}
61+
62+
Serial.print("Size of UPDATE.BIN.LZSS: ");
63+
Serial.println(bytes_written);
64+
65+
auto status = 0;
66+
while (status != 2) {
67+
status = fileUtils.createFile(CHECK_FILE_NAME, CHECK_FILE, 2);
68+
delay(100);
69+
}
70+
71+
Serial.println("Please type \"restart\" to apply the update");
72+
update_available = true;
73+
}
74+
75+
76+
void loop() {
77+
if (update_available == true) {
78+
String command = Serial.readStringUntil('\n');
79+
if (command.indexOf("restart") >= 0) {
80+
NVIC_SystemReset();
81+
}
82+
}
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/**************************************************************************************
2+
INCLUDE
3+
**************************************************************************************/
4+
5+
#include "lzss.h"
6+
7+
#include <stdlib.h>
8+
#include <stdint.h>
9+
10+
#include <MKRNB.h>
11+
#include <FlashStorage.h>
12+
13+
/**************************************************************************************
14+
DEFINE
15+
**************************************************************************************/
16+
17+
#define EI 11 /* typically 10..13 */
18+
#define EJ 4 /* typically 4..5 */
19+
#define P 1 /* If match length <= P then output one character */
20+
#define N (1 << EI) /* buffer size */
21+
#define F ((1 << EJ) + 1) /* lookahead buffer size */
22+
23+
#define LZSS_EOF (-1)
24+
25+
#define FPUTC_BUF_SIZE (512)
26+
#define FGETC_BUF_SIZE (512)
27+
28+
/**************************************************************************************
29+
GLOBAL VARIABLES
30+
**************************************************************************************/
31+
32+
extern NBFileUtils fileUtils;
33+
extern FlashClass mcu_flash;
34+
extern const char * UPDATE_FILE_NAME_LZSS;
35+
36+
static uint32_t SKETCH_START = 0;
37+
static uint32_t LZSS_FILE_SIZE = 0;
38+
39+
int bit_buffer = 0, bit_mask = 128;
40+
unsigned long codecount = 0, textcount = 0;
41+
unsigned char buffer[N * 2];
42+
43+
static char write_buf[FPUTC_BUF_SIZE];
44+
static size_t write_buf_num_bytes = 0;
45+
static size_t bytes_written_fputc = 0;
46+
static size_t bytes_written_flash = 0;
47+
static uint32_t flash_addr = 0;
48+
49+
bool fromLZSStoBIN = true;
50+
bool append = false;
51+
bool endOfFile = false;
52+
53+
/**************************************************************************************
54+
PUBLIC FUNCTIONS
55+
**************************************************************************************/
56+
57+
void lzss_init(uint32_t const sketch_start, bool LZSStoBIN)
58+
{
59+
fromLZSStoBIN = LZSStoBIN;
60+
if (LZSStoBIN) {
61+
SKETCH_START = sketch_start;
62+
flash_addr = sketch_start;
63+
LZSS_FILE_SIZE = fileUtils.listFile("UPDATE.BIN.LZSS");
64+
}
65+
}
66+
67+
void lzss_flush()
68+
{
69+
bytes_written_fputc += write_buf_num_bytes;
70+
71+
if (fromLZSStoBIN) {
72+
/* Only write to the flash once we've surpassed
73+
* the SBU in the update binary.
74+
*/
75+
if (bytes_written_fputc > (SKETCH_START - 0x2000))
76+
{
77+
mcu_flash.write((void*)flash_addr, write_buf, write_buf_num_bytes);
78+
flash_addr += write_buf_num_bytes;
79+
}
80+
} else {
81+
fileUtils.downloadFile("UPDATE.BIN.LZSS", write_buf, write_buf_num_bytes, append);
82+
append = true;
83+
}
84+
85+
write_buf_num_bytes = 0;
86+
}
87+
88+
/**************************************************************************************
89+
PRIVATE FUNCTIONS
90+
**************************************************************************************/
91+
92+
void lzss_fputc(int const c)
93+
{
94+
/* Buffer the decompressed data into a buffer so
95+
* we can perform block writes and don't need to
96+
* write every byte singly on the flash (which
97+
* wouldn't be possible anyway).
98+
*/
99+
write_buf[write_buf_num_bytes] = static_cast<char>(c);
100+
write_buf_num_bytes++;
101+
102+
/* The write buffer is full of decompressed
103+
* data, write it to the flash now.
104+
*/
105+
if (write_buf_num_bytes == FPUTC_BUF_SIZE || endOfFile)
106+
lzss_flush();
107+
}
108+
109+
/**************************************************************************************
110+
LZSS FUNCTIONS
111+
**************************************************************************************/
112+
113+
void putbit1(void)
114+
{
115+
bit_buffer |= bit_mask;
116+
if ((bit_mask >>= 1) == 0) {
117+
lzss_fputc(bit_buffer);
118+
bit_buffer = 0; bit_mask = 128;
119+
}
120+
}
121+
122+
void putbit0(void)
123+
{
124+
if ((bit_mask >>= 1) == 0) {
125+
lzss_fputc(bit_buffer);
126+
bit_buffer = 0; bit_mask = 128;
127+
}
128+
}
129+
130+
void flush_bit_buffer(void)
131+
{
132+
if (bit_mask != 128) {
133+
//if (fputc(bit_buffer, outfile) == EOF) error();
134+
lzss_fputc(bit_buffer);
135+
codecount++;
136+
}
137+
}
138+
139+
void output1(int c)
140+
{
141+
int mask;
142+
143+
putbit1();
144+
mask = 256;
145+
while (mask >>= 1) {
146+
if (c & mask) putbit1();
147+
else putbit0();
148+
}
149+
}
150+
151+
void output2(int x, int y)
152+
{
153+
int mask;
154+
155+
putbit0();
156+
mask = N;
157+
while (mask >>= 1) {
158+
if (x & mask) putbit1();
159+
else putbit0();
160+
}
161+
mask = (1 << EJ);
162+
while (mask >>= 1) {
163+
if (y & mask) putbit1();
164+
else putbit0();
165+
}
166+
}
167+
168+
int lzss_encode(const char buf_in[], uint32_t size)
169+
{
170+
int i, j, f1, x, y, r, s, bufferend, c;
171+
172+
for (i = 0; i < N - F; i++) buffer[i] = ' ';
173+
for (i = N - F; i < N * 2; i++) {
174+
if (textcount >= size) {
175+
endOfFile = true;
176+
break;
177+
} else {
178+
buffer[i] = buf_in[textcount];
179+
textcount++;
180+
}
181+
}
182+
bufferend = i; r = N - F; s = 0;
183+
while (r < bufferend) {
184+
f1 = (F <= bufferend - r) ? F : bufferend - r;
185+
x = 0; y = 1; c = buffer[r];
186+
for (i = r - 1; i >= s; i--)
187+
if (buffer[i] == c) {
188+
for (j = 1; j < f1; j++)
189+
if (buffer[i + j] != buffer[r + j]) break;
190+
if (j > y) {
191+
x = i; y = j;
192+
}
193+
}
194+
if (y <= P) { y = 1; output1(c); }
195+
else output2(x & (N - 1), y - 2);
196+
r += y; s += y;
197+
if (r >= N * 2 - F) {
198+
for (i = 0; i < N; i++) buffer[i] = buffer[i + N];
199+
bufferend -= N; r -= N; s -= N;
200+
while (bufferend < N * 2) {
201+
if (textcount >= size) {
202+
endOfFile = true;
203+
break;
204+
} else {
205+
buffer[bufferend++] = buf_in[textcount];
206+
textcount++;
207+
}
208+
}
209+
}
210+
}
211+
flush_bit_buffer();
212+
213+
return bytes_written_fputc;
214+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef SBU_LZSS_H_
2+
#define SBU_LZSS_H_
3+
4+
/**************************************************************************************
5+
INCLUDE
6+
**************************************************************************************/
7+
8+
#include <stdint.h>
9+
10+
/**************************************************************************************
11+
FUNCTION DEFINITION
12+
**************************************************************************************/
13+
14+
void lzss_init(uint32_t const sketch_start, bool LZSStoBIN);
15+
void lzss_flush();
16+
int lzss_encode(const char buf_in[], uint32_t size);
17+
18+
#endif /* SBU_LZSS_H_ */

libraries/SBU/extras/SBUBoot/SBUBoot.ino

+4-4
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,20 @@ int main()
5252
// Try to update only if update file
5353
// has been download successfully.
5454

55-
if (fileUtils.existFile(CHECK_FILE_NAME))
55+
if (fileUtils.listFile(CHECK_FILE_NAME))
5656
{
5757
/*This is for LZSS compressed binaries. */
58-
if (fileUtils.existFile(UPDATE_FILE_NAME_LZSS))
58+
if (fileUtils.listFile(UPDATE_FILE_NAME_LZSS))
5959
{
60-
/* Erase the complete flash starting from the SSU forward
60+
/* Erase the complete flash starting from the SBU forward
6161
* because we've got no possibility of knowing how large
6262
* the decompressed binary will finally be.
6363
*/
6464
mcu_flash.erase((void*)SKETCH_START, 0x40000 - (uint32_t)SKETCH_START);
6565
/* Initialize the lzss module with the data which
6666
* it requires.
6767
*/
68-
lzss_init((uint32_t)SKETCH_START);
68+
lzss_init((uint32_t)SKETCH_START, true);
6969
/* During the process of decoding UPDATE.BIN.LZSS
7070
* is decompressed and stored as UPDATE.BIN.
7171
*/

0 commit comments

Comments
 (0)