Skip to content

Commit b473139

Browse files
Enable use of uninitialized_ram() macro (#1199)
The uninitted RAM macro would fail because the OTA code would clear out the first 50KB or so of RAM to copy its code and global values. Move all global values to the end of RAM in OTA, and then align any uninitted vars to a 16KB unit to ensure it won't appear in the 1st part of RAM that is still needed to copy the OTA executable. In the normal case, without any uninit_ram vars, no additional space is used. When uninit_ram is used, up to 16KB of space may be lost to get that alignment, but it will work properly. Fixes #1188
1 parent 7afcec8 commit b473139

File tree

7 files changed

+46
-37
lines changed

7 files changed

+46
-37
lines changed

lib/memmap_default.ld

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,6 @@ SECTIONS
191191
__data_end__ = .;
192192
} > RAM AT> FLASH
193193

194-
.uninitialized_data (COPY): {
195-
. = ALIGN(4);
196-
*(.uninitialized_data*)
197-
} > RAM
198-
199194
/* Start and end symbols must be word-aligned */
200195
.scratch_x : {
201196
__scratch_x_start__ = .;
@@ -213,7 +208,7 @@ SECTIONS
213208
} > SCRATCH_Y AT > FLASH
214209
__scratch_y_source__ = LOADADDR(.scratch_y);
215210

216-
.bss : {
211+
.bss : {
217212
. = ALIGN(4);
218213
__bss_start__ = .;
219214
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
@@ -222,6 +217,15 @@ SECTIONS
222217
__bss_end__ = .;
223218
} > RAM
224219

220+
/* At most one of the following two will be engaged, depending on the SDK version */
221+
.uninitialized_ram BLOCK(16k) (NOLOAD) : {
222+
*(.uninitialized_ram*)
223+
} > RAM
224+
225+
.uninitialized_data BLOCK(16k) (NOLOAD) : {
226+
*(.uninitialized_data*)
227+
} > RAM
228+
225229
.heap (COPY):
226230
{
227231
__end__ = .;

lib/ota.o

0 Bytes
Binary file not shown.

ota/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ target_compile_definitions(ota PUBLIC
5050
target_compile_options(ota PUBLIC
5151
-fno-exceptions
5252
-Os
53+
-Wall
54+
-Werror
5355
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
5456
)
5557

ota/memmap_ota.ld

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,28 @@
2323

2424
MEMORY
2525
{
26-
FLASH(rx) : ORIGIN = 0x10000100, LENGTH = 16384k
27-
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
26+
FLASH(rx) : ORIGIN = 0x10000100, LENGTH = 16384k
27+
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 212k
28+
/* We split RAM into main (where the flash->ram code will be copied) and GLOBALS which has all large arrays */
29+
/* By placing those arrays at the end of RAM we can avoid overwriting uninitialize_ram from the main app as */
30+
/* long as those vars are stored after 12K by using an alignment value in the main app linker file. */
31+
GLOBALS(rwx) : ORIGIN = 0x20035000, LENGTH = 44k
2832
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
2933
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
3034
}
3135

3236
ENTRY(_entry_point)
3337

34-
SECTIONS
35-
{
38+
SECTIONS {
3639
/* Second stage bootloader is prepended to the image. It must be 256 bytes big
3740
and checksummed. It is usually built by the boot_stage2 target
3841
in the Raspberry Pi Pico SDK
3942
*/
4043

44+
/* Make sure the globals are not copied/etc. They're empty RAM we will init ourselves */
45+
.globals (NOLOAD) : {
46+
} > GLOBALS
47+
4148
.flash_begin : {
4249
__flash_binary_start = .;
4350
} > FLASH
@@ -72,14 +79,12 @@ SECTIONS
7279
. = ALIGN(4);
7380
} > FLASH
7481

75-
.ARM.extab :
76-
{
82+
.ARM.extab : {
7783
*(.ARM.extab* .gnu.linkonce.armextab.*)
7884
} > FLASH
7985

8086
__exidx_start = .;
81-
.ARM.exidx :
82-
{
87+
.ARM.exidx : {
8388
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
8489
} > FLASH
8590
__exidx_end = .;
@@ -188,7 +193,7 @@ SECTIONS
188193
} > SCRATCH_Y AT > FLASH
189194
__scratch_y_source__ = LOADADDR(.scratch_y);
190195

191-
.bss : {
196+
.bss : {
192197
. = ALIGN(4);
193198
__bss_start__ = .;
194199
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
@@ -197,8 +202,7 @@ SECTIONS
197202
__bss_end__ = .;
198203
} > RAM
199204

200-
.heap (COPY):
201-
{
205+
.heap (COPY): {
202206
__end__ = .;
203207
end = __end__;
204208
*(.heap*)
@@ -214,12 +218,10 @@ SECTIONS
214218
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
215219
* stack is not used then all of SCRATCH_X is free.
216220
*/
217-
.stack1_dummy (COPY):
218-
{
221+
.stack1_dummy (COPY): {
219222
*(.stack1*)
220223
} > SCRATCH_X
221-
.stack_dummy (COPY):
222-
{
224+
.stack_dummy (COPY): {
223225
*(.stack*)
224226
} > SCRATCH_Y
225227

ota/ota.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ void dumphex(uint32_t x) {
5353
#endif
5454
}
5555

56-
static OTACmdPage _ota_cmd;
57-
56+
extern OTACmdPage _ota_cmd;
5857
void do_ota() {
5958
if (*__FS_START__ == *__FS_END__) {
6059
return;
@@ -165,7 +164,7 @@ void do_ota() {
165164

166165
#pragma GCC push_options
167166
#pragma GCC optimize("O0")
168-
int main(int a, unsigned char **b) {
167+
int main(int a, char **b) {
169168
(void) a;
170169
(void) b;
171170

@@ -190,7 +189,7 @@ int main(int a, unsigned char **b) {
190189
fcn();
191190

192191
// Should never get here!
193-
return 0;
192+
return *sp;
194193
}
195194
#pragma GCC pop_options
196195

ota/ota_lfs.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "../libraries/LittleFS/lib/littlefs/lfs_util.h"
2727
#include "./uzlib/src/uzlib.h"
2828

29+
OTACmdPage __attribute__((section (".globals"))) _ota_cmd;
30+
2931
static lfs_t _lfs;
3032
static struct lfs_config _lfs_cfg;
3133

@@ -70,9 +72,9 @@ static int lfs_flash_sync(const struct lfs_config *c) {
7072
return 0;
7173
}
7274

73-
uint8_t _read_buffer[256];
74-
uint8_t _prog_buffer[256];
75-
uint8_t _lookahead_buffer[256];
75+
uint8_t __attribute__((section (".globals"))) _read_buffer[256];
76+
uint8_t __attribute__((section (".globals"))) _prog_buffer[256];
77+
uint8_t __attribute__((section (".globals"))) _lookahead_buffer[256];
7678
bool lfsMount(uint8_t *start, uint32_t blockSize, uint32_t size) {
7779
_start = start;
7880
_blockSize = blockSize;
@@ -104,16 +106,16 @@ bool lfsMount(uint8_t *start, uint32_t blockSize, uint32_t size) {
104106
static bool _gzip = false;
105107
static lfs_file_t _file;
106108

107-
static unsigned char __attribute__((aligned(4))) uzlib_read_buff[4096];
108-
static unsigned char gzip_dict[32768];
109-
static uint8_t _flash_buff[4096]; // no room for this on the stack
110-
static struct uzlib_uncomp m_uncomp;
109+
unsigned char __attribute__((section (".globals"))) uzlib_read_buff[4096];
110+
unsigned char __attribute__((section (".globals"))) gzip_dict[32768];
111+
uint8_t __attribute__((section (".globals")))_flash_buff[4096]; // no room for this on the stack
112+
struct uzlib_uncomp __attribute__((section (".globals"))) m_uncomp;
111113

112-
static uint8_t _ota_buff[256];
113-
static struct lfs_file_config _ota_cfg = { (void *)_ota_buff, NULL, 0 };
114+
uint8_t __attribute__((section (".globals")))_ota_buff[256];
115+
struct lfs_file_config _ota_cfg = { (void *)_ota_buff, NULL, 0 };
114116

115-
static uint8_t _file_buff[256];
116-
static struct lfs_file_config _file_cfg = { (void *)_file_buff, NULL, 0 };
117+
uint8_t __attribute__((section (".globals")))_file_buff[256];
118+
struct lfs_file_config _file_cfg = { (void *)_file_buff, NULL, 0 };
117119

118120
bool lfsReadOTA(OTACmdPage *ota, uint32_t *blockToErase) {
119121
lfs_file_t f;

platform.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ recipe.output.save_file={build.project_name}.{build.variant}.{build.preferred_ou
153153
## Compute size
154154
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
155155
recipe.size.regex=^(?:\.boot2|\.text|\.rodata|\.ARM\.extab|\.ARM\.exidx)\s+([0-9]+).*
156-
recipe.size.regex.data=^(?:\.data|\.bss|\.ram_vector_table|\.uninitialized_data)\s+([0-9]+).*
156+
recipe.size.regex.data=^(?:\.data|\.bss|\.ram_vector_table|\.uninitialized_ram|\.uninitialized_data)\s+([0-9]+).*
157157

158158

159159
# Debugging

0 commit comments

Comments
 (0)