![]() |
![]() ![]() |
|
Вопросы о SMH-2G(i) Здесь всё, что касается работы контроллера SMH-2G(i). |
![]() |
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Senior Member
Регистрация: Oct 2011
Сообщения: 184
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
![]()
На работающем объекте на контроллере 2Gi появилась подобная надпись. Пароль root никто не сбрасывал. Помимо "ядро убито" есть еще "превышено время цикла" и "озу переполнено" и еще "обратитесь в сегнетикс".
![]() ![]() В чем может быть причина и как такого избежать в будущем? Некамильфо ездить за тыщу километров для смены контроллера... Причину появления этого можете сказать? На кого списывать расходы на поездку: эксплуатация виновата, программист или производитель контроллера? Последний раз редактировалось Arsie, 23.07.2013 в 12:06 |
![]() |
![]() |
![]() |
#2 |
Senior Member
Регистрация: Oct 2011
Сообщения: 184
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
![]()
Обновление ПО до последних версий не помогло. В системных авариях все те же ошибки.
Последний раз редактировалось Arsie, 23.07.2013 в 12:06 |
![]() |
![]() |
![]() |
#3 |
Сотрудник Segnetics
Регистрация: Jan 2006
Адрес: Russia, SPb
Сообщения: 18 160
Благодарил(а): 15 раз(а)
Поблагодарили:
665 раз(а) в 607 сообщениях
|
![]()
По фотографии только можно сказать, что у контроллера по какой-то причине одна из программ заполнила ОЗУ до отказа. В результате этого заполнения ядро SMLogix было принудительно выгружено из памяти.
__________________ Программа делает то что написал программист, а не то что он хотел. Добро всегда побеждает зло. Кто победил - тот и добрый. Последний раз редактировалось Arsie, 25.07.2013 в 12:45 |
![]() |
![]() |
![]() |
#4 |
Сотрудник Segnetics
Регистрация: Dec 2008
Адрес: Оракул отдела продаж ООО"Сегнетикс"+7(812)564-50-01
Сообщения: 411
Благодарил(а): 90 раз(а)
Поблагодарили:
28 раз(а) в 27 сообщениях
|
![]()
Скажите пожалуйста у Вас в контроллере загружено:
только "проект лоджика" или "проект лоджика" + "программа на С++" |
![]() |
![]() |
![]() |
#5 | |
Сотрудник Segnetics
Регистрация: Jan 2006
Адрес: Russia, SPb
Сообщения: 18 160
Благодарил(а): 15 раз(а)
Поблагодарили:
665 раз(а) в 607 сообщениях
|
![]() Цитата:
Однако обращу ваше внимание, что не раз бывали случаи, когда контроллеры обвинялись во всех смертных грехах, а на поверку оказывалось, что умирали они от искусственных причин. Например от частой записи в блоках EEPROM/ARRAY, что в случае SMH-2Gi исчерпывает ресурс энергонезависимой памяти и операционная система начинает работать с разнообразнейшими глюками. Совсем как Windows на компьютере с умирающим HDD. __________________ Программа делает то что написал программист, а не то что он хотел. Добро всегда побеждает зло. Кто победил - тот и добрый. Последний раз редактировалось Arsie, 24.07.2013 в 11:42 |
|
![]() |
![]() |
![]() |
#6 |
Senior Member
Регистрация: Oct 2011
Сообщения: 184
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
![]()
В контроллер залит проект лоджика и программа на С++ (на основе примера регистратор - на USB накопитель в текстовый файл записываются 3 перменные с периодом в 10 сек).
|
![]() |
![]() |
![]() |
#7 |
Сотрудник Segnetics
Регистрация: Jan 2006
Адрес: Russia, SPb
Сообщения: 18 160
Благодарил(а): 15 раз(а)
Поблагодарили:
665 раз(а) в 607 сообщениях
|
![]()
Можно увидеть текст программы на C?
__________________ Программа делает то что написал программист, а не то что он хотел. Добро всегда побеждает зло. Кто победил - тот и добрый. |
![]() |
![]() |
![]() |
#8 |
Senior Member
Регистрация: Oct 2011
Сообщения: 184
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
![]()
Я не специализируюсь в програмировании на языке С, но по Вашему примеру удалось написать рабочий код, выполняющий необходимый функционал:
Код:
// ASHATLY TankLine #include "shm.hpp" #include <sys/vfs.h> #include <sys/mount.h> // В данном случае файл сохраняется в корневом каталоге ЗУ. // Ниже определен полный путь к нашему файлу в файловой системе SMH 2Gi. //#define MY_FLASH_FILENAME "/media/u1/mylog.txt" // SMH 2Gi сам автоматически всегда монтирует ЗУ именно в /media/u1 // Каталог, куда смон#define MY_FLASH_FILENAME "/media/u1/mylog.txt"тировано ЗУ, менять не нужно #define FLASH_MOUNT_DIR "/media/u1" // Идентификатор типа файловой системы FAT #define TYPE_VFAT 0x4d44 //Инициализация переменных разделяемой памяти Shm mymem("./load_files.srv"); void log_value_E1(const char* name, float value) { struct statfs flash_fs; char s [80]; //char MY_FLASH_FILENAME [100]; struct tm *ptr; // Вызов функции сбора информации о // подключенной файловой системе statfs(FLASH_MOUNT_DIR, &flash_fs); // Проверяем, подключен ли usb flash drive // по типу смонтированной файловой системы if (flash_fs.f_type != TYPE_VFAT) return; // Если не подключен - завершаем выполнение функции // формирование имени файла с датой time_t curtime = time(NULL); // Сохраним время для конвертации в строковый формат ptr = localtime((&curtime)); strftime(s,80,"/media/u1/%d.%m.%Y_",ptr); char*MY_FLASH_FILENAME = strncat(s,"mylog_E1.txt",100); // открыть файл для записи с добавлением в конец файла FILE* pfd = fopen(MY_FLASH_FILENAME, "a"); //time_t curtime = time(NULL); // Сохраним время для конвертации в строковый формат //char *s = ctime(&curtime); // Вызов функции конвертации в строковый формат //ptr = localtime((&curtime)); strftime(s,100,"%d.%m.%Y %H:%M:%S",ptr); //s[strlen(s) - 1] = 0; // Избавление от символа перевода строки //запись время, имя, значение fprintf(pfd,"%s; %s; %f \r\n",name,s,value); fclose(pfd); } void log_value_E2( const char* name, float value) { struct statfs flash_fs; char s [80]; //char MY_FLASH_FILENAME [100]; struct tm *ptr; // Вызов функции сбора информации о // подключенной файловой системе statfs(FLASH_MOUNT_DIR, &flash_fs); // Проверяем, подключен ли usb flash drive // по типу смонтированной файловой системы if (flash_fs.f_type != TYPE_VFAT) return; // Если не подключен - завершаем выполнение функции // формирование имени файла с датой time_t curtime = time(NULL); // Сохраним время для конвертации в строковый формат ptr = localtime((&curtime)); strftime(s,80,"/media/u1/%d.%m.%Y_",ptr); char*MY_FLASH_FILENAME = strncat(s,"mylog_E2.txt",100); // открыть файл для записи с добавлением в конец файла FILE* pfd = fopen(MY_FLASH_FILENAME, "a"); //time_t curtime = time(NULL); // Сохраним время для конвертации в строковый формат //char *s = ctime(&curtime); // Вызов функции конвертации в строковый формат //ptr = localtime((&curtime)); strftime(s,100,"%d.%m.%Y %H:%M:%S",ptr); //s[strlen(s) - 1] = 0; // Избавление от символа перевода строки //запись время, имя, значение fprintf(pfd,"%s; %s; %f \r\n",name,s,value); fclose(pfd); } void log_value_E3( const char* name, float value) { struct statfs flash_fs; char s [80]; //char MY_FLASH_FILENAME [100]; struct tm *ptr; // Вызов функции сбора информации о // подключенной файловой системе statfs(FLASH_MOUNT_DIR, &flash_fs); // Проверяем, подключен ли usb flash drive // по типу смонтированной файловой системы if (flash_fs.f_type != TYPE_VFAT) return; // Если не подключен - завершаем выполнение функции // формирование имени файла с датой time_t curtime = time(NULL); // Сохраним время для конвертации в строковый формат ptr = localtime((&curtime)); strftime(s,80,"/media/u1/%d.%m.%Y_",ptr); char*MY_FLASH_FILENAME = strncat(s,"mylog_E3.txt",100); // открыть файл для записи с добавлением в конец файла FILE* pfd = fopen(MY_FLASH_FILENAME, "a"); //time_t curtime = time(NULL); // Сохраним время для конвертации в строковый формат //char *s = ctime(&curtime); // Вызов функции конвертации в строковый формат //ptr = localtime((&curtime)); strftime(s,100,"%d.%m.%Y %H:%M:%S",ptr); //s[strlen(s) - 1] = 0; // Избавление от символа перевода строки //запись время, имя, значение fprintf(pfd,"%s; %s; %f \r\n",name,s,value); fclose(pfd); } // ----------------------------------------------------------------------------- // Функция main, с нее начинается выполнение программы // ----------------------------------------------------------------------------- int main() { //Инициализация переменных разделяемой памяти Shm mymem("./load_files.srv"); if (mymem.getType("Var1") != FLOAT) exit(1); if (mymem.getType("Var2") != FLOAT) exit(1); if (mymem.getType("Var3") != FLOAT) exit(1); if (mymem.getType("Eject") != BOOL) exit(1); if (mymem.getType("mount") != BOOL) exit(1); if (mymem.getType("WathDog") != BOOL) exit(1); if (mymem.getType("E1_OPER") != SHORT) exit(1); if (mymem.getType("E2_OPER") != SHORT) exit(1); if (mymem.getType("E3_OPER") != SHORT) exit(1); if (mymem.getType("E1_Tset") != FLOAT) exit(1); if (mymem.getType("E2_Tset") != FLOAT) exit(1); if (mymem.getType("E3_Tset") != FLOAT) exit(1); if (mymem.getType("E1_TaskTime") != SHORT) exit(1); if (mymem.getType("E2_TaskTime") != SHORT) exit(1); if (mymem.getType("E3_TaskTime") != SHORT) exit(1); float Var1, Var2, Var3;// Параметр из FBD short E1_OPER, E2_OPER, E3_OPER; struct timespec tv; // Создание структуры задержки tv.tv_sec = 0; // было 0 tv.tv_nsec = 1000000; // Инициализация структуры задержки (1мс) было 1000000 E1_OPER = 0; E2_OPER = 0; E3_OPER = 0; while (1) { time_t timeto; // Сохранение текущего системного времени (в секундах) timeto = time(NULL) + 10; // Цикл ожидания новых данных, или отсечки по времени если таковых нет do { // задержка, чтобы не занимать процессорное время // слишком частыми операциями опроса переменной nanosleep(&tv, NULL); // Устнановлена ли переменная Eject в 1 if (mymem.getBool("Eject")) { // произведем размонтирование ЗУ umount(FLASH_MOUNT_DIR); // и снимаем уведомление ПЛК о том, что флешка готова //mymem.setBool("mount", false); break; // выходим из цикла } // Если прошло 10 секунд, то также выходим из цикла } while (timeto > time(NULL)); Var1 = mymem.getFloat("Var1"); // Функция сохранения значения в файл // | функция | имя | значение | log_value_E1("Var1", Var1); //} Var2 = mymem.getFloat("Var2"); log_value_E2("Var2", Var2); Var3 = mymem.getFloat("Var3"); log_value_E3("Var3", Var3); // 1 - нагрев // 2 - выдержка // 3 - охлаждение 1 // 4 - сквашивание // 5 - охлаждение 2 if (E1_OPER != mymem.getShort("E1_OPER")) { E1_OPER = mymem.getShort("E1_OPER"); log_value_E1("E1_OPER", E1_OPER); log_value_E1("E1_Tset", mymem.getFloat("E1_Tset")); if (E1_OPER == 2 || E1_OPER == 4 ) log_value_E1("E1_TaskTime", mymem.getShort("E1_TaskTime")); } if (E2_OPER != mymem.getShort("E2_OPER")) { E2_OPER = mymem.getShort("E2_OPER"); log_value_E2("E2_OPER", E2_OPER); log_value_E2("E2_Tset", mymem.getFloat("E2_Tset")); if (E2_OPER == 2 || E2_OPER == 4 ) log_value_E2("E2_TaskTime", mymem.getShort("E2_TaskTime")); } if (E3_OPER != mymem.getShort("E3_OPER")) { E3_OPER = mymem.getShort("E3_OPER"); log_value_E3("E3_OPER", E3_OPER); log_value_E3("E3_Tset", mymem.getFloat("E3_Tset")); if (E3_OPER == 2 || E3_OPER == 4 ) log_value_E3("E3_TaskTime", mymem.getShort("E3_TaskTime")); } struct statfs flash_fs; // Вызов функции сбора информации о // подключенной файловой системе statfs(FLASH_MOUNT_DIR, &flash_fs); if (flash_fs.f_type == TYPE_VFAT) { // уведомляем ПЛК о том, что флешка готова mymem.setBool("mount", true); } else mymem.setBool("mount", false); // WathDog if (mymem.getBool("WathDog")) mymem.setBool("WathDog", false); else mymem.setBool("WathDog", true); //Вычисление свободного дискового пространства //float FreeDiskSpace = (float) flash_fs.f_bfree / (float) flash_fs.f_blocks * 100.0; //Передача данных о свободном дисковом пространстве в FBD-проект //mymem.setFloat("FreeDiskSpace", FreeDiskSpace); // mymem.setFloat("FreeDiskSpace", 0.0); } } |
![]() |
![]() |
![]() |
#9 | |
Сотрудник Segnetics
Регистрация: Jan 2006
Адрес: Russia, SPb
Сообщения: 18 160
Благодарил(а): 15 раз(а)
Поблагодарили:
665 раз(а) в 607 сообщениях
|
![]() Цитата:
У вас в коде постоянно встречаются следующие комбинации: char s [80]; strftime(s,80,"/media/u1/%d.%m.%Y_",ptr); strncat(s,"mylog_E1.txt",100); Вы выделяете под строку массив из 80 байт. В этом массиве может храниться строка из 80 символов (79 букв + #0). Но ниже с этой 80-символьной строкой работаете как с 80-символьной и 100-символьной. Если в какой-то момент времени число значащих символов превысит 79, то неконтролируемо испортится информация в ОЗУ и поведение контроллера станет непредсказуемым. PS. Дополнительно укажу, что если на "диске" контроллера останется слишком мало свободного места, то нестабильная работа также обеспечена. __________________ Программа делает то что написал программист, а не то что он хотел. Добро всегда побеждает зло. Кто победил - тот и добрый. |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Регистрация: Jan 2012
Адрес: Саратов
Сообщения: 179
Благодарил(а): 1 раз(а)
Поблагодарили:
3 раз(а) в 3 сообщениях
|
![]()
Попробуйте увеличить задержку. У меня
tv.tv_nsec = 90000000; // Инициализация структуры задержки (90мс для тика 100мс) |
![]() |
![]() |