Skip to content

Commit 14eb591

Browse files
authored
Merge pull request #237 from facchinm/rp2040_iot_cloud_ota
Improve SFU for Nano RP2040 OTA
2 parents e5bf677 + 96f23a1 commit 14eb591

15 files changed

+4370
-3916
lines changed

libraries/SFU/extra/build.sh

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
3+
mbed config root .
4+
mbed deploy
5+
mbed target NANO_RP2040_CONNECT
6+
mbed toolchain GCC_ARM
7+
mbed compile
8+
set -e
9+
xxd -i BUILD/NANO_RP2040_CONNECT/GCC_ARM/extra_application.bin > ../src/rp2040.h
10+
set +e
11+
#remove last 2 lines
12+
sed -i '$d' ../src/rp2040.h
13+
sed -i '$d' ../src/rp2040.h
14+
#remove first line
15+
sed -i '1d' ../src/rp2040.h

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_ */

0 commit comments

Comments
 (0)