Add possiblilty for segments to dynamically allocate memory

This commit is contained in:
cschwinne 2019-12-31 11:11:05 +01:00
parent 2ef46195d3
commit 51fb981d24
3 changed files with 41 additions and 6 deletions

View File

@ -44,10 +44,17 @@
#define WLED_FPS 42
#define FRAMETIME (1000/WLED_FPS)
/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
#define MAX_NUM_SEGMENTS 10
/* How much data bytes all segments combined may allocate */
#ifdef ESP8266
#define MAX_SEGMENT_DATA 2048
#else
#define MAX_SEGMENT_DATA 8192
#endif
#define NUM_COLORS 3 /* number of colors per segment */
#define SEGMENT _segments[_segment_index]
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
@ -221,13 +228,35 @@ class WS2812FX {
} segment;
// segment runtime parameters
typedef struct Segment_runtime { // 16 bytes
typedef struct Segment_runtime { // 28 bytes
unsigned long next_time;
uint32_t step;
uint32_t call;
uint16_t aux0;
uint16_t aux1;
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;};
byte* data = nullptr;
bool allocateData(uint16_t len){
if (data && _dataLen == len) return true; //already allocated
deallocateData();
if (WS2812FX::_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory
data = new (std::nothrow) byte[len];
if (!data) return false; //allocation failed
WS2812FX::_usedSegmentData += len;
_dataLen = len;
memset(data, 0, len);
return true;
}
void deallocateData(){
if (data) {
delete[] data;
}
data = nullptr;
WS2812FX::_usedSegmentData -= _dataLen;
_dataLen = 0;
}
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; deallocateData();}
private:
uint16_t _dataLen = 0;
} segment_runtime;
WS2812FX() {
@ -518,6 +547,7 @@ class WS2812FX {
uint16_t _length, _lengthRaw, _usableCount;
uint16_t _rand16seed;
uint8_t _brightness;
static uint16_t _usedSegmentData;
void handle_palette(void);
void fill(uint32_t);
@ -564,7 +594,8 @@ class WS2812FX {
// start, stop, speed, intensity, palette, mode, options, 3 unused bytes (group, spacing, opacity), color[]
{ 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
};
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
friend class Segment_runtime;
};

View File

@ -473,7 +473,7 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) {
void WS2812FX::resetSegments() {
memset(_segments, 0, sizeof(_segments));
memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
//memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
_segment_index = 0;
_segments[0].mode = DEFAULT_MODE;
_segments[0].colors[0] = DEFAULT_COLOR;
@ -484,7 +484,9 @@ void WS2812FX::resetSegments() {
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
{
_segments[i].colors[0] = color_wheel(i*51);
_segment_runtimes[i].reset();
}
_segment_runtimes[0].reset();
}
void WS2812FX::setIndividual(uint16_t i, uint32_t col)
@ -862,3 +864,5 @@ uint32_t WS2812FX::gamma32(uint32_t color)
b = gammaT[b];
return ((w << 24) | (r << 16) | (g << 8) | (b));
}
uint16_t WS2812FX::_usedSegmentData = 0;

View File

@ -98,7 +98,7 @@
//version code in format yymmddb (b = daily build)
#define VERSION 1912291
#define VERSION 1912311
char versionString[] = "0.9.0-b2";