Помогите найти утечку памяти
- Войдите на сайт для отправки комментариев
Пнд, 24/07/2017 - 21:03
Добрый день, форумчане!
Процедура занимается генерацией смс-сообщения с последующей передачей его другой функции.
void timerInterupt() {
{
char smsbuf [150];
smsbuf[0] = '\0';
char *psmsbuf = &smsbuf[0];
{
char *str = "System powered\r";
while (*str)
{
*psmsbuf++ = *str++;
}
}
if (gerconflag == false) {
*psmsbuf = &smsbuf[15];
{
char *str = "Door closed\r";
while (*str)
{
*psmsbuf++ = *str++;
}
}
}
else
{
*psmsbuf = &smsbuf[15];
{
char *str = "Door openered\r";
while (*str)
{
(*psmsbuf++ = *str++);
}
}
}
// Serial.print("2sms ="); for (byte j = 0; j < 30; j++) {
// Serial.print(smsbuf[j]);
// } Serial.println("!");
*psmsbuf = &smsbuf[27];
{
char *str = "Current t.= ";
while (*str)
{
(*psmsbuf++ = *str++);
}
}
// Serial.print("3sms ="); for (byte j = 0; j < 40; j++) {
// Serial.print(smsbuf[j]);
// } Serial.println("!");
*psmsbuf = &smsbuf[39];
{
char t[4];
dtostrf(Temperature(Pintemp), 2, 2, t);
char *str = t;
while (*str)
{
(*psmsbuf++ = *str++);
}
}
*psmsbuf = &smsbuf[43];
{
char *str = "C\rTemp.history:\r";
while (*str)
{
(*psmsbuf++ = *str++);
}
}
// Serial.print("4sms ="); for (byte j = 0; j < 60; j++) {
// Serial.print(smsbuf[j]);
// } Serial.println("!");
*psmsbuf = &smsbuf[59];
for (byte j = 0; j <= 11; j++)
{
{
char t[4];
dtostrf(Temp[j], 2, 2, t);
char *str = t;
while (*str)
{
(*psmsbuf++ = *str++);
}
*psmsbuf++ = '\r';
}
}
// Serial.print("5sms ="); for (byte j = 0; j < 120; j++) {
// Serial.print(smsbuf[j]);
// } Serial.println("!");
*psmsbuf = &smsbuf[119];
{
char *str = "Sys.time:\r";
while (*str)
{
(*psmsbuf++ = *str++);
}
}
// Serial.print("6sms ="); for (byte j = 0; j < 140; j++) {
// Serial.print(smsbuf[j]);
// } Serial.println("!");
// for (byte j = 0; j < 140; j++) {
// if (smsbuf[j] == '\r') Serial.println(j);
// }
*psmsbuf = &smsbuf[128];
{
{
char t[1];
itoa (GetTime('H'), t, 10);
char *str = t;
while (*str)
{
(*psmsbuf++ = *str++);
}
}
*psmsbuf++ = ':';
{
char t[1];
itoa (GetTime('M'), t, 10);
char *str = t;
while (*str)
{
(*psmsbuf++ = *str++);
}
}
*psmsbuf++ = ':';
{
char t[1];
itoa (GetTime('S'), t, 10);
char *str = t;
while (*str)
{
(*psmsbuf++ = *str++);
}
}
*psmsbuf++ = '\0';
}
// Serial.print("7sms ="); for (byte j = 0; j < 150; j++) {
// Serial.print(smsbuf[j]);
// } Serial.println("!");
// for (byte j = 0; j < 150; j++) {
// if (smsbuf[j] == '\r') Serial.println(j);
// }
Serial.print("sms ="); Serial.println(smsbuf);
sendsms(smsbuf);
}
Serial.println("continue temp check");
}
void sendsms(char *currsms) //процедура отправки СМС
volatile int GetTime (char ini) ///GetTime
float Temperature(int Pintemp) //значение температуры
Плата зависает на пробегании предпоследней строчки: {
begin interupt
smsbuf=7sms =System powered
Door closed
Current t.= 0.00C
Temp.history:
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
Sys.time:
8194:8194:8194
conti⸮
}
Иногда при повторном вызове функции, хотя переменные инициализируются снова, а может и не зависнуть.
Загрузка:{
Скетч использует 18176 байт (56%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 1254 байт (61%) динамической памяти, оставляя 794 байт для локальных переменных. Максимум: 2048 байт.
}
но будет больше, поэтому раскидывться нельзя. Подскажите, пожалуйста, что не так, а то за неделю все мозги сломал((
Выложите скетч как положено, чтобы можно было обсуждать. В шапке вверху есть специальная тема с обьяснением, как правильно выкладывать код.
Спасибо. Интересующая процедура как раз начинается со строчки 100.
/* */ //#include <MemoryExplorer.h> #include <MsTimer2.h> #include <SoftwareSerial.h> #include <OneWire.h> #include <stdio.h> //работа со строчками #include <Wire.h> // Подключаем библиотеку Wire #include <TimeLib.h> // Подключаем библиотеку TimeLib #include <DS1307RTC.h> // Подключаем библиотеку DS1307RTC #include <avr/wdt.h> //подключаем сторожевую собаку #include <string.h> const byte Pintemp = 2; const byte Pingercon = 3; const byte PinVib = 4; //const byte PinMov = 7; const char MasterNum[] = {"+7000000000"}; const byte PinLight = 12; const byte tempinterval = 5; //в минутах, время между сохранением температуры const byte tempalarm = 50; // град. с. при предупредждении о опышении темперутуры SoftwareSerial mySerial(10, 11); // RX, TX float Temp[11]; int tempcount; void setup() { Serial.begin(9600); pinMode(Pingercon, INPUT); pinMode(PinVib, INPUT); pinMode(PinLight, OUTPUT); pinMode(8, OUTPUT); pinMode(13, OUTPUT); mySerial.begin(9600); sim800ini(); MsTimer2::set(60000, timerInterupt); // задаем период прерывания по таймеру в мс MsTimer2::start(); // разрешаем прерывание по таймеру wdt_enable(WDTO_4S); } String currStr; //переменные для получения смс // Переменная принимает значение True, если текущая строка является сообщением boolean isStringMessage = false; int i = 0; boolean gerconflag = false; boolean vibflag = false; boolean UP = true; //выключен - false (влючен - true) после заливки прошивки boolean smsflag = true; //шлем смс, если true char ini; void loop() { // i++; //Serial.println(i); //delay (10); ////////////////// Обработка геркона /////////////////////////// if (Gercon(Pingercon) == true && gerconflag == false && UP == true) { gerconflag = true; digitalWrite(PinLight, HIGH); //здесь действие при сработке { } } ////////////////// Обработка датчика вибрации /////////////////////////// if (Vib(PinVib) == true && vibflag == false && UP == true) { vibflag = true; digitalWrite(PinLight, HIGH); //здесь действие при сработке { } } ////////////////// ОБРАБОТКА КОМАНД СМС ////////////////////// { volatile int comand = 0; comand = recivesms(); if (comand == 4) sim800ini(); //и так далее... } //////////////////// КОМАНДЫ ПО ТАЙМЕРУ/////////////////// wdt_reset(); } ///////////////////////////////////////////////FUNCTIONS//////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// ///////////// TIMER ////////// void timerInterupt() { Serial.println("begin interupt"); { char smsbuf [150]; smsbuf[0] = '\0'; Serial.print("smsbuf="); Serial.print(smsbuf); //Serial.println("!!"); char *psmsbuf = &smsbuf[0]; { char *str = "System powered\r"; while (*str) { *psmsbuf++ = *str++; } } if (gerconflag == false) { *psmsbuf = &smsbuf[15]; { char *str = "Door closed\r"; while (*str) { *psmsbuf++ = *str++; } } } else { *psmsbuf = &smsbuf[15]; { char *str = "Door openered\r"; while (*str) { (*psmsbuf++ = *str++); } } } *psmsbuf = &smsbuf[27]; { char *str = "Current t.= "; while (*str) { (*psmsbuf++ = *str++); } } *psmsbuf = &smsbuf[39]; { char t[4]; dtostrf(Temperature(Pintemp), 2, 2, t); char *str = t; while (*str) { (*psmsbuf++ = *str++); } } *psmsbuf = &smsbuf[43]; { char *str = "C\rTemp.history:\r"; while (*str) { (*psmsbuf++ = *str++); } } *psmsbuf = &smsbuf[59]; for (byte j = 0; j <= 11; j++) { { char t[4]; dtostrf(Temp[j], 2, 2, t); char *str = t; while (*str) { (*psmsbuf++ = *str++); } *psmsbuf++ = '\r'; } } *psmsbuf = &smsbuf[119]; { char *str = "Sys.time:\r"; while (*str) { (*psmsbuf++ = *str++); } } *psmsbuf = &smsbuf[128]; { { char t[1]; itoa (GetTime('H'), t, 10); char *str = t; while (*str) { (*psmsbuf++ = *str++); } } *psmsbuf++ = ':'; { char t[1]; itoa (GetTime('M'), t, 10); char *str = t; while (*str) { (*psmsbuf++ = *str++); } } *psmsbuf++ = ':'; { char t[1]; itoa (GetTime('S'), t, 10); char *str = t; while (*str) { (*psmsbuf++ = *str++); } } *psmsbuf++ = '\0'; } Serial.print("7sms ="); for (byte j = 0; j < 150; j++) { Serial.print(smsbuf[j]); } Serial.println("!"); // for (byte j = 0; j < 150; j++) { // if (smsbuf[j] == '\r') Serial.println(j); // } Serial.print("sms ="); Serial.println(smsbuf); //массив температур.. if (GetTime('M') == tempinterval) { Temp[tempcount] = Temperature(Pintemp); tempcount++; } if (smsflag == true && GetTime('H') == 10 && GetTime('M') == 10) { sendsms(smsbuf); tempcount = 0; } if (smsflag == true && GetTime('H') == 22 && GetTime('M') == 10) { sendsms(smsbuf); tempcount = 0; } if (smsflag == true && GetTime('H') == 17 && GetTime('M') == 10) { sendsms(smsbuf); tempcount = 0; } sendsms(smsbuf); } Serial.println("continue temp check"); // if (Temperature(Pintemp) > tempalarm) // { // { String currsms, chars; // currsms = "Temperature exceed detected!\r"; // chars = "t.= "; // currsms = currsms + chars; // currsms = currsms + Temperature(Pintemp); // chars = "C\rSys.time:\r"; // currsms = currsms + chars; // chars = GetTime('H'); // currsms = currsms + chars; // chars = ":"; // currsms = currsms + chars; // chars = GetTime('M'); // currsms = currsms + chars; // chars = ":"; // currsms = currsms + chars; // chars = GetTime('S'); // currsms = currsms + chars; // Serial.println(currsms); // // if (smsflag == true) sendsms(currsms); // } // // } Serial.println("continue switch"); if (digitalRead(13) == HIGH) { digitalWrite(13, LOW); } else { digitalWrite(13, HIGH); } Serial.println("end interupt"); } ///GetTime volatile int GetTime (char ini) { tmElements_t tm; if (RTC.read(tm)) { int _var = 0; switch (ini) { case 'H' : _var = tm.Hour; return (_var); case 'M' : _var = tm.Minute; return (_var); case 'S' : _var = tm.Second; return (_var); case 'D' : _var = tm.Day; return (_var); case 'm' : _var = tm.Month; return (_var); case 'Y' : _var = tm.Year; return (_var); } } } ///SIM800 Initialization void sim800ini() { mySerial.begin(9600); // Настраиваем приём сообщений с других устройств // Между командами даём время на их обработку mySerial.print("AT+CMGF=1\r"); //устанавливает текстовый режим смс-сообщения delay(500); mySerial.print("at+cscs="); mySerial.print(char(34)); mySerial.print("GSM"); mySerial.print(char(34)); mySerial.print("\r"); //кодировка GSM delay(500); mySerial.print("AT+IFC=1, 1\r"); //устанавливает программный контроль потоком передачи данны // delay(300); //mySerial.print("AT+CPBS=\"SM\"\r"); //открывает доступ к данным телефонной книги SIM-карты delay(500); mySerial.print("AT+CNMI=1,2,2,1,0\r"); //включает оповещение о новых сообщениях // Serial.print("AT+CNMI=1,2,2,1,0\r"); // mySerial.print("AT+CMGDA="DEL ALL"\r"); // удаляем все смски из памяти delay(2500); } void openport () //активирует usb-uart { if (mySerial.available()) Serial.write(mySerial.read()); if (Serial.available()) { while (Serial.available()) { mySerial.write(Serial.read()); } mySerial.println(); } } void infonet() //инфо о сети и пр. { //mySerial.println("at"); mySerial.println("AT+COPS?"); delay(500); mySerial.println("AT+creg?"); delay(500); mySerial.println("AT+CSQ"); //mySerial.println("at"); delay(2000); } int recivesms() { volatile int _comand = 0; if (!mySerial.available()) return _comand; char currSymb = mySerial.read(); Serial.print(currSymb); if ('\r' == currSymb) { if (isStringMessage) { //если текущая строка - SMS-сообщение, //отреагируем на него соответствующим образом if (!currStr.compareTo("On")) { _comand = 1; //Serial.print (_comand); } else if (!currStr.compareTo("Off")) { _comand = 2; } else if (!currStr.compareTo("Temp")) { _comand = 3; } else if (!currStr.compareTo("Net")) { _comand = 4; } else if (!currStr.compareTo("Echo")) { _comand = 5; } else if (!currStr.compareTo("SMS off")) { _comand = 6; } else if (!currStr.compareTo("Status")) { _comand = 7; } isStringMessage = false; } else { if (currStr.startsWith("+CMT")) { //если текущая строка начинается с "+CMT", //то следующая строка является сообщением isStringMessage = true; } } currStr = ""; } else if ('\n' != currSymb) { currStr += String(currSymb); } return _comand; Serial.print("_comand="); Serial.print(_comand); } void sendsms(char *currsms) //процедура отправки СМС { Serial.println("SMS send started"); mySerial.println("AT+CMGF=1"); delay(500); Serial.println("AT+CMGF=1"); mySerial.print("AT+CMGS="); mySerial.print(char(34)); mySerial.print(MasterNum) ; mySerial.print(char(34)); mySerial.println(); Serial.print("AT+CMGS="); Serial.print(char(34)); Serial.print(MasterNum) ; Serial.print(char(34)); Serial.println(); delay(500); Serial.println ("Msg sending:"); Serial.println(currsms); //Serial.print(char(26)); mySerial.print(currsms); mySerial.print(char(26)); Serial.println("SMS send complete"); delay(2000); } boolean Vib (int PinVib) { if (digitalRead(PinVib) != HIGH) { return true; } else { return false; } } boolean Gercon(int Pingercon) { if (digitalRead(Pingercon) != HIGH) { return true; } else { return false; } } float Temperature(int Pintemp) { // код return celsius; }ой жуть какая.
Признайтесь. сколько дней вы программируете? Один?
Зачем начинать с таких сложных скетчей. помигайте сначала диодами.
Если честно - рука устанет перечислять все ошибки в коде.
Самое главное - функция, вызываемая прерыванием - или аналогичная, вызываемая библиотекой работы с таймерами - должна отрабатывать максимально быстро! Реально - вызвали, проверили одно-два условия. выставили флаг о результате - и ВЫШЛИ. А у вас половина программы запихнута в функцию timerInterupt()
Признаюсь, довольно долго. Мигать диодами может быть скучно, а нужные проекты требуют усилий.
Ваше замечание учту, спасибо, но от проблем генерации массива символов не уйти.
Совет - оставьте в скетче только генерацию текста СМС- без таймеров и интерруптов. И сначала добейтесь, чтобы оно работало. Когда получится - добавляйте в основную программу.
Тот код, что вы привели- вы явно откуда-то списали и сами не понимаете. Я бы советовал не искать в нем ошибки, а написать свой. заново. самостоятельно. Код совершенно жуткий и ошибок в нем куча.
Совет - оставьте в скетче только генерацию текста СМС- без таймеров и интерруптов. И сначала добейтесь, чтобы оно работало. Когда получится - добавляйте в основную программу.
Хорошо. Какой вариант генерации текста оптимальный, если не указатель-массив? Функция strcat в этих же условиях зависает так же, String делает больше проходов, но на второй-третий вызов - зависает.
Тот код, что вы привели- вы явно откуда-то списали и сами не понимаете. Я бы советовал не искать в нем ошибки, а написать свой. заново. самостоятельно. Код совершенно жуткий и ошибок в нем куча.
Ну да, отсюда: http://cpp.com.ru/kr_cbook/ch5kr.html :)