Jump to content
Форум по продукции MOXA

IA-240LX - помогите чайнику! (очень нужно)


Recommended Posts

Имеется проект на одном устройстве - при запуске с помощью bash скрипта:

1) - запускаются 4 экземпляра сервера modbusRTUserverS (тут проблем нет) для каждого последовательного порта с прослушиванием для каждого своего TCP порта - соответственно.

2) - запускается "сервер межпроцессовой связи"

3) - запускаются 4 процесса для работы с 4 интерфейсами по ModbusRTU через запущенные серверы. И эти же процессы взаимодействуют между собой через заранее запущенный "сервер межпроцессорной связи"

Все взаимодействия через локальные (127.0.0.1) TCP соединения. Т.е. всё запущено на одном устройстве.

 

Собственно проблема: "слипаются" данные двух последних рабочих процессов. Выглядит это по консольному выводу "сервера связи" повторений данных для этих последних процессов, которые управляют двумя частотными преобразователями по двум разным ModbusRTU соединениям через серверы  modbusRTUserverS. Всё это запускается от имени пользователя. При консольном выводе для каждого процесса вроде всё нормально. Сервер связи - точнее его потоки(многопоточная схема) испытал и отделяемые и не отделяемые. Возможно на каждый поток надо указать свой стек и т.п. но примеры для MOXA не компилятся

 

при выполнеии команды free занято 30М из 60М (округляю) и буфер более 3М. Обращение каждого процесса к "серверу связи" для приёма и передачи проискодит (интервал) 50мс. с таким же интервалом происходит обращение каждого процесса к устройствам по ModbusRTU через соответствующие серверы.

 

Может есть у кого соображения. Может выделение памяти как-то изменить?

Оборудование почти оживил (разработал) но вот возникла эта проблема в процессе пусконаладки. Ранее делал похожую схему, но без сервера связи, а через файлы на рам диске, но там и время реакции было не так важно.

Уже не знаю куда копать! Исходники если угодно могу выложить.

 

Точнее выкладываю - иначе некрасиво как-то и непонятно тоже.

 

src.tar

 

Сам думаю что что-то с выделением памяти, но не знаю что и как конфигурировать(возможно надо чтото в /etc или ещё где менять). Может какие ключи при компиляции?

 

Вот так выглядит отчёт:

 

console.doc

 

Заранее благодарен!

 

Link to comment

Здравствуйте!

 

Опишите, пожалуйста, конкретно, по пунктам:

1) Назначение каждого из элементов системы (modbusRTUserverS, сервер межпроцессной связи, процессы IA240_modbusx).

2) Что подразумевается под взаимодействием процессов между собой? Они пересылают какие-то данные или, может, один процесс вызывает участки кода второго процесса или ещё что-то?

3) В чём именно состоит проблема? Неправильно выводятся данные на консоль или есть какие-то более серьёзные последствия?

4) Какой из элементов выводит первый ("правильный"), а какой - второй ("неправильный") отчёт?

5) Какие участки кода отвечают за формирование отчётов?

6) В каких условиях выводится первый, а в каких - второй отчёт? Что нужно сделать, чтобы программа, работающая правильно, стала работать неправильно или наоборот?

7) Вы указываете на объём занятой памяти. Избыточно ли оно для Вашей задачи? Или другими словами - это описание второй проблемы или условий? Изменяется ли объём занятой памяти со временем? Насколько быстро?

Link to comment

Здравствуйте!

 

Опишите, пожалуйста, конкретно, по пунктам:

1) Назначение каждого из элементов системы (modbusRTUserverS, сервер межпроцессной связи, процессы IA240_modbusx).

2) Что подразумевается под взаимодействием процессов между собой? Они пересылают какие-то данные или, может, один процесс вызывает участки кода второго процесса или ещё что-то?

3) В чём именно состоит проблема? Неправильно выводятся данные на консоль или есть какие-то более серьёзные последствия?

4) Какой из элементов выводит первый ("правильный"), а какой - второй ("неправильный") отчёт?

5) Какие участки кода отвечают за формирование отчётов?

6) В каких условиях выводится первый, а в каких - второй отчёт? Что нужно сделать, чтобы программа, работающая правильно, стала работать неправильно или наоборот?

7) Вы указываете на объём занятой памяти. Избыточно ли оно для Вашей задачи? Или другими словами - это описание второй проблемы или условий? Изменяется ли объём занятой памяти со временем? Насколько быстро?

 

1 - на Modbus 1 (/dev/ttyM0) экземпляр программы modbusRTUserverS (115200)- подключены: счётчик метража СИ30; Устройство ввода-вывода (кнопки - пуск/стоп, датчики положения ножниц и пневмоножницы обрезки кабеля). С этим работает процесс (программа) 1. Отвечает за изменение метража, процесс ножниц. Параметры настроек (задание, режим, состояние и т.п.) получает и принимает от других процессов *программ) 2...4 через программу "Сервер Связи". Данный процесс "ведущий"

2 - на Modbus  2 (/dev/ttyM1) экземпляр программы modbusRTUserverS (9600) - подключена панель ИП320. Ранее подключал это по Modbus 1, но это устройство имеет увеличенный интервал запрос-ответ и в результате пришлось его повесить на отдельный модбас и снизить скорость. Данная панель позволяет изменять и индицировать параметры работы. Все значения принимаются и передаются через "сервер связи" другим программам (процессам) 1,3,4.

3 - на Modbus  3 (/dev/ttyM2) экземпляр программы modbusRTUserverS (19200) - подключен частотный преобразователь привода протяжки кабеля. С ним работает программа (процесс) 3, которая получает значение задания метража, измеренный метраж и режим работы, а отдаёт процессу 1 свое состояние, ошибки, завершение и т.п.

4 - на Modbus  3 (/dev/ttyM3) экземпляр программы modbusRTUserverS (19200) - подключен частотный преобразователь привода намотки. Аналогично протяжке, но только в выбранном режиме намотки. Данный привод находится на удалении и в режиме протяжки может быть вообще не подключен (не подано питание).

 

"Сервер связи" (ServConn)только обмен между программами (процессами). По замыслу управляющие программы не обязательно могут находиться на одном устройстве (ну кроме modbusRTUserverS), но также на других IA240LX/UC-7112LX-Plus.

 

Запуск производится последовательно (скрипт Cabel - с параметром start или restart):

-Сначала запускаются серверы работы с портами Modbus RTU (modbusRTUserverS), каждый из которых в парметрах запуска получает номер последовательного порта, его настройки, и TCP порт прослушивания (для допуска других процессов к устройствам на соответствующем модбасе)

-Затем запускается "сервер связи"(ServConn), котрый в параметрах запуска получает порт TCP.

-И запускаются все 4 программы (IA240_modbus1, IA240_modbus2, IA240_modbus3, IA240_modbus4) работы, котрые в своих параметрах запуска получают адреса и порты TCP соответствующих серверов Modbus для доступа к устройствам и адрес и порт TCP "сервера связи".

Таким образом каждая программа(процесс) отвечает за работу устройств только на "своём" модбасе, но при этом имеет(передаёт) данные от других программ, которые работают со своими устройствами на "своих" модбасах. Данная "схема" позволила максимально "распараллелить" всю работу. Кроме этого отладку программ можно производить и на ноутбуке (с Linux, если откомпилировать для него, разумеется кроме modbusRTUserverS, которая должна иметь свой указанный последоватеьный порт)  не загружая в устройство. Можно так же распределить задачи и на "соседних" устройствах и не обязательно именно IA20, при условии наличия связи между ними по сети Ethernet. Правда запускать их надо уже по своим правилам (автозапуск).

 

Собственно сейчас проблема в том, что данные о подключении и статусе работы, а так же параметры "путаются" (дублируются) на программах управления протяжкой и намоткой (IA240_modbus3, IA240_modbus4). Предположительно в "сервере связи" (ServConn) - вот и думаю, что что-то сбоит в обмене по TCP. Вроде всё обыскал. Может быть проблема и в том, что сервер связи многопоточная программа и для компиляции надо что-то указать (ключ -lpthread уже указан в Makefile) чтобы небыло "слипания" данных. Да кстати каждый процесс при связи с сервером связи имеет свой идентификатор (не путать с ID пакета в отчёте - это просто тестовый счётчик), а в сервере связи свои структуры данных для каждого идентификатора индивидуальны. Вот и не должны они путаться. И ещё это происходит только с этими двумя последними при запуске процессами (IA240_modbus3, IA240_modbus4). Но стоит оговориться что частотный преобразователь привода намотки не подключен. За это отвечает экземпляр сервера modbusRTUserverS на /dev/ttyM3, который сообщает процессу (программе) IA_240_modbus4 об ошибочном доступе к ПЧВ3 и повторяет попытку.

 

4) Какой из элементов выводит первый ("правильный"), а какой - второй ("неправильный") отчёт?

В отчете 3 и 4 столбцы в строке "stat" и ID не должны иметь одинаковые данные - потому как статус(в stat) связи с частотником протяжки имеет маску 0x08, а с частоткиком намотки 0x10 (правильно привод протяжки кодключен, а привод намотки нет):

 

--- ----------ServConn-------- ---

mb1 IDfr: 000010BF mb2 IDfr: 00000925 mb3 IDfr: 000010C1 mb4 IDfr: 000010B1 ---ID From

mb1 IDto: 000010BF mb2 IDto: 00000925 mb3 IDto: 000010C1 mb4 IDto: 000010B1 ---ID To

mb1 stat: 820100AF mb2 stat: 80000020 mb3 stat: 02000008 mb4 stat: 04000000 ---stat

mb1 mode: 86000028 mb2 mode: 820100AF mb3 mode: 820100AF mb4 mode: 820100AF ---mode

mb1 Lght: 0.000000 mb2 Lght: 0.000000 mb3 Lght: 0.000000 mb4 Lght: 0.000000 ---Lenght

mb1 SLgt: 0.000000 mb2 SLgt: 0.000000 mb3 SLgt: 0.000000 mb4 SLgt: 0.000000 ---Set Lenght

mb1eLgt1: 0.000000 mb2eLgt1: 0.000000 mb3eLgt1: 0.000000 ------------------ ---Set Err Correct Lenght M1

mb1eLgt2: 0.000000 mb2eLgt2: 0.000000 ------------------ mb4eLgt2: 0.000000 ---Set Err Correct Lenght M2

mb1 SCCt: 00000000 mb2 SCCt: 00000000 ------------------ ------------------ ---Set Cnt Cut

mb1 CntC: 00000000 mb2 CntC: 00000000 ------------------ ------------------ ---Cnt Cut

mb1_SPM1: 0.000000 ------------------ mb3_SPM1: 0.000000 ------------------ ---pr_speed_m1

mb1_SdM1: 3.000000 ------------------ mb3_SdM1: 3.000000 ------------------ ---pr_speed_m1_min

mb1_SuM1: 50.000000 ------------------ mb3_SuM1: 50.000000 ------------------ ---pr_speed_m1_max

------------------ ------------------ mb3_SLu1: 45.000000 ------------------ ---StepSpeedLenghtUp_m1

------------------ ------------------ mb3_SLd1: 45.000000 ------------------ ---StepSpeedLenghtDown_m1

------------------ ------------------ mb3_SLD1: 0.300000 ------------------ ---SetLenghtDelta_m1

mb1_SPM2: 0.000000 ------------------ ------------------ mb4_SPM2: 0.000000 ---pr_speed_m2

mb1_SdM2: 5.000000 ------------------ ------------------ mb4_SdM2: 5.000000 ---pr_speed_m2_min

mb1_SuM2: 50.000000 ------------------ ------------------ mb4_SuM2: 50.000000 ---pr_speed_m2_max

------------------ ------------------ ------------------ mb4_SLu2: 35.000000 ---StepSpeedLenghtUp_m2

------------------ ------------------ ------------------ mb4_SLd2: 35.000000 ---StepSpeedLenghtDown_m2

------------------ ------------------ ------------------ mb4_SLD2: 0.400000 ---SetLenghtDelta_m2

а вот неправильно (слиплись и статус и счётчик пакетов):

 

-- ----------ServConn-------- ---

mb1 IDfr: 000010BF mb2 IDfr: 00000925 mb3 IDfr: 000010BC mb4 IDfr: 000010BC ---ID From

mb1 IDto: 000010BF mb2 IDto: 00000925 mb3 IDto: 000010BA mb4 IDto: 000010BB ---ID To

mb1 stat: 820100AF mb2 stat: 80000020 mb3 stat: 02000008 mb4 stat: 02000008 ---stat

mb1 mode: 82000028 mb2 mode: 820100AF mb3 mode: 820100AF mb4 mode: 820100AF ---mode

mb1 Lght: 0.000000 mb2 Lght: 0.000000 mb3 Lght: 0.000000 mb4 Lght: 0.000000 ---Lenght

mb1 SLgt: 0.000000 mb2 SLgt: 0.000000 mb3 SLgt: 0.000000 mb4 SLgt: 0.000000 ---Set Lenght

mb1eLgt1: 0.000000 mb2eLgt1: 0.000000 mb3eLgt1: 0.000000 ------------------ ---Set Err Correct Lenght M1

mb1eLgt2: 0.000000 mb2eLgt2: 0.000000 ------------------ mb4eLgt2: 0.000000 ---Set Err Correct Lenght M2

mb1 SCCt: 00000000 mb2 SCCt: 00000000 ------------------ ------------------ ---Set Cnt Cut

mb1 CntC: 00000000 mb2 CntC: 00000000 ------------------ ------------------ ---Cnt Cut

mb1_SPM1: 0.000000 ------------------ mb3_SPM1: 0.000000 ------------------ ---pr_speed_m1

mb1_SdM1: 3.000000 ------------------ mb3_SdM1: 3.000000 ------------------ ---pr_speed_m1_min

mb1_SuM1: 50.000000 ------------------ mb3_SuM1: 50.000000 ------------------ ---pr_speed_m1_max

------------------ ------------------ mb3_SLu1: 45.000000 ------------------ ---StepSpeedLenghtUp_m1

------------------ ------------------ mb3_SLd1: 45.000000 ------------------ ---StepSpeedLenghtDown_m1

------------------ ------------------ mb3_SLD1: 0.300000 ------------------ ---SetLenghtDelta_m1

mb1_SPM2: 0.000000 ------------------ ------------------ mb4_SPM2: 0.000000 ---pr_speed_m2

mb1_SdM2: 5.000000 ------------------ ------------------ mb4_SdM2: 5.000000 ---pr_speed_m2_min

mb1_SuM2: 50.000000 ------------------ ------------------ mb4_SuM2: 50.000000 ---pr_speed_m2_max

------------------ ------------------ ------------------ mb4_SLu2: 35.000000 ---StepSpeedLenghtUp_m2

------------------ ------------------ ------------------ mb4_SLd2: 35.000000 ---StepSpeedLenghtDown_m2

------------------ ------------------ ------------------ mb4_SLD2: 0.400000 ---SetLenghtDelta_m2

 

Это происходит циклически около 30 на 30 секунд иногда реже или чаще.

 

5) Какие участки кода отвечают за формирование отчётов?

 

В сервере связи в цикле main (всего-навсего вывод на консоль некотрых данных сервера связи принятых от процессов и подготовленных для отправки им):

#if(_mdbg > 0)
	if(mdbgcnt < 1)
	{
		printf("\n---\t\t\t\t----------ServConn--------\t\t\t\t---\n");
		printf("mb1 IDfr: %.8X\tmb2 IDfr: %.8X\tmb3 IDfr: %.8X\tmb4 IDfr: %.8X\t---ID From\n", 
		work.mb1s.id, work.mb2s.id, work.mb3s.id, work.mb4s.id);
		printf("mb1 IDto: %.8X\tmb2 IDto: %.8X\tmb3 IDto: %.8X\tmb4 IDto: %.8X\t---ID To\n", 
		work.mb1c.id, work.mb2c.id, work.mb3c.id, work.mb4c.id);
		printf("mb1 stat: %.8X\tmb2 stat: %.8X\tmb3 stat: %.8X\tmb4 stat: %.8X\t---stat\n", 
		work.mb1s.stat, work.mb2s.stat, work.mb3s.stat, work.mb4s.stat);
		printf("mb1 mode: %.8X\tmb2 mode: %.8X\tmb3 mode: %.8X\tmb4 mode: %.8X\t---mode\n", 
		work.mb1c.mode, work.mb2c.mode, work.mb3c.mode, work.mb4c.mode);
		printf("mb1 Lght: %f\tmb2 Lght: %f\tmb3 Lght: %f\tmb4 Lght: %f\t---Lenght\n", 
		work.mb1s.Lenght, work.mb2c.Lenght, work.mb3c.Lenght, work.mb4c.Lenght);
		printf("mb1 SLgt: %f\tmb2 SLgt: %f\tmb3 SLgt: %f\tmb4 SLgt: %f\t---Set Lenght\n",
		work.mb1c.SetLenght, work.mb2s.SetLenght, work.mb3c.SetLenght, work.mb1c.SetLenght);
		printf("mb1eLgt1: %f\tmb2eLgt1: %f\tmb3eLgt1: %f\t------------------\t---Set Err Correct Lenght M1\n",
		work.mb1c.ErrSetLenghtM1, work.mb2s.ErrSetLenghtM1, work.mb3c.ErrSetLenghtM1);
		printf("mb1eLgt2: %f\tmb2eLgt2: %f\t------------------\tmb4eLgt2: %f\t---Set Err Correct Lenght M2\n",
		work.mb1c.ErrSetLenghtM2, work.mb2s.ErrSetLenghtM2, work.mb4c.ErrSetLenghtM2);
		printf("mb1 SCCt: %.8u\tmb2 SCCt: %.8u\t------------------\t------------------\t---Set Cnt Cut\n",
		work.mb1c.SetCntCut, work.mb2s.SetCntCut);
		printf("mb1 CntC: %.8u\tmb2 CntC: %.8u\t------------------\t------------------\t---Cnt Cut\n",
		work.mb1s.CntCut, work.mb2c.CntCut);
		printf("mb1_SPM1: %f\t------------------\tmb3_SPM1: %f\t------------------\t---pr_speed_m1\n",
		work.mb1s.pr_speed_m1, work.mb3c.pr_speed_m1);
		printf("mb1_SdM1: %f\t------------------\tmb3_SdM1: %f\t------------------\t---pr_speed_m1_min\n",
		work.mb1c.pr_speed_m1_min, work.mb3c.pr_speed_m1_min);
		printf("mb1_SuM1: %f\t------------------\tmb3_SuM1: %f\t------------------\t---pr_speed_m1_max\n",
		work.mb1c.pr_speed_m1_max, work.mb3c.pr_speed_m1_max);
		printf("------------------\t------------------\tmb3_SLu1: %f\t------------------\t---StepSpeedLenghtUp_m1\n",
		work.mb3c.StepSpeedLenghtUp);
		printf("------------------\t------------------\tmb3_SLd1: %f\t------------------\t---StepSpeedLenghtDown_m1\n",
		work.mb3c.StepSpeedLenghtWown);
		printf("------------------\t------------------\tmb3_SLD1: %f\t------------------\t---SetLenghtDelta_m1\n",
		work.mb3c.SetLenghtDelta);
		printf("mb1_SPM2: %f\t------------------\t------------------\tmb4_SPM2: %f\t---pr_speed_m2\n",
		work.mb1s.pr_speed_m2, work.mb4c.pr_speed_m2);
		printf("mb1_SdM2: %f\t------------------\t------------------\tmb4_SdM2: %f\t---pr_speed_m2_min\n",
		work.mb1c.pr_speed_m2_min, work.mb4c.pr_speed_m2_min);
		printf("mb1_SuM2: %f\t------------------\t------------------\tmb4_SuM2: %f\t---pr_speed_m2_max\n",
		work.mb1c.pr_speed_m2_max, work.mb4c.pr_speed_m2_max);
		printf("------------------\t------------------\t------------------\tmb4_SLu2: %f\t---StepSpeedLenghtUp_m2\n",
		work.mb4c.StepSpeedLenghtUp);
		printf("------------------\t------------------\t------------------\tmb4_SLd2: %f\t---StepSpeedLenghtDown_m2\n",
		work.mb4c.StepSpeedLenghtWown);
		printf("------------------\t------------------\t------------------\tmb4_SLD2: %f\t---SetLenghtDelta_m2\n",
		work.mb4c.SetLenghtDelta);
		//
		mdbgcnt	= (1000000 / _main_sleep);
  	}
	else
		mdbgcnt--;

при опции компиляции в файле config.h:

#define _mdbg			1		//консольное сообщение цикла main

6) В каких условиях выводится первый, а в каких - второй отчёт? Что нужно сделать, чтобы программа, работающая правильно, стала работать неправильно или наоборот?

Ничего делать не надо - само по себе.

 

7) Вы указываете на объём занятой памяти. Избыточно ли оно для Вашей задачи? Или другими словами - это описание второй проблемы или условий? Изменяется ли объём занятой памяти со временем? Насколько быстро?

Памяти пропасть - задачи-то небольшие!

Незначительно - практически незаметно. И в плюс и в минус.

Находясь в цехе это определить не удаётся. Нет возможности непрерывно наблюдать часами.

 

И последнее - забыл сказать. Компилировал пакетом для UC-7112-LX-Plus - думаю это не так важно (надеюсь там нет специальных ограничений - ранее им же и делал другие проекты). Может я не прав?

Link to comment

То есть, насколько я понимаю, система выглядит так: modbusRTUserverS - простые преобразователи Modbus RTU в TCP, а процессы IA240_modbus содержат всю рабочую логику, ведут обмен с устройствами, обращаясь к modbusRTUserverS, а между собой передают данные через сервер связи. При этом, modbusRTUserverS к серверу связи не имеют никакого отношения и нужно искать проблему именно во взаимодействии процессов и сервера.

Как процессы начинают работать с сервером связи? Они просто подключаются к нему или кроме подключения ещё и как-то регистрируются? Не может ли сервер связи как-то "перепутать" процессы во время регистрации? Как происходит процесс обмена данными? Хранит ли сервер связи какие-то данные или только передаёт их от отправителя к получателю? Передаются какие-то фрагменты данных (отдельные параметры) или все данные системы единым блоком? К чему именно относится отчёт? Это данные о зарегистрированных процессах, которые не меняются во время выполения, или таблица всех параметров, или такой отчёт относится только к одному сеансу связи? Не может ли какой-то процесс изменить поля stat, так что возникает эта проблема?

 

Link to comment

То есть, насколько я понимаю, система выглядит так: modbusRTUserverS - простые преобразователи Modbus RTU в TCP, а процессы IA240_modbus содержат всю рабочую логику, ведут обмен с устройствами, обращаясь к modbusRTUserverS, а между собой передают данные через сервер связи. При этом, modbusRTUserverS к серверу связи не имеют никакого отношения и нужно искать проблему именно во взаимодействии процессов и сервера.

Как процессы начинают работать с сервером связи? Они просто подключаются к нему или кроме подключения ещё и как-то регистрируются? Не может ли сервер связи как-то "перепутать" процессы во время регистрации? Как происходит процесс обмена данными? Хранит ли сервер связи какие-то данные или только передаёт их от отправителя к получателю? Передаются какие-то фрагменты данных (отдельные параметры) или все данные системы единым блоком? К чему именно относится отчёт? Это данные о зарегистрированных процессах, которые не меняются во время выполения, или таблица всех параметров, или такой отчёт относится только к одному сеансу связи? Не может ли какой-то процесс изменить поля stat, так что возникает эта проблема?

 

Именно так! modbusRTUserverS - обеспечение процесса обмена по Modbus RTU (CRC, контроль связи, повторение и т.п.); IA240_modbus(1..4) - логика работы; сервер связи обмен между IA240_modbus(1...4). Он содержит в себе структуры (массивы) данных для приёма и передачи каждому из IA240_modbus(1..4) в отдельности. Обмен организован через отдельные потки для каждого TCP соединения (синхронизация через мютекс). Его цикл Main производит копирование нужных данных из одной структуры(массива) принятых данных от одного IA240_modbus в массив для передачи другому IA240_modbus. Всё "синхронизировано" всесте с другими потками через мютекс. Кроме того при указании перед компиляцией"ключа":

#define _mdbg			1		//консольное сообщение цикла main

производикся компиляция для вывода отчёта по текущему консольному соединению, иначе без вывода.

 

Каждий из IA240_modbus(1..4) при запуске производит соединение с соответствующим сервером modbusRTUserverS и общим сервером связи. Таким образом modbusRTUserverS имеет непрерывное в процессе всей работы соединение с соответствующим IA240_modbus(1..4). А сервер связи имеет непрерывную связь со всеми четыремя IA240_modbus(1..4).

 

В отчёте только выборочная индикация параметров из массивов для каждого соединения IA240_modbus(1..4) и на процесс работы влиять не может.

 

Не может ли сервер связи как-то "перепутать" процессы во время регистрации?

 

По идее не может

тут при приёме запроса на соединение создаётся поток для соединения в сервере:

                ....
                csock = accept(listener,NULL,NULL);
                if((cserver.csock > 0) && (csock == cserver.csock))
                {
			pthread_mutex_unlock(&ServerMutex);
                        usleep(_listen_sleep);
			pthread_mutex_lock(&ServerMutex);
                        goto mt1;
                }
		//создание потока клиента
                printf("-----CLIENT-----\r\n");
                printf("-- sock. %i --\r\n", csock);
                count = 0;
                //тут ищем место для записи параметров соединения
                while(count < _max_sock)
                  {
                        if(cserver.midcl[count] == 0)
                        {
				#if(_dbg > 0)
					printf("ServCoon clien %i connecting...\n",count);
				#endif
                                cserver.csock	 		= csock;
                                cserver.idclient 		= count;
				cserver.midcl[count]		= 0xFF;
				//				
				pthread_attr_init(&cserver.tattr[count]);
				pthread_attr_setdetachstate(&cserver.tattr[count], PTHREAD_CREATE_DETACHED);
				//thread_attr_setscope(&cserver.tattr[count], PTHREAD_SCOPE_SYSTEM);
				//
                                //pthread_create(&cserver.pth[count],NULL,(void*) server_con, &cserver);
				pthread_create(&cserver.pth[count], &cserver.tattr[count],(void*) server_con, &cserver);
				//
                                cserver.cntclient++;
				break;
				//goto mt1;
                        }
                        count++;
                }

Сам поток (каждый из потоков) имеет собственный массив на приём и передачу в сервере:

//поток клиента
void server_con(CSERV * cs)
{
	int		countlive;
	int		setcntlive;
	int		csock;
	int		idclient;
	//int		rd;
	pthread_t	pth;
	U8		midcl;
	U8		rxbuf[_size_buf] //буфер приема;
	U8		txbuf[_size_buf] //буфер передачи;
	int		txsz 		= 0;
	U8		work;
	int		res;
	#if(_deb_con == 1)
		printf("ServConn client connected\n");
	#endif

	pthread_mutex_lock(&ServerMutex);

	countlive 	= cs->setcntlive;
	setcntlive	= cs->setcntlive;
	csock		= cs->csock;
	idclient	= cs->idclient;
	midcl		= cs->midcl[idclient];
	pth		= cs->pth[idclient];
	work		= cs->work;
	//
	pthread_mutex_unlock(&ServerMutex);
	//
	#if(_deb_con == 1)
		printf("ServConn client connected and starting...\n");
	#endif
        .......
        default: //нормально - данные приняты
                countlive = setcntlive;
                //обработка команд и данных сокета
                #if(_deb_con == 1)
                    printf("---starting mwork...\n");
                #endif
                pthread_mutex_lock(&MainMutex);
                txsz = mwork(&rxbuf[0], &txbuf[0]); //обработка нашего клиента
                pthread_mutex_unlock(&MainMutex);
                //if(txsz == 0)
                //    continue;
                break;

        .......

копирование данных по идентификатору в сервере (на примере 4-го процесса):

//вызываемая функция анализа и
//обработки запросов по сокетам
inline int    mwork(U8 * rbuf, U8 * sbuf)
{
    int     res     = 0;
    U8     stype    = (*(U8*)(rbuf + _type)); //тип (команда-чтение;запись;чтение и запись) то что желает клиент
    U8    scop    = (*(U8*)(rbuf + _cop)); //от клиента берём его идентификатор (он сам прислал)
    U16    ssize    = 0x02;
    
    //
    #if(_dbg > 0)
        printf("stype = %i  cop = %i\n", stype, scop);
    #endif
    //pthread_mutex_lock(&MainMutex);
    switch(stype)
    {        
         .......
         case _type_from_modbus4:
			#if(_dbg > 0)
				printf("mwork ServConn for mb4\n");
			#endif
			switch(scop)
			{
				case _cop_wr:	//запись данных в труктуру Modbus 4 - для сервера					//
					memcpy(&work.mb4s, rbuf + _daddr, sizeof(MODBUS4_SERVER));
					//
					(*(U16*)(sbuf + _tcp_szl))		= 0;
					res 					= 0;
					break;
				case _cop_rd:	//чтение данных из Modbus 4 - для клиента					(*(U8*)(sbuf + _type))			= stype;
					ssize++;
					(*(U8*)(sbuf + _cop))			= scop;
					ssize++;
					//
					memcpy(sbuf + _daddr, &work.mb4c, sizeof(MODBUS4_CLIENT));
					ssize += sizeof(MODBUS4_CLIENT);
					//
					(*(U16*)(sbuf + _tcp_szl))		= ssize;
					res 					= ssize;
					break;
				case _cop_rdwr:	//чтение и запись данных в Modbus 4
 					//
					memcpy(&work.mb4s, rbuf + _daddr, sizeof(MODBUS4_SERVER));
					//
					(*(U8*)(sbuf + _type))			= stype;
					ssize++;
					(*(U8*)(sbuf + _cop))			= scop;
					ssize++;
					//
					memcpy(sbuf + _daddr, &work.mb4c, sizeof(MODBUS4_CLIENT));
					ssize += sizeof(MODBUS4_CLIENT);
					//
					(*(U16*)(sbuf + _tcp_szl))		= ssize;
					res 					= ssize;
					break;
				default:
					(*(U16*)(sbuf + _tcp_szl))		= 0;
					res 					= 0;
					break;
			}
			break;

Хранит ли сервер связи какие-то данные или только передаёт их от отправителя к получателю?

 

Для прийма от каждого и для передачи каждому в отдельности

Link to comment

Извините меня за беспокойство!

Эта ошибка найдена!

А именно в сервере связи:

........

    }
            break;
        case _type_from_modbus3:
            #if(_dbg > 0)
                printf("mwork ServConn for mb3\n");
            #endif
            switch(scop)
            {
                case _cop_wr:    //запись данных в труктуру Modbus 3
                    //
                    memcpy(&work.mb3s, rbuf + _daddr, sizeof(MODBUS3_SERVER));
                    //
                    (*(U16*)(sbuf + _tcp_szl))        = 0;
                    res                     = 0;
                    break;
                case _cop_rd:    //передача данных в Modbus 3
                    (*(U8*)(sbuf + _type))            = stype;
                    ssize++;
                    (*(U8*)(sbuf + _cop))            = scop;
                    ssize++;
                    //
                    memcpy(sbuf + _daddr, &work.mb3c, sizeof(MODBUS3_CLIENT));
                    ssize += sizeof(MODBUS3_CLIENT);
                    //
                    (*(U16*)(sbuf + _tcp_szl))        = ssize;
                    res                     = ssize;
                    break;
                case _cop_rdwr:    //передача данных в Modbus 3
                    //
                    memcpy(&work.mb3s, rbuf + _daddr, sizeof(MODBUS3_SERVER));
                    //
                    (*(U8*)(sbuf + _type))            = stype;
                    ssize++;
                    (*(U8*)(sbuf + _cop))            = scop;
                    ssize++;
                    //
                    memcpy(sbuf + _daddr, &work.mb3c, sizeof(MODBUS3_CLIENT));
                    ssize += sizeof(MODBUS3_CLIENT);
                    //
                    (*(U16*)(sbuf + _tcp_szl))        = ssize;
                    res                     = ssize;
                    break;
                default:
                    (*(U16*)(sbuf + _tcp_szl))        = 0;
                    res                     = 0;
                    break;
            }

            // - А в этой строке дожен быть break;
        case _type_from_modbus4:
            #if(_dbg > 0)
                printf("mwork ServConn for mb4\n");
            #endif
            switch(scop)

....................

 

таким образом "разбор" данных завершался для процесса 3 и начинался "разбор" процесса 4

 

Ещё раз простите! Спасибо что откликнулись!

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...