|
Вопросы о SMH-2G(i) Здесь всё, что касается работы контроллера SMH-2G(i). |
|
Опции темы | Поиск в этой теме |
29.06.2012, 17:31 | #1 |
Новичок
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
Срочно! Помогите! О разделяемой памяти!
Всем добрый день!
Нужна помощь, может быть кто-нибудь у же сталкивался с проблемой вывода данных! Apache установлен на контроллере. Пробовал двумя способами: 1 способ: Через функцию shmop взаимодействовать с памятью. Взял адреса из файла load_files.srv. Он туда их автоматом прописывает. <?php // отрытие $shm_id = shmop_open(0xa0a8h, "c", 0644, 100); if(!$shm_id) { echo "Ошибка при открытии.\n"; } // Получаем размер сегмента разделяемой памяти $shm_size = shmop_size($shm_id); // Считываем $my_data = shmop_read($shm_id, 0, $shm_size); if(!$my_string) { echo "Ошибка при попытке чтения разделяемой памяти\n"; } echo " ".$my_data."\n"; //закрываем shmop_close($shm_id); ?> как бы работает- но выводит пустоту Тогда я решил поэкспериментировать и взял адрес из переменных modbus - вообще не работает(в плане того, что даже просто текст не выводит). 2 способ: Мне предложили чтобы прога на С записывала в файл , а потом уже от туда читать Как описано в мануале написали на С и добавили запись в файл залили в контроллер код: #include "shm.hpp" #include <stdio.h> #include <time.h> #include <unistd.h> #include <signal.h> #include <rlserial.h> int main() { Shm mymem("./load_files.srv"); //Инициализация переменных разделяемой памяти FILE *file; struct timespec tv;//Структура для задания временных интервалов tv.tv_sec = 0; tv.tv_nsec = 1000000000; //(наносекунд) задержка в 1 сек // хотя лучше сделать столько-же, сколько период обновления на веб-морде (!) while (1) // Бесконечный цикл { if ((file = fopen("result.txt","w")) == NULL) { printf("Can't open file\n"); exit(-1); } else { fprintf (file, "<?xml version=\"1.0\" encoding=\"cp1251\">"); fprintf (file, "<result>"); fprintf (file, "<bases>"); nanosleep(&tv, NULL); //выполняем задержку для экономии ресурсов //================================================== ==================// // mem_tech - температура наружняя // //================================================== ==================// if ( mymem.getType("mem_tech") == FLOAT ) { float mem_tech = mymem.getFloat("mem_tech"); fprintf(file,"<base>mem_tech = %f</base>",mem_tech); } else { fprintf(file,"<base>ERROR: mem_tech has type %d</base>",mymem.getType("mem_tech")); exit(-1); } //================================================== ==================// // mem_in - температура канала // //================================================== ==================// if ( mymem.getType("mem_in") == FLOAT ) { float mem_in = mymem.getFloat("mem_in"); fprintf(file,"<base>mem_in = %f</base>",mem_in); } else { fprintf(file,"<base>ERROR: mem_in has type %d</base>",mymem.getType("mem_in")); exit(-1); } //================================================== ==================// // mem_out - температура обр_воды // //================================================== ==================// if ( mymem.getType("mem_out") == FLOAT ) { float mem_out = mymem.getFloat("mem_out"); fprintf(file,"<base>mem_out = %f</base>",mem_out); } else { fprintf(file,"<base>ERROR: mem_out has type %d</base>",mymem.getType("mem_out")); exit(-1); } //================================================== ==================// // mem_room - температура помещения // //================================================== ==================// if ( mymem.getType("mem_room") == FLOAT ) { float mem_room = mymem.getFloat("mem_room"); fprintf(file,"<base>mem_room = %f</base>",mem_room); } else { fprintf(file,"<base>ERROR: mem_room has type %d</base>",mymem.getType("mem_room")); exit(-1); } fprintf (file, "</bases>"); fprintf (file, "</result>"); fclose(file); } } } Но почему-то он записывает в файл "-1" От сюда можно сделать вывод - он не берет значения! Почему? Подскажите что делать? Как дальше жить? |
02.07.2012, 09:18 | #2 |
Новичок
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
Ответ: Срочно! Помогите! О разделяемой памяти!
Расскажу более подробно мою задачу!
Дело в том, что мне нужно вывести данные о состоянии системы на сайт, чтобы любой кто имеет доступ к этому, мог посмотреть данные о температуре, авариях, какие устройства на данный момент включены, а также мог запустить или остановить устройства, внести корректировки в некоторые данные(например какая температура должна поддерживаться в помещении) Так вот, как я понимаю есть 2 способа(какой из них лучше и практичнее я не знаю, мне просто нужен способ рабочий , чтобы реализовать свою задачу о выводе и редактирования некоторых данных): 1 способ: взаимодействие напрямую php и smlogix через shared memory(схему смотрим ниже-shmop) задача: вывести температуру помещения на встроенный сайт В проект я добавил mem-блок "mem_room", залил на контроллер-написал код(смотрим выше, адрес памяти взял из файла load_files.srv) И пока не получается вывести это. Может быть, я что-то не то делаю, подскажите. 2 способ написать программу , которая будет брать данные shared memory и записывать в xml файл постоянно - далее с помощью технологии ajax выводить это на сайт (схема ниже - xml) В проект я добавил mem-блок "mem_room", залил на контроллер. Через виртуальную машину написал программу на С (код выше)- залил на контроллер. И на это я и застопорился. Так вот он создает файл, но почему- то записывает туда -1. Подскажите, почему так? Заранее благодарен! |
02.07.2012, 11:31 | #3 | |
Сотрудник Segnetics
Регистрация: Jan 2006
Адрес: Russia, SPb
Сообщения: 18 117
Благодарил(а): 15 раз(а)
Поблагодарили:
660 раз(а) в 604 сообщениях
|
Ответ: Срочно! Помогите! О разделяемой памяти!
Цитата:
Нужен не адрес, а "ключ файла", который генерится специальной функцией, которую для пхп я не знаю. В "обычной жизни" она называется ftokey или как-то похожим образом. Ну и вот: http://ru2.php.net/manual/ru/function.shmop-open.php __________________ Программа делает то что написал программист, а не то что он хотел. Добро всегда побеждает зло. Кто победил - тот и добрый. |
|
02.07.2012, 16:17 | #4 |
Новичок
Регистрация: May 2010
Сообщения: 26
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
Ответ: Срочно! Помогите! О разделяемой памяти!
Из того что делал я в качестве эксперимента:
1) Пишем программу на С++ для смлоджика которая является сервером разделяемых переменных по стандартному сокету. 2) В скрипте php открываем сокет, подключаемся к нашему серверу, делаем запрос 3) сервер отвечает, результат = значение нашей переменной. Запрос для переменной может быть простой текстовый вида "Get01", "Get02" и тд. Впринципе можно передавать и массивом сразу все переменные. |
03.07.2012, 12:34 | #5 |
Новичок
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
Ответ: Срочно! Помогите! О разделяемой памяти!
Спасибо за ответы! Будем пробовать! Потом обязательно отпишусь! Будут идеи с удовольствием выслушаю
|
03.07.2012, 13:07 | #6 |
Новичок
Регистрация: May 2010
Сообщения: 26
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
Ответ: Срочно! Помогите! О разделяемой памяти!
По поводу записи в файл. Делал запись и чтение параметров из файла, у меня работало, но были проблемы с обновлением данных (т.е) скорость работы оставляла желать лучшего, да и ресурс памяти контроллера убивается очень быстро.
По поводу чтения разделяемой памяти не уверен что апач вообще корректно будет работать с смлоджиком. Оптимальным решением было написание именно простенького однопоточного сервера (1 слушатель и 1 клиент) обрабатывающий запросы "Set" и "Get" (часа 2-3 на написание и отладку). +: 1) Простота 2) Надежность 3) Универсальность -: 1) Относительно низкая скорость работы, время ответа на один запрос около 50 мс. (Хотя можно добиться и большего быстродействия, при уменьшении времени основного цикла) Для месье знающих толк в извращениях)) можно посоветовать прикрутить библиотеку ModbusTCP слэйв к апачу (ну либо написать её самому) |
04.07.2012, 12:00 | #7 |
Новичок
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
Ответ: Срочно! Помогите! О разделяемой памяти!
Кто может объяснить мне:
Есть функция float getFloat(const char * name, float val), она вызывает get() с определенным набором параметров, а get() натравливает IsFound() на поиск имени переменной в map , которая собирается с ини-файла. Собирается все отлично, переменные, их тип и адреса видны в файлике load_files.srv. НО! Когда мы начинаем брать значения этих переменных (хоть по имени, хоть по номеру из этого файла) - нам возвращают -1 в первом случае и NULL во втором. Тут и начинается самое интересное: - В смлоджик имена менял (на всякий) - ноль эмоций - Контроллер рестартил - Наткнулся на кучу ерроров нетбинс (IDE на убунте), которая не может распарсить итераторы у мапа (хотя на это можно положить) - Обнаружил очень интересную фичу: раньше итемы в листе собирали с чарами, а теперь решили собрать со стрингом. На всякий, оставив комментами старые методы. Если честно, возвращать обратно чары не вижу смысла (см. про NULL в ответ на запрос по номеру переменной), но интересен сам факт - видимо с именами проблемы уже были. #include "shm.hpp" int main() { Shm mymem("./load_files.srv"); //Инициализация переменных разделяемой памяти //FILE *file; struct timespec tv;//Структура для задания временных интервалов tv.tv_sec = 0; tv.tv_nsec = 100000000; //(наносекунд) задержка в 1 сек // хотя лучше сделать столько-же, сколько период обновления на веб-морде (!) if (( mymem.getType("mem_tech") == FLOAT ) && \ ( mymem.getType("mem_in") == FLOAT ) && \ ( mymem.getType("mem_out") == FLOAT ) && \ ( mymem.getType("mem_room") == FLOAT )) for (int i=0;i<50;i++) // Бесконечный цикл { /*if ((file = fopen("result.txt","w")) == NULL) { printf("Can't open file\n"); exit(-1); } else { fprintf (file, "<?xml version=\"1.0\" encoding=\"cp1251\">"); fprintf (file, "<result>"); fprintf (file, "<bases>");*/ nanosleep(&tv, NULL); //выполняем задержку для экономии ресурсов //================================================== ==================// // mem_tech - температура наружняя // //================================================== ==================// float mem_tech = mymem.getFloat(6); //fprintf(file,"<base>mem_tech = %f</base>",mem_tech); printf("<base>mem_tech = %3.6f</base>\n",mem_tech); //================================================== ==================// // mem_in - температура канала // //================================================== ==================// float mem_in = mymem.getFloat(7); //fprintf(file,"<base>mem_in = %f</base>",mem_in); printf("<base>mem_in = %f</base>\n",mem_in); //================================================== ==================// // mem_out - температура обр_воды // //================================================== ==================// float mem_out = mymem.getFloat(8); //fprintf(file,"<base>mem_out = %f</base>",mem_out); printf("<base>mem_out = %f</base>\n",mem_out); //================================================== ==================// // mem_room - температура помещения // //================================================== ==================// float mem_room = mymem.getFloat(9); //fprintf(file,"<base>mem_room = %f</base>",mem_room); printf("<base>mem_room = %f</base>\n",mem_room); /*fprintf (file, "</bases>"); fprintf (file, "</result>"); fclose(file); }*/ printf("=====\n"); } else { //fprintf(file,"<base>ERROR: mem_tech has type %d</base>",mymem.getType("mem_tech")); printf("ERROR: mem_tech has type %d\n",mymem.getType("mem_tech")); //fprintf(file,"<base>ERROR: mem_in has type %d</base>",mymem.getType("mem_in")); printf("ERROR: mem_in has type %d\n",mymem.getType("mem_in")); //fprintf(file,"<base>ERROR: mem_out has type %d</base>",mymem.getType("mem_out")); printf("ERROR: mem_out has type %d\n",mymem.getType("mem_out")); //fprintf(file,"<base>ERROR: mem_room has type %d</base>",mymem.getType("mem_room")); printf("ERROR: mem_room has type %d\n",mymem.getType("mem_room")); exit(-1); } printf("DONE\n"); } Собственно вопрос: в каком случае вашими нативными методами нельзя взять перменные? (хотелось бы МАКСИМАЛЬНО подробно) |
04.07.2012, 14:58 | #8 | |
Новичок
Регистрация: May 2010
Сообщения: 26
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
Ответ: Срочно! Помогите! О разделяемой памяти!
Что сразу бросается в глаза.
Цитата:
Цикл ни разу не бесконечный, а длится 5 сек. В связи с этим, проверьте что за это время переменные принимают какие то осмысленные значения. Используйте вызов функций вида GetFloat("Название переменной"). Проверьте на переменных другого типа-Short, Long. |
|
04.07.2012, 18:00 | #9 |
Новичок
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили:
0 раз(а) в 0 сообщениях
|
Ответ: Срочно! Помогите! О разделяемой памяти!
Да просто комменты не убрал со старого цикла.
> проверьте что за это время переменные принимают какие то осмысленные значения свой проект я запускаю при старте процесса logix, и дополнительно запускаю руками - поэтому переменные явно успевают стать осмысленными. Так а толку от других типов? Мне нужны градусы с большой точность. Целочисленным типом здесь делать нечего, даже если он заработает. |