Skip to content

Commit 96f23a1

Browse files
committed
TEMP: SFU: add decompression
1 parent dbe4cd9 commit 96f23a1

File tree

6 files changed

+2394
-1706
lines changed

6 files changed

+2394
-1706
lines changed

libraries/SFU/extra/double_tap.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
extern "C" {
2+
#include "pico.h"
3+
#include "pico/time.h"
4+
#include "pico/bootrom.h"
5+
}
6+
7+
#define LED_DEFAULT 6
8+
9+
// Doesn't make any sense for a RAM only binary
10+
#if !PICO_NO_FLASH
11+
12+
static const uint32_t magic_token[] = {
13+
0xf01681de, 0xbd729b29, 0xd359be7a,
14+
};
15+
16+
static uint32_t __uninitialized_ram(magic_location)[count_of(magic_token)];
17+
18+
// run at initialization time
19+
static void boot_double_tap_check() {
20+
for (uint i = 0; i < count_of(magic_token); i++) {
21+
if (magic_location[i] != magic_token[i]) {
22+
// Arm for 500 ms then disarm and continue booting
23+
for (i = 0; i < count_of(magic_token); i++) {
24+
magic_location[i] = magic_token[i];
25+
}
26+
busy_wait_us(500000);
27+
magic_location[0] = 0;
28+
return;
29+
}
30+
}
31+
32+
magic_location[0] = 0;
33+
reset_usb_boot(1 << LED_DEFAULT, 0);
34+
}
35+
36+
class DoubleTap {
37+
public:
38+
DoubleTap() {
39+
boot_double_tap_check();
40+
}
41+
};
42+
43+
DoubleTap dt __attribute__ ((init_priority (101)));
44+
45+
#endif

libraries/SFU/extra/lzss.cpp

+221
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/**************************************************************************************
2+
INCLUDE
3+
**************************************************************************************/
4+
5+
#include "mbed.h"
6+
#include "FlashIAPBlockDevice.h"
7+
8+
#include "lzss.h"
9+
10+
#include <stdlib.h>
11+
#include <stdint.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 (256)
26+
#define FGETC_BUF_SIZE (256)
27+
28+
/**************************************************************************************
29+
GLOBAL VARIABLES
30+
**************************************************************************************/
31+
32+
extern const char * UPDATE_FILE_NAME_LZSS;
33+
34+
static uint32_t SKETCH_START = 0;
35+
static uint32_t LZSS_FILE_SIZE = 0;
36+
static FILE* update_file = 0;
37+
static FlashIAP* flash;
38+
39+
int bit_buffer = 0, bit_mask = 128;
40+
unsigned char buffer[N * 2];
41+
42+
static char write_buf[FPUTC_BUF_SIZE];
43+
static size_t write_buf_num_bytes = 0;
44+
static size_t bytes_written_fputc = 0;
45+
static size_t bytes_written_flash = 0;
46+
static uint32_t flash_addr = 0;
47+
48+
/**************************************************************************************
49+
PUBLIC FUNCTIONS
50+
**************************************************************************************/
51+
52+
void lzss_init(FILE* update_file_ptr, FlashIAP* _flash, uint32_t const sketch_start, uint32_t const lzss_file_size)
53+
{
54+
SKETCH_START = sketch_start;
55+
flash_addr = sketch_start + XIP_BASE;
56+
update_file = update_file_ptr;
57+
LZSS_FILE_SIZE = lzss_file_size;
58+
flash = _flash;
59+
}
60+
61+
void lzss_flush()
62+
{
63+
bytes_written_fputc += write_buf_num_bytes;
64+
65+
/* Only write to the flash once we've surpassed
66+
* the SSU in the update binary.
67+
*/
68+
if (bytes_written_fputc > SKETCH_START)
69+
{
70+
flash->program(write_buf, flash_addr, write_buf_num_bytes);
71+
flash_addr += write_buf_num_bytes;
72+
}
73+
74+
write_buf_num_bytes = 0;
75+
}
76+
77+
/**************************************************************************************
78+
PRIVATE FUNCTIONS
79+
**************************************************************************************/
80+
81+
void lzss_fputc(int const c)
82+
{
83+
/* Buffer the decompressed data into a buffer so
84+
* we can perform block writes and don't need to
85+
* write every byte singly on the flash (which
86+
* wouldn't be possible anyway).
87+
*/
88+
write_buf[write_buf_num_bytes] = static_cast<char>(c);
89+
write_buf_num_bytes++;
90+
91+
/* The write buffer is full of decompressed
92+
* data, write it to the flash now.
93+
*/
94+
if (write_buf_num_bytes == FPUTC_BUF_SIZE)
95+
lzss_flush();
96+
}
97+
98+
int lzss_fgetc()
99+
{
100+
static uint8_t read_buf[FGETC_BUF_SIZE];
101+
static size_t read_buf_pos = FGETC_BUF_SIZE;
102+
static size_t bytes_read_fgetc = 0;
103+
static size_t bytes_read_from_modem = 0;
104+
105+
/* lzss_file_size is set within SSUBoot:main
106+
* and contains the size of the LZSS file. Once
107+
* all those bytes have been read its time to return
108+
* LZSS_EOF in order to signal that the end of
109+
* the file has been reached.
110+
*/
111+
if (bytes_read_fgetc == LZSS_FILE_SIZE)
112+
return LZSS_EOF;
113+
114+
/* If there is no data left to be read from the read buffer
115+
* than read a new block and store it into the read buffer.
116+
*/
117+
if (read_buf_pos == FGETC_BUF_SIZE)
118+
{
119+
/* Read the next block from the flash memory. */
120+
bytes_read_from_modem += fread(read_buf, 1, FGETC_BUF_SIZE, update_file);
121+
/* Reset the read buffer position. */
122+
read_buf_pos = 0;
123+
}
124+
125+
uint8_t const c = read_buf[read_buf_pos];
126+
read_buf_pos++;
127+
bytes_read_fgetc++;
128+
129+
return c;
130+
}
131+
132+
/**************************************************************************************
133+
LZSS FUNCTIONS
134+
**************************************************************************************/
135+
136+
void putbit1(void)
137+
{
138+
bit_buffer |= bit_mask;
139+
if ((bit_mask >>= 1) == 0) {
140+
lzss_fputc(bit_buffer);
141+
bit_buffer = 0; bit_mask = 128;
142+
}
143+
}
144+
145+
void putbit0(void)
146+
{
147+
if ((bit_mask >>= 1) == 0) {
148+
lzss_fputc(bit_buffer);
149+
bit_buffer = 0; bit_mask = 128;
150+
}
151+
}
152+
153+
void output1(int c)
154+
{
155+
int mask;
156+
157+
putbit1();
158+
mask = 256;
159+
while (mask >>= 1) {
160+
if (c & mask) putbit1();
161+
else putbit0();
162+
}
163+
}
164+
165+
void output2(int x, int y)
166+
{
167+
int mask;
168+
169+
putbit0();
170+
mask = N;
171+
while (mask >>= 1) {
172+
if (x & mask) putbit1();
173+
else putbit0();
174+
}
175+
mask = (1 << EJ);
176+
while (mask >>= 1) {
177+
if (y & mask) putbit1();
178+
else putbit0();
179+
}
180+
}
181+
182+
int getbit(int n) /* get n bits */
183+
{
184+
int i, x;
185+
static int buf, mask = 0;
186+
187+
x = 0;
188+
for (i = 0; i < n; i++) {
189+
if (mask == 0) {
190+
if ((buf = lzss_fgetc()) == LZSS_EOF) return LZSS_EOF;
191+
mask = 128;
192+
}
193+
x <<= 1;
194+
if (buf & mask) x++;
195+
mask >>= 1;
196+
}
197+
return x;
198+
}
199+
200+
void lzss_decode(void)
201+
{
202+
int i, j, k, r, c;
203+
204+
for (i = 0; i < N - F; i++) buffer[i] = ' ';
205+
r = N - F;
206+
while ((c = getbit(1)) != LZSS_EOF) {
207+
if (c) {
208+
if ((c = getbit(8)) == LZSS_EOF) break;
209+
lzss_fputc(c);
210+
buffer[r++] = c; r &= (N - 1);
211+
} else {
212+
if ((i = getbit(EI)) == LZSS_EOF) break;
213+
if ((j = getbit(EJ)) == LZSS_EOF) break;
214+
for (k = 0; k <= j + 1; k++) {
215+
c = buffer[(i + k) & (N - 1)];
216+
lzss_fputc(c);
217+
buffer[r++] = c; r &= (N - 1);
218+
}
219+
}
220+
}
221+
}

libraries/SFU/extra/lzss.h

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef SSU_LZSS_H_
2+
#define SSU_LZSS_H_
3+
4+
/**************************************************************************************
5+
INCLUDE
6+
**************************************************************************************/
7+
8+
#include <stdint.h>
9+
10+
/**************************************************************************************
11+
FUNCTION DEFINITION
12+
**************************************************************************************/
13+
14+
void lzss_init(FILE* update_file_ptr, FlashIAP* _flash, uint32_t const sketch_start, uint32_t const lzss_file_size);
15+
void lzss_decode();
16+
void lzss_flush();
17+
18+
#endif /* SSU_LZSS_H_ */

libraries/SFU/extra/main.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#define SD_MOUNT_PATH "ota"
99
#define FULL_UPDATE_FILE_PATH "/" SD_MOUNT_PATH "/" MBED_CONF_APP_UPDATE_FILE
10+
#define FULL_UPDATE_FILE_PATH_COMPRESSED FULL_UPDATE_FILE_PATH ".LZSS"
1011

1112
#define POST_APPLICATION_ADDR 0x10000
1213
#define VERSION 1
@@ -22,6 +23,9 @@ FATFileSystem fs(SD_MOUNT_PATH);
2223
FlashIAP flash;
2324

2425
void apply_update(FILE *file, uint32_t address);
26+
int verify_and_decompress(FILE *file);
27+
int verify(FILE* update_file);
28+
int decompress_and_flash(FILE* update_file, FlashIAP* flash, size_t offset);
2529

2630
int main()
2731
{
@@ -35,6 +39,22 @@ int main()
3539
goto boot;
3640
}
3741

42+
file = fopen(FULL_UPDATE_FILE_PATH_COMPRESSED, "rb");
43+
if (file != NULL) {
44+
45+
printf("Compressed firmware update found\r\n");
46+
47+
int err = verify_and_decompress(file);
48+
49+
fclose(file);
50+
remove(FULL_UPDATE_FILE_PATH_COMPRESSED);
51+
if (err != 0) {
52+
/* TODO */
53+
printf("Error while decompressing or flashing, erase the entire flash to enter ROM loader\n");
54+
}
55+
goto boot;
56+
}
57+
3858
file = fopen(FULL_UPDATE_FILE_PATH, "rb");
3959
if (file != NULL) {
4060
printf("Firmware update found\r\n");
@@ -57,6 +77,16 @@ int main()
5777
mbed_start_application(XIP_BASE + POST_APPLICATION_ADDR + 0x100);
5878
}
5979

80+
int verify_and_decompress(FILE* file) {
81+
int err = verify(file);
82+
if (err != 0) {
83+
printf("Error during verification\n");
84+
return err;
85+
}
86+
err = decompress_and_flash(file, &flash, POST_APPLICATION_ADDR);
87+
return err;
88+
}
89+
6090
void apply_update(FILE *file, uint32_t address)
6191
{
6292
fseek(file, 0, SEEK_END);

0 commit comments

Comments
 (0)