move to 16kb fpga ring buffer size, recompile fullimage and lower stack size to 7160 bytes

This commit is contained in:
iceman1001
2026-09-01 10:14:35 +02:00
parent ea5b017299
commit 83c3f81b1b
3 changed files with 50 additions and 2 deletions
+12
View File
@@ -3,6 +3,18 @@
mcu_flash_size = 512K;
mcu_sram_size = 64K;
/* Stack for the OS image. Default in ldscript.common is 8488, but the AT91 only
* has 64K of SRAM and the stack is carved out of the same pool as BigBuf:
* BigBuf = _stack_start - __bss_end__, _stack_start = sram_end - stacksize - commonarea
* so every byte here is a byte BigBuf does not get. Worst-case stack measured
* across all 41 standalone modes (-fstack-usage + call graph, VLA bounds added
* in) is 5408 bytes, so 7168 keeps ~1.7 kB of headroom and hands 1320 bytes back
* to BigBuf. Re-measure before lowering this further - overflow grows silently
* down into the top of BigBuf, where BigBuf_malloc() hands out chunks.
* Not set for AT32/PM5, which has 512K of SRAM and no such pressure.
*/
stacksize = 7168;
mcu_flash_base_addr = 0x00100000;
mcu_sram_base_addr = 0x00200000;
+12 -1
View File
@@ -32,7 +32,18 @@
#define FPGA_TYPE "2s30vq100"
#define FPGA_CONFIG_SIZE 42336L // FPGA .bit file rounded up to next multiple of FPGA_INTERLEAVE_SIZE
#endif
#define FPGA_RING_BUFFER_BYTES (1024 * 30)
// LZ4 sliding-window / staging size for ONE compressed block, not the image:
// fpga_compress chops the interleaved bitstreams into blocks of at most this
// size, and the ARM decompresses them one at a time while DownloadFPGA() shifts
// the bytes out to the FPGA. It is allocated out of BigBuf, which on AT91 is
// only ~31-33 kB, so 30 kB left nothing for the caller.
// Smaller window = slightly worse compression
// Measured on flash:
// 30 kB -> 102555 bytes
// 16 kB -> 107121 bytes
// This does NOT bound the firmware's .data section
// fpga_compress gives the single-input case its own 1 MB block, because start.c only decompresses one.
#define FPGA_RING_BUFFER_BYTES (1024 * 16)
#define FPGA_TRACE_SIZE 3072
// definitions for multiple FPGA config files support
+26 -1
View File
@@ -83,6 +83,19 @@ static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) {
} while (all_feof(infile, num_infiles) == false);
// Block size for the LZ4 stream. Two very different consumers:
//
// - many infiles: the interleaved FPGA bitstreams. armsrc decompresses them
// one block at a time into a FPGA_RING_BUFFER_BYTES buffer taken from BigBuf
// (see get_from_fpga_combined_stream()), so the block size must match.
//
// - one infile: the firmware's .data section. start.c's
// uncompress_data_section() reads ONE 4-byte length and does ONE
// LZ4_decompress_safe(), so this must come out as a SINGLE block - it has no
// loop over blocks, and a short result is not treated as an error, so a
// second block would silently leave the tail of .data uninitialized.
// That is why it gets its own, much larger, block size and must not be
// tied to FPGA_RING_BUFFER_BYTES.
uint32_t buffer_size = FPGA_RING_BUFFER_BYTES;
if (num_infiles == 1) {
@@ -110,12 +123,24 @@ static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) {
LZ4_streamHC_t *lz4_streamhc = LZ4_createStreamHC();
LZ4_resetStreamHC_fast(lz4_streamhc, LZ4HC_CLEVEL_MAX);
if (num_infiles == 1 && total_size > buffer_size) {
fprintf(stderr, "error: %u bytes does not fit in a single %u byte block, and start.c only decompresses one\n"
, total_size
, buffer_size
);
free(ring_buffer);
free(outbuf);
free(fpga_config);
LZ4_freeStreamHC(lz4_streamhc);
return (EXIT_FAILURE);
}
int current_in = 0;
int current_out = 0;
while (current_in < total_size) {
int bytes_to_copy = MIN(FPGA_RING_BUFFER_BYTES, (total_size - current_in));
int bytes_to_copy = MIN(buffer_size, (total_size - current_in));
memcpy(ring_buffer, fpga_config + current_in, bytes_to_copy);