take some steps towards reducing memory footprint in stack buffers

sipo
Ondřej Hruška 7 years ago
parent d49081b190
commit 7280338f8b
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 2
      USB/usbd_desc.c
  2. 3
      comm/messages.c
  3. 10
      debug.h
  4. 6
      framework/resources.c
  5. 15
      framework/settings.c
  6. 4
      platform/plat_compat.h
  7. 13
      utils/hexdump.c
  8. 27
      utils/ini_writer.c
  9. 15
      utils/ini_writer.h
  10. 3
      utils/macro.h
  11. 1
      utils/stacksmon.c
  12. 2
      vfs/vfs_user.c

@ -246,7 +246,7 @@ uint8_t * USBD_FS_ManufacturerStrDescriptor( USBD_SpeedTypeDef speed , uint16_t
*/ */
uint8_t * USBD_FS_SerialStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length) uint8_t * USBD_FS_SerialStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
{ {
char buff[25]; char buff[26];
fixup_sprintf(buff, "%08"PRIX32"-%08"PRIX32"-%08"PRIX32, fixup_sprintf(buff, "%08"PRIX32"-%08"PRIX32"-%08"PRIX32,
LL_GetUID_Word0(), LL_GetUID_Word0(),
LL_GetUID_Word1(), LL_GetUID_Word1(),

@ -62,10 +62,13 @@ static void settings_bulkread_cb(BulkRead *bulk, uint32_t chunk, uint8_t *buffer
// clean-up request // clean-up request
if (buffer == NULL) { if (buffer == NULL) {
free(bulk); free(bulk);
iw_end();
dbg("INI read complete."); dbg("INI read complete.");
return; return;
} }
if (bulk->offset == 0) iw_begin();
IniWriter iw = iw_init((char *)buffer, bulk->offset, chunk); IniWriter iw = iw_init((char *)buffer, bulk->offset, chunk);
settings_build_units_ini(&iw); settings_build_units_ini(&iw);
} }

@ -17,7 +17,15 @@ int PUTS(const char *string);
void PUTNL(void); void PUTNL(void);
int PUTCHAR(int ch); int PUTCHAR(int ch);
#define dbg(format, ...) do { PRINTF(format, ##__VA_ARGS__); PUTNL(); } while (0) #define dbg(format, ...) do { \
if (VA_ARG_COUNT(__VA_ARGS__) == 0) { \
PUTS(format); \
} else { \
PRINTF(format, ##__VA_ARGS__); \
} \
PUTNL(); \
} while (0)
#else #else
#define dbg(format, ...) do {} while (0) #define dbg(format, ...) do {} while (0)

@ -226,8 +226,6 @@ void rsc_print_all_available(IniWriter *iw)
{ {
if (iw->count == 0) return; if (iw->count == 0) return;
static char buf[80];
iw_string(iw, "Resources available on this platform\r\n" iw_string(iw, "Resources available on this platform\r\n"
"------------------------------------\r\n"); "------------------------------------\r\n");
@ -258,7 +256,7 @@ void rsc_print_all_available(IniWriter *iw)
if (i%16 == 0) { if (i%16 == 0) {
// here we print the previous port // here we print the previous port
if (bitmap != 0) { if (bitmap != 0) {
iw_string(iw, str_pinmask(bitmap, buf)); iw_string(iw, str_pinmask(bitmap, iwbuffer));
bitmap = 0; bitmap = 0;
} }
@ -273,7 +271,7 @@ void rsc_print_all_available(IniWriter *iw)
} }
// the last one // the last one
if (bitmap != 0) { if (bitmap != 0) {
iw_string(iw, str_pinmask(bitmap, buf)); iw_string(iw, str_pinmask(bitmap, iwbuffer));
} }
iw_newline(iw); iw_newline(iw);
iw_newline(iw); iw_newline(iw);

@ -59,7 +59,7 @@ void settings_load(void)
} }
static uint8_t save_buffer[FLASH_SAVE_BUF_LEN]; static uint8_t *save_buffer = NULL;
static uint32_t save_addr; static uint32_t save_addr;
#if DEBUG_FLASH_WRITE #if DEBUG_FLASH_WRITE
@ -87,6 +87,12 @@ static bool savebuf_ovhandler(PayloadBuilder *pb, uint32_t more)
void settings_save(void) void settings_save(void)
{ {
HAL_StatusTypeDef hst; HAL_StatusTypeDef hst;
bool suc;
assert_param(save_buffer == NULL); // It must be NULL here - otherwise we have a leak
save_buffer = malloc_ck(FLASH_SAVE_BUF_LEN, &suc);
assert_param(suc);
PayloadBuilder pb = pb_start(save_buffer, FLASH_SAVE_BUF_LEN, savebuf_ovhandler); PayloadBuilder pb = pb_start(save_buffer, FLASH_SAVE_BUF_LEN, savebuf_ovhandler);
save_addr = SETTINGS_FLASH_ADDR; save_addr = SETTINGS_FLASH_ADDR;
@ -145,6 +151,9 @@ void settings_save(void)
assert_param(hst == HAL_OK); assert_param(hst == HAL_OK);
fls_printf("--- Flash done ---\r\n"); fls_printf("--- Flash done ---\r\n");
free(save_buffer);
save_buffer = NULL;
#if DEBUG_FLASH_WRITE #if DEBUG_FLASH_WRITE
dbg("written @ %p", (void*)SETTINGS_FLASH_ADDR); dbg("written @ %p", (void*)SETTINGS_FLASH_ADDR);
hexDump("Flash", (void*)SETTINGS_FLASH_ADDR, 64); hexDump("Flash", (void*)SETTINGS_FLASH_ADDR, 64);
@ -160,6 +169,8 @@ void settings_save(void)
*/ */
static void savebuf_flush(PayloadBuilder *pb, bool final) static void savebuf_flush(PayloadBuilder *pb, bool final)
{ {
assert_param(save_buffer != NULL);
// TODO this might be buggy, was not tested cross-boundary yet // TODO this might be buggy, was not tested cross-boundary yet
// TODO remove those printf's after verifying correctness // TODO remove those printf's after verifying correctness
@ -289,7 +300,7 @@ void settings_load_ini_begin(void)
void settings_load_ini_key(const char *restrict section, const char *restrict key, const char *restrict value) void settings_load_ini_key(const char *restrict section, const char *restrict key, const char *restrict value)
{ {
// dbg("[%s] %s = %s", section, key, value); // dbg("[%s] %s = %s", section, key, value);
static char namebuf[INI_KEY_MAX]; char namebuf[INI_KEY_MAX];
// SYSTEM and UNITS files must be separate. // SYSTEM and UNITS files must be separate.
// Init functions are run for first key in the section. // Init functions are run for first key in the section.

@ -18,9 +18,9 @@
#define TSK_STACK_MSG 220 // TF message handler task stack size (all unit commands run on this thread) #define TSK_STACK_MSG 220 // TF message handler task stack size (all unit commands run on this thread)
#define BULK_READ_BUF_LEN 256 // Buffer for TF bulk reads #define BULK_READ_BUF_LEN 256 // Buffer for TF bulk reads
#define UNIT_TMP_LEN 512 // Buffer for bulk read and various internal unit operations #define UNIT_TMP_LEN 512 // Buffer for internal unit operations
#define FLASH_SAVE_BUF_LEN 128 // Static buffer for saving to flash #define FLASH_SAVE_BUF_LEN 128 // Malloc'd buffer for saving to flash
#define MSG_QUE_SLOT_SIZE 64 // FIXME this should be possible to lower, but there's some bug with bulk transfer / INI parser #define MSG_QUE_SLOT_SIZE 64 // FIXME this should be possible to lower, but there's some bug with bulk transfer / INI parser
#define RX_QUE_CAPACITY 8 // TinyFrame rx queue size (64 bytes each) #define RX_QUE_CAPACITY 8 // TinyFrame rx queue size (64 bytes each)

@ -16,7 +16,7 @@ void hexDump(const char *restrict desc, const void *restrict addr, uint32_t len)
PRINTF ("%s:\r\n", desc); PRINTF ("%s:\r\n", desc);
if (len == 0) { if (len == 0) {
PRINTF(" ZERO LENGTH\r\n"); PUTS(" ZERO LENGTH\r\n");
return; return;
} }
@ -26,8 +26,11 @@ void hexDump(const char *restrict desc, const void *restrict addr, uint32_t len)
if ((i % 16) == 0) { if ((i % 16) == 0) {
// Just don't print ASCII for the zeroth line. // Just don't print ASCII for the zeroth line.
if (i != 0) if (i != 0) {
PRINTF (" %s\r\n", buff); PUTS(" ");
PUTS((const char *) buff);
PUTS("\r\n");
}
// Output the offset. // Output the offset.
PRINTF (" %04"PRIx32" ", i); PRINTF (" %04"PRIx32" ", i);
@ -38,7 +41,7 @@ void hexDump(const char *restrict desc, const void *restrict addr, uint32_t len)
// And store a printable ASCII character for later. // And store a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e)) if ((pc[i] < 0x20) || (pc[i] > 0x7e))
buff[i % 16] = '.'; buff[i % 16] = (uint8_t) ((pc[i] == 0xA5) ? ' ' : '.'); // special treatment for 0xA5 which is used as a filler in stacks
else else
buff[i % 16] = pc[i]; buff[i % 16] = pc[i];
buff[(i % 16) + 1] = '\0'; buff[(i % 16) + 1] = '\0';
@ -46,7 +49,7 @@ void hexDump(const char *restrict desc, const void *restrict addr, uint32_t len)
// Pad out last line if not exactly 16 characters. // Pad out last line if not exactly 16 characters.
while ((i % 16) != 0) { while ((i % 16) != 0) {
PRINTF (" "); PUTS(" ");
i++; i++;
} }

@ -2,9 +2,10 @@
// Created by MightyPork on 2017/12/01. // Created by MightyPork on 2017/12/01.
// //
#include <framework/system_settings.h>
#include "platform.h" #include "platform.h"
#include "framework/system_settings.h"
#include "ini_writer.h" #include "ini_writer.h"
#include "malloc_safe.h"
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)>(b)?(b):(a)) #define MIN(a,b) ((a)>(b)?(b):(a))
@ -16,9 +17,27 @@
//#define IWBUFFER_LEN 128 // moved to plat_compat.h //#define IWBUFFER_LEN 128 // moved to plat_compat.h
// sprintf from varargs, allocating buffer on stack. Uses 'format' argument char *iwbuffer = NULL;
/** Allocate the helper buffer */
void iw_begin(void)
{
assert_param(iwbuffer == NULL);
bool suc = true;
iwbuffer = malloc_ck(IWBUFFER_LEN, &suc);
assert_param(suc);
}
/** Release the helper buffer */
void iw_end(void)
{
assert_param(iwbuffer != NULL);
free(iwbuffer);
iwbuffer = NULL;
}
#define IW_VPRINTF() do { \ #define IW_VPRINTF() do { \
char iwbuffer[IWBUFFER_LEN]; \ assert_param(iwbuffer != NULL); \
va_list args; \ va_list args; \
va_start(args, format); \ va_start(args, format); \
uint32_t len = (int)fixup_vsnprintf(&iwbuffer[0], IWBUFFER_LEN, format, args); \ uint32_t len = (int)fixup_vsnprintf(&iwbuffer[0], IWBUFFER_LEN, format, args); \
@ -95,7 +114,9 @@ void iw_entry(IniWriter *iw, const char *key, const char *format, ...)
uint32_t iw_measure_total(void (*handler)(IniWriter *)) uint32_t iw_measure_total(void (*handler)(IniWriter *))
{ {
IniWriter iw = iw_init(NULL, 0xFFFFFFFF, 1); IniWriter iw = iw_init(NULL, 0xFFFFFFFF, 1);
iw_begin();
handler(&iw); handler(&iw);
iw_end();
return 0xFFFFFFFF - iw.skip; return 0xFFFFFFFF - iw.skip;
} }

@ -13,6 +13,21 @@ typedef struct iniwriter_ {
uint32_t count; uint32_t count;
} IniWriter; } IniWriter;
/**
* IniWriter helper buffer, available within a IW-scope only.
*
* This buffer is used internally by printf-like iw functions.
* It can be used to prepare buffer for iw_buff or iw_string,
* but must not be used for %s substitutions in iw_* functions.
*/
extern char *iwbuffer;
/** Allocate the helper buffer */
void iw_begin(void);
/** Release the helper buffer */
void iw_end(void);
/** /**
* Initialize a IniWriter struct (macro) * Initialize a IniWriter struct (macro)
* *

@ -67,6 +67,9 @@ extern "C" {
#define __at(_addr) __attribute__ ((at(_addr))) #define __at(_addr) __attribute__ ((at(_addr)))
#define VA_ARG_COUNT(...) INTERNAL_GET_ARG_COUNT_PRIVATE(0, ## __VA_ARGS__, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define INTERNAL_GET_ARG_COUNT_PRIVATE(_0, _1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, _16_, _17_, _18_, _19_, _20_, _21_, _22_, _23_, _24_, _25_, _26_, _27_, _28_, _29_, _30_, _31_, _32_, _33_, _34_, _35_, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, count, ...) count
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -5,6 +5,7 @@
#include "task_msg.h" #include "task_msg.h"
#include "platform.h" #include "platform.h"
#include "stacksmon.h" #include "stacksmon.h"
#include "hexdump.h"
#if USE_STACK_MONITOR #if USE_STACK_MONITOR

@ -32,7 +32,9 @@ static uint32_t read_iw_sector(uint32_t sector_offset, uint8_t *data, uint32_t n
const uint32_t avail = num_sectors*VFS_SECTOR_SIZE; const uint32_t avail = num_sectors*VFS_SECTOR_SIZE;
const uint32_t skip = sector_offset*VFS_SECTOR_SIZE; const uint32_t skip = sector_offset*VFS_SECTOR_SIZE;
IniWriter iw = iw_init((char *)data, skip, avail); IniWriter iw = iw_init((char *)data, skip, avail);
iw_begin();
handler(&iw); handler(&iw);
iw_end();
return avail - iw.count; return avail - iw.count;
} }

Loading…
Cancel
Save