Оперативка
- Войдите на сайт для отправки комментариев
Ср, 27/02/2019 - 08:49
Собственно вопрос по "практической" опасной близости кучи к стеку, где критическая граница? Понятно, что компилятор будет предупреждать заранее, ещё за долго об этой опасности. Может кто сталкивался на практике с глюками по теме?
Скетч использует 16776 байт (54%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 1541 байт (75%) динамической памяти, оставляя 507 байт для локальных переменных. Максимум: 2048 байт. Недостаточно памяти, программа может работать нестабильно.
Граница в сферическом скетче?
vlad072, вам что поговорить не о чем?
Да, вопрос задал сумбурно.. Правильней так: от чего в AVR в основном зависит размер стека, и в каких пределах он обычно разрастается на практике?
Понятно, что компилятор будет предупреждать заранее, ещё за долго об этой опасности.
И не подумает. Вот даже в мыслях у него не будет.
Да, вопрос задал сумбурно.. Правильней так: от чего в AVR в основном зависит размер стека, и в каких пределах он обычно разрастается на практике?
Он не "разрастается". Он занимает ровно столько места, сколько требуют ваши временные и локальные переменные.
И еще отвечу не на ваш вопрос - однако по делу :)
Вот у вас кода всего 16К - а оперативки занято уже 1500 байт - и ЭТО НЕНОРМАЛЬНО. Ищите, куда вы дели такую прорву RAM.
Не обижайтесь, но скорее всего - вы банально не умеете писать эффективный код и не владеете приемами экономии памяти. Для кода, занимающего 16к во флеше - в среде Ардуино средний расход RAM обычно не превышает 300-500 байт
ну так ты не берешь в ращёт, наерна, такие прожорливые биб-ки, как SD, OLED и т.д. мало ли что память жрать умеет как не в себя...
ну так ты не берешь в ращёт, наерна, такие прожорливые биб-ки, как SD, OLED и т.д. мало ли что память жрать умеет как не в себя...
беру. Использование библиотеки ОЛЕД с буфером в 1К - это тоже признак неумения экономить память :)
Не обижайтесь, но скорее всего - вы банально не умеете писать эффективный код и не владеете приемами экономии памяти. Для кода, занимающего 16к во флеше - в среде Ардуино средний расход RAM обычно не превышает 300-500 байт
и как после этого дальше жить )))
Для кода, занимающего 16к во флеше - в среде Ардуино средний расход RAM обычно не превышает 300-500 байт
Много строковых переменных для работы с модемом и iot. Из библиотек использую только SoftwareSerial и 1wire.
так хотелось бы узнать, что больше всего использует стек? Переменные функций в нём размещаются? И главный вопрос, стоит ли вообще париться при 25% свободной оперативки или это излишняя осторожность компилятора?
и как после этого дальше жить )))
Конструктив так и прёт, трололо
так хотелось бы узнать, что больше всего использует стек? Переменные функций в нём размещаются? И главный вопрос, стоит ли вообще париться при 25% свободной оперативки или это излишняя осторожность компилятора?
Да, кто ж Вас знает, что там за скетч у Вас и что (а, главное, как) он использует?
Ну, попробуйте запустить с постоянным мониторингом памяти, увидите как оно меняется в процессе работы.
Вот в этой теме показано как следить за памятью в процессе выполнения программы.
Много строковых переменных для работы с модемом и iot.
ну вот именно это я и предполагал - не умеете работать с памятью. Строки во флеш класть не пробовали?
Повторяю, вы не о том думаете. Судя по многим признакам. память у вас кончилась потому. что код кривой. Так что правильный вопрос от вас должен звучать так: "Как мне уменьшить расход памяти в программе?" - а не "Где граница стека?" - на этот вопрос точно вам никто не ответит.
у стека нет границы, у него есть только верхушка. А она постоянна плавает.
у стека нет границы, у него есть только верхушка. А она постоянна плавает.
а 0x0000 ? надеюсь здесь он тоже вниз растёт?
Строки во флеш класть не пробовали?
Может я чего то не понимаю, но во флеш мы можем положить максимум константы, а мне не хватает памяти под переменные.
#include <SoftwareSerial.h> #include <OneWire.h> #include <CyberLib.h> #include "consts.h" #include "classes.h" SoftwareSerial gsm(SIM800RX_PIN, SIM800TX_PIN); OneWire ds(ONEWIRE_PIN); Input lock(LOCK_PIN), door(DOOR_PIN), hood(HOOD_PIN), fuelpump(FUELPUMP_PIN); Output siren(SIREN_PIN), flash(FLASH_PIN), dvr(DVR_PIN), led(LED_PIN); InOut ign(IGN_SUPPLY_PIN, IGN_PIN), starter(STARTER_SUPPLY_PIN, STARTER_PIN); char at[ 128 ] = ""; uint32_t tpingresp = 0; uint32_t t30sec = 0; uint32_t t1min = 0; uint32_t t3hour = 0; byte celstate = 0; // initial=0, dialing=1, oncall=2, voice ready=4; int stoptimer = 0; int stoptemp = 0; bool armed = false; volatile byte alarm = 0; bool warmup = false; int temp[4] = {-127, -127, -127, -127}; void dbg(const char* par, const char* val = NULL) { Serial.print("["); Serial.print(millis()); Serial.print("]"); Serial.print(par); if ( val != NULL ) Serial.print("="), Serial.print(val); Serial.println(); } int getanalog(byte pin) { uint16_t _lvl[5]; for (byte i = 0; i < 5; i++) _lvl[i] = analogRead(pin); return find_similar(_lvl, 5, 3); } float vbatt() { int _lvl = getanalog(BATT_PIN); return(_lvl/65.0); } float ibatt() { int _lvl = getanalog(CURRENT_PIN); return (_lvl - 640) / 20.46; } bool neutral() { return(getanalog(NEUTRAL_PIN) < 130); // ~591 for INTERNAL } bool engrun() { return( fuelpump.active() || (vbatt() > 13.8) ); } bool drive() { return( engrun() && !neutral() ); } void arming(bool arm) { if ( arm ) attachInterrupt(0, shock2, FALLING), attachInterrupt(1, shock1, FALLING); else detachInterrupt(0), detachInterrupt(1); armed = arm; } void shock1() { alarm |= 1; } void shock2() { alarm |= 0x82; } void starting() { if ( engrun() || !neutral() ) return; dbg("starting!"); gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) pubf("info/stoptimer", stoptimer, 0), pubf("info/stoptemp", stoptemp, 0), gsm.write(0x1A); uint32_t _tinit = 0; float _vrel = 0; detachInterrupt(0); detachInterrupt(1); ign.set(true); delay(200); if ( starter.active() ) goto _err; // mosfet breakdown if ( !fuelpump.active() ) goto _err; delay(3000); // fuelpump fault? _vrel = vbatt() - 2; _tinit = millis(); if ( !starter.set(true) ) goto _err; delay(500); // starter fault? while ( ((millis() - _tinit) < 3000) && (vbatt() < _vrel) ); // spinup engine - max 3sec if ( starter.set(false) ) goto _ok; _err: ign.set(false); _ok: if (armed) attachInterrupt(0, shock2, FALLING), attachInterrupt(1, shock1, FALLING); ign.change(); delay(3000); warmup = !warmup && engrun(); } void modemreset () { dbg("reset modem..."); gsm.println("AT+CFUN=1,1"); if ( gsm.find("OK") ) delay(3500), gsm.println("AT+BTPOWER=1"); tpingresp = millis(); } bool atfind(const char* str) { return strstr(at, str) != NULL; } void play(const char* track) { celstate &= ~bit(2); gsm.print("AT+CREC=4,\"C:\\User\\"), gsm.print(track), gsm.println(".amr\",0,90"); } void pub (const char* topic, const char* msg, bool retn = false) { gsm.write(0x30 | (byte)retn); gsm.write((2+strlen(topic) + strlen(msg))); gsm.write((byte)0x00), gsm.write(strlen(topic)), gsm.write(topic); gsm.write(msg); } void pubf (const char* topic, float val, int x) { char _st[8]; dtostrf(val, 0, x, _st); pub(topic, _st); } void sub (const char* topic) { gsm.write(0x82); gsm.write(strlen(topic) + 5); gsm.write((byte)0x00); gsm.write(0x01) ; gsm.write((byte)0x00); gsm.write(strlen(topic)); gsm.write(topic); gsm.write((byte)0x00); } void brokercon () { dbg("broker connect..."); gsm.println("AT+CIPSEND"); if ( !gsm.find(">") ) return; gsm.write(0x10); gsm.write(4 + 2+strlen(proto) + 2+strlen(cid) + 2+strlen(willt) + 2+strlen(willm) + 2+strlen(user) + 2+strlen(pass)); gsm.write((byte)0x00); gsm.write(strlen(proto)); gsm.write(proto); gsm.write(0x03); // proto, ver gsm.write(0xE6); gsm.write((byte)0x00); gsm.write(0x3C); // flags, ka timout | E/C -retain/not gsm.write((byte)0x00); gsm.write(strlen(cid)); gsm.write(cid); gsm.write((byte)0x00); gsm.write(strlen(willt)); gsm.write(willt); gsm.write((byte)0x00); gsm.write(strlen(willm)); gsm.write(willm); gsm.write((byte)0x00); gsm.write(strlen(user)); gsm.write(user); gsm.write((byte)0x00); gsm.write(strlen(pass)); gsm.write(pass); pub("info/online", "1", true); sub("cmd/#"); gsm.write(0x1A); } void ping() { gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) gsm.write(0xC0), gsm.write(byte(0x00)), gsm.write(0x1A); } void sendbalance(const char* msg) { if ( msg == NULL ) return; char _bal[10] = ""; byte _end = 67; for ( byte i = 35; i < _end; i += 4 ) if ( msg[i] == 'D' ) strcat(_bal, "-"); else if ( msg[i] == 'E' ) strcat(_bal, "."), _end = i + 9; else strncat(_bal, msg+i, 1); strcat(_bal, "\0"); gsm.println("AT+CIPSEND"); if ( gsm.find('>') ) pub("info/balance", _bal, true), gsm.write(0x1A); //dbg(_bal); } void sendloc(const char* loc) { char* _epos = strchr(loc, ',') + 1; char* _npos = strchr(_epos, ',') + 1; byte _elen = _npos - _epos - 1; byte _nlen = strchr(_npos, ',') - _npos; // char _link[64] = "https://www.google.com/maps/place/"; char _link[24]; strncat(_link, _npos, _nlen); strcat(_link, ","); strncat(_link, _epos, _elen); strcat(_link, "\0"); //gsm.println("AT+CIPSEND"); if ( gsm.find('>') ) pub("info/location", _link), gsm.write(0x1A); dbg(_link); } void ipdhandling(const byte* frame, byte len = 1 ) { //++++++++++++++ PROCESSING DATA FROM BROKER ++++++++++++++++++ // for (int i = 0; i < (byte)frame[1]+2; i++) Serial.write(frame[i]); // dbg("pack len", itoa(_len)); tpingresp = millis(); if ( frame == NULL ) return; for ( byte _idx = 0; _idx < len; ) { if ( (frame[_idx] == 0xD0) && (frame[_idx+1] == 0x00) ) { // pingresp d0 00 dbg("ping responce!"); _idx += 2; } else if ( (frame[_idx] == 0x20) && (frame[_idx+1] == 0x02) ) { // connak 20 02 00 00 if ( frame[_idx+3] == 0x00 ) led.act(1000), dbg("conn accepted"); else { dbg("conn refused"); gsm.println("AT+CIPSHUT"); return; } _idx += 4; } else if ( (frame[_idx] & ~0x01) == 0x30 ) { // pub recv !!sometime 31 10 00 0c char* _tfirst = (char*)(frame + _idx + 8); byte _tlen = frame[_idx+3] - 4; char* _pfirst = (char*)(frame + _idx + frame[_idx+3] + 4) ; byte _plen = frame[_idx+1] - frame[_idx+3] - 2; char _topic[_tlen+1]; strncpy(_topic, _tfirst, _tlen); _topic[_tlen] = '\0'; char _payl [_plen+1]; strncpy(_payl, _pfirst, _plen); _payl[_plen] = '\0'; _idx += frame[_idx+1] + 2; dbg(_topic, _payl); if ( strstr(_topic, "stoptimer") != NULL ) { stoptimer = atoi(_payl); } else if ( strstr(_topic, "stoptemp") != NULL ) { stoptemp = atoi(_payl); } else if ( strstr(_topic, "start") != NULL ) { if ( atoi(_payl) == 1 ) starting(); else ign.set(false); gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) pub("info/warmup", warmup ? "1" : "0"), gsm.write(0x1A); } else if ( strstr(_topic, "armed") != NULL ) { armed = true; } else if ( strstr(_topic, "update") != NULL ) { if ( atoi(_payl) == 2 ) gsm.println("AT+CIPGSMLOC=1,1"); else if ( atoi(_payl) == 1 ) gsm.println("AT+CUSD=1,\"*105#\""); else gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) { pubf("info/engtemp", temp[0], 0); pubf("info/outtemp", temp[1], 0); pubf("info/vehtemp", temp[2], 0); pubf("info/vbatt", vbatt(), 2); pubf("info/ibatt", ibatt(), 2); pubf("info/stoptemp", stoptemp, 0); pubf("info/stoptimer", stoptimer, 0); pub ("info/ign", ign.active() ? "1" : "0"); pub ("info/eng", engrun() ? "1" : "0"); pub ("info/warmup", warmup ? "1" : "0"); pub ("info/doorop", door.active() ? "1" : "0"); pub ("info/hoodop", hood.active() ? "1" : "0"); pub ("info/armed", armed ? "1" : "0"); gsm.write(0x1A); if ( gsm.find("SEND OK") ) gsm.println("AT+CSQ"); } } else if ( strstr(_topic, "horn") != NULL ) { siren.act(2000); flash.act(3000); } } else break; //unexpected header } // cycle } // ipd func void athandling() { //++++++++++++++++++ AT HANDLING ++++++++++++++++++++ byte _atlen = 0; while ( gsm.available() ) { if ( (_atlen + 1) < sizeof(at) ) at[_atlen++] = gsm.read(); else gsm.read(); delay(1); } at[_atlen] = '\0'; for (int i = 0; i < _atlen; i++) Serial.write(at[i]); if ( atfind("SMS Ready") ) gsm.println("AT+CIPHEAD=1;+CIPSHUT"); if ( atfind("SHUT OK") ) gsm.print("AT+CIPSTART=TCP,"), gsm.println(broker); if ( atfind("CONNECT OK") ) brokercon(); if ( atfind("DEACT") || atfind("CLOSED") || atfind("CONNECT FAIL") ) dbg("conn fail!"), gsm.println("AT+CIPSHUT"); if ( atfind("ERROR") ) dbg("ERR_STR", at)/*/, modemreset()*/; if ( atfind("+CLIP:") ) if ( atfind("\"admin") ) { // cellular bits: siren.set(false); flash.set(false); // 0( 1 ) = dialing gsm.println("ATA"); celstate = 6; delay(500); play("hello"); // 1( 2 ) = on call } else gsm.println("ATH0"); // 2( 4 ) = voice ready if ( atfind("+COLP:") ) { siren.set(false); flash.set(false); celstate = 6; delay(500); play("hello"); } if ( atfind("+CREC: 0") ) celstate |= bit(2); if ( atfind("NO CARRIER") || atfind("BUSY") || atfind("NO ANSWER") ) tpingresp = millis(), celstate = 0; if ( atfind("+DTMF: #") ) { alarm = 0; if (celstate == 6) play("alarmres"); } if ( atfind("+BT") && atfind(btkey) ) if ( !drive() ) arming( atfind("DISCONN") ); if ( atfind("+CUSD:") ) sendbalance(strstr(at, "+CUSD:") + 11); if ( atfind("+CSQ:") ) { gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) pubf("info/sq", atoi(strstr(at, "+CSQ:")+6), 0), gsm.write(0x1A); } if ( atfind("+IPD") ) ipdhandling( strchr(strstr(at, "+IPD"), ':') + 1, atoi(strchr(strstr(at, "+IPD"), ',') + 1) ); if ( atfind("+CIPGSMLOC:") ) sendloc(strstr(at, "+CIPGSMLOC:") + 12); } void dsinit() { for( byte _i = 0; _i < sizeof(temp)/sizeof(int); _i++ ) { ds.reset(); ds.select(sid[_i]); ds.write(0x4E); ds.write(0x7F), ds.write(0xFF); ds.write(0x1F); // ds.reset(); ds.select(sid[_i]); ds.write(0x48); // to rom } } void updtemps() { for( byte _i = 0; _i < sizeof(temp)/sizeof(int); _i++ ) { ds.reset(); ds.select(sid[_i]); ds.write(0x44); delay(100); ds.reset(); ds.select(sid[_i]); ds.write(0xBE); int16_t _raw = ds.read(); _raw |= ds.read() << 8; _raw >>= 4; ds.read(); ds.read(); // th/tl temp[_i] = (ds.read() == 0x1F) ? (int)_raw : -127; // conf? } ds.reset(); } void setup() { pinMode(SHOCK1_PIN, INPUT_PULLUP); pinMode(SHOCK2_PIN, INPUT_PULLUP); Serial.begin(9600); delay(200); gsm.begin(9600); delay(200); dsinit(); updtemps(); modemreset(); } void loop() { if ( gsm.available() ) athandling(); led.set( armed && ((millis() & 0x3ff) > 0x370) ); if ( drive() ) dvr.act(60000); if ( ((millis() - tpingresp) > 70000) && (celstate == 0) ) dbg("broker isn't responding!"), modemreset(); if ( (millis() - t30sec) > 30000 ) t30sec = millis(), updtemps(), ping(); if ( warmup ) if ( (millis() - t1min) > 60000 ) { t1min = millis(); if ( stoptimer > 1 ) stoptimer--; gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) { pubf("info/stoptimer", stoptimer, 0); pubf("info/stoptemp", stoptemp, 0); pubf("info/engtemp", temp[0], 0); pubf("info/ibatt", ibatt(), 2); gsm.write(0x1A); } } if ( (millis() - t3hour) > 10800000 ) t3hour = millis(), gsm.println("AT+CUSD=1,\"*105#\""); if ( warmup ) if ( (temp[0] > stoptemp) || (stoptimer < 1) || (ibatt() > 15.0) || !neutral() ) { ign.set(false); warmup = false; gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) { pub ("info/warmup", "0"); pubf("info/ibatt", ibatt(), 2); gsm.write(0x1A); } } switch( lock.change() ) { //csan locking case 0: arming(false); break; case 1: //if ( drive() ) break; if ( door.active() || hood.active() ) siren.act(200); arming(true); } if ( armed ) { if ( hood.change() == 1 ) alarm |= 0x84; if ( door.change() == 1 ) alarm |= 0x88; if ( ign.change() == 1 ) alarm |= 0x90; } if ( (temp[1] > 50) || (temp[2] > 50) || (temp[3] > 50) ) alarm |= 0xA0; //dbg("alarm", alarm); if ( alarm == 1 ) { static bool _even = false; siren.act(500); flash.act(2000); dvr.act(30000); gsm.println("AT+CIPSEND"); if ( gsm.find(">") ) pub("notify", _even ? "kick!" : "kick! "), gsm.write(0x1A); alarm &= ~1; _even = !_even; } else if ( alarm > 0x81 ) { siren.act(20000); flash.act(20000); dvr.act(60000); alarm &= ~bit(7); if ( celstate == 0 ) gsm.println("ATD>\"admin\";"), celstate = 1; } if ( (alarm > 1) && (celstate == 6) ) for ( byte _i = 5; _i > 0; _i-- ) { // alarm bits: if ( (alarm & bit(_i)) == 0 ) continue; // 0( h01 ) = shock1 alarm &= ~bit(_i); // 1( h02 ) = shock2 if ( _i == 5 ) { play("fire"); break; } // 2( h04 ) = hood open if ( _i == 4 ) { play("ignon"); break; } // 3( h08 ) = door open if ( _i == 3 ) { play("dooropen"); break; } // 4( h10 ) = ignition on if ( _i == 2 ) { play("hoodopen"); break; } // 5( h20 ) = fire if ( _i == 1 ) { play("shock"); break; } // 7( h80 ) = NEW IMPORTANT ALARM } dvr.processing(); siren.processing(); flash.processing(); led.processing(); } // ************* LOOP +++++++++++++++++++++++.//++++++++++ classes.h+++++++++++++++++ class Input { public: Input(byte pin) { _pin = pin; pinMode(_pin, INPUT_PULLUP); _old = active(); } bool active(void) { byte _cntr; do { _cntr = 0; for ( byte _i = 0; _i < 10; _i++ ) _cntr += (byte)digitalRead(_pin); } while ( (_cntr > 0) && (_cntr < 10) ); return _cntr == 0; } int change() { bool _state = active(); if (_state == _old) return -1; _old = _state; return (int)_state; } private: byte _pin; bool _old; }; // Input class Output { public: Output(byte pin) { _pin = pin; pinMode(_pin, OUTPUT); digitalWrite(_pin, LOW); } void set(bool val) { digitalWrite(_pin, val ? HIGH:LOW); _state = val; _actual = false; } void act(uint32_t timeout) { _begin = millis(); _timeout = timeout; _actual = true; } void processing() { if (_actual) { bool _timely = (millis() - _begin) < _timeout; if (_timely && !_state) { digitalWrite(_pin, HIGH); _state = true;} if (!_timely && _state) { digitalWrite(_pin, LOW); _state = false; _actual = false; } } } private: byte _pin; uint32_t _begin = 0; uint32_t _timeout = 0; bool _actual = false; bool _state = false; }; // Output class InOut : public Input, Output { public: InOut(byte inpin, byte outpin) : Input(inpin), Output(outpin) { } bool set(bool val) { Output::set(val); return (active() == val); } }; // InOut//++++++++++++++ consts.h +++++++++++++++++ //============ pins ============== #define IGN_PIN 4 // включение зажигания - транспондер через оптрон (2) #define STARTER_PIN 5 // включение стартера (3) #define SIREN_PIN 6 // сирена (4)mqtt #define DVR_PIN 7 // видеоргистратор (5) #define IGN_SUPPLY_PIN A5 // контроль зажигания (6) #define FLASH_PIN 8 // аварийка (7) #define SIM800RX_PIN 9 // RX Arduino (TX sim800L) (8) #define SIM800TX_PIN 10 // TX Arduino (RX sim800L) (9) #define FUELPUMP_PIN 11 // контроль работы бензонасоса ! (оптрон) 10 #define STARTER_SUPPLY_PIN A4 // контроль питания стартера ! (оптрон) (11) #define ONEWIRE_PIN 12 // датчики температуры #define LED_PIN 13 // светодиод #define HOOD_PIN A0 // концевик дверей (через диод) PULLUP #define DOOR_PIN A1 // концевик капота (через диод) PULLUP #define NEUTRAL_PIN A2 // контроль нейтрали ! (через диод) PULLUP #define LOCK_PIN A3 // центральный замок (через диод) PULLUP #define SHOCK1_PIN 3 // датчик удара1 (через диод) PULLUP (A4) #define SHOCK2_PIN 2 // датчик удара2 (через диод) PULLUP (A5) #define BATT_PIN A7 // напряжение аккума (делитель) #define CURRENT_PIN A6 // ток в цепи +12В const char* broker = "m23.cloudmqtt.com,17510"; // addr,port const char* proto = "MQIsdp"; const char* cid = "BlackBox"; const char* willt = "info/online"; const char* willm = "0"; const char* user = "sdfwevebd"; const char* pass = "4t5g4tgefg3rgrg"; const char* btkey = "CONN: \"Redmi\",20:ca:2e:ff:55:4a"; const byte sid[4][8] = { {0x28, 0x7B, 0x45, 0x46, 0x92, 0x01, 0x02, 0xB3}, // engine {0x28, 0xEB, 0xB0, 0x77, 0x91, 0x0D, 0x02, 0x18}, // outdoor {0x28, 0x7E, 0x60, 0x46, 0x92, 0x02, 0x02, 0x27}, // vehacle {0x28, 0xE6, 0xBD, 0x3B, 0x05, 0x00, 0x00, 0xCF} }; // selfhttp://microsin.net/programming/avr/avrstudio-gcc-progmem.html
Понятно, что компилятор будет предупреждать заранее, ещё за долго об этой опасности.
И не подумает. Вот даже в мыслях у него не будет.
Если бы ни разу не приходилось менеджер памяти допиливать, то можно бы уточнить откуда такие сведения о компиляторе, а так просто поржать.
Строки во флеш класть не пробовали?
Может я чего то не понимаю, но во флеш мы можем положить максимум константы, а мне не хватает памяти под переменные.
может я тоже не понял гениального замысла кода - но в первом отрывке все дикое количество строк - это именно константы. а не переменные. Во втором коде строк, вроде нет - а в третьем строки даже описаны как const
Код весьма кудряво написан. Сами с нуля писали или правите то, что нашли в инете?
свой код и прямо таки с паролями выложили )))
vlad072 , примеров и добрых советов вы как я понял слушать не желаете как я понял,
было же вам уже с progmem пример - чем не нравится то?
http://arduino.ru/forum/programmirovanie/snova-mqtt-1?page=1#comment-428950
sadman41 Спасибо, теперь многое становится понятно.
"Несмотря на указание const при декларации констант, компилятор все равно для их хранения использует ОЗУ (при старте программы они просто копируются из flash в RAM). "
примеров и добрых советов вы как я понял слушать не желаете
"Нет ничего более раздражающего, чем хороший пример" (Марк Твен).
а 0x0000 ? надеюсь здесь он тоже вниз растёт?
Вниз по кругу.)