jcxz 235 12 апреля, 2023 Опубликовано 12 апреля, 2023 · Жалоба 49 минут назад, MementoMori сказал: Казалось бы, около 10 кбайт в секунду. С чего бы такой странный вывод??? Начинайте уже наконец-то думать! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба Подумал, разобрался, оптимизировал прием, все хорошо. До 10 пакетов в 200 байт туда и обратно за одну секунду. Идем дальше, получаем проблемы с извлечением принятых данных. tINFO_VAR ANSWER_INFO_VAR; tINFO_VAR * pAnswerInfo; pAnswerInfo=&ANSWER_INFO_VAR; len_rx=0; while(len_rx<sizeof(ANSWER_INFO_VAR)) // гоняем цикл пока не прочитаем всю структуру { FData=Socket->ReceiveData(100); // получаем то, что есть в буфере на текухий момент. len_rx+=FData.Length;// увеличиваем счетчик прочитанных байт memcpy(pAnswerInfo,FData.data(),FData.Length); //копируем то, что есть, в ANSWER_INFO_WAR pAnswerInfo+=FData.Length; //смещаем указатель на число прочитанных байт } Указанный код запускается по таймеру раз в 50 мсек. При этом в начале кода таймер останавливается и вновь запускается в конце. То есть код запускается раз в 50 мсек, но выполняться может столько сколько нужно. Принцип работы не мной написанной библиотеки таков - нельзя узнать сколько в буфере приема байт, нельзя просто дождаться, пока 200 байт накапает. Нужно читать FData=Socket->ReceiveData(100). А когда данные прочел, содержимое буфера стирается. То есть, повторюсь, нельзя дождаться всей посылки и прочесть ее разом. Читаем кусками и склеиваем. Получается 9-10 кусков, в зависимости от того, в какой момент приема сработает таймер Так вот, первые 15-25 байт (видимо длина первой посылки) читаются нормально. В остальных нули. В процессе работы почти все эти байты заполняются верными данными. Но не все и не сразу. Где собака порылась? Добавлено спустя 10 минут: Собака порылась кажется здесь: pAnswerInfo+=FData.Length; Эта команда дает прирост адреса указателя на 4000. Хотя должна приращивать на 15-25 байт Вот строка для отладки Form1->Memo1->Lines->Add(IntToHex((__int32)pAnswerInfo)+" и "+IntToStr(FData.Length))+" байт"); Она выдает следующее Quote С0B73D6C и 20 байт С0B74D0C и 20 байт То есть "pAnswerInfo+20" это то же самое, что "адрес pAnswerInfo+4000" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 177 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба 1 час назад, MementoMori сказал: pAnswerInfo+=FData.Length; Эта команда дает прирост адреса указателя на 4000. Хотя должна приращивать на 15-25 байт Может, все-таки, открыть учебник по Си? А то так не продвинуться дальше двух строчек кода. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба 2 часа назад, MementoMori сказал: Хотя должна приращивать на 15-25 байт Не должна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба On 4/13/2023 at 5:17 PM, MementoMori said: Собака порылась кажется здесь: pAnswerInfo+=FData.Length; Эта команда дает прирост адреса указателя на 4000. Хотя должна приращивать на 15-25 байт Изучайте арифметические операции с указателями Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 42 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба 2 hours ago, MementoMori said: FData=Socket->ReceiveData(100); // получаем то, что есть в буфере на текухий момент. len_rx+=FData.Length;// увеличиваем счетчик прочитанных байт memcpy(pAnswerInfo,FData.data(),FData.Length); //копируем то, что есть, в ANSWER_INFO_WAR pAnswerInfo+=FData.Length; //смещаем указатель на число прочитанных байт Коллега! Так нельзя. Нет, ну если очень хочется мордой в кучу дерьма, то пожалуйста. ИМХО, использовать адресную арифметику со значениями, полученными через какую-то линию связи, категорически нельзя. Да ещё без единой проверки на то, что указатель ссылается на что-то осмысленное. Всё, что принято извне, содержит ошибки (пока неоднократно не доказано обратное), поэтому должно 100500 раз перепроверяться. Не согласны со мной и доверяете CSRC32? Вы обречены. Посмотри на Модбас. Максимальная длина кадра ограничена. Поле, указывающее размер кадра, не_может превысить размер кадра в силу своей разрядности (256 байт и 8 бит). В кадре указаны параметры, которое однозначно связаны с параметрами запроса, а в конце ещё и CRC16. Предлагаю продумать протокол на предмет перекрёстных проверок правильности принятых данных. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба 13 minutes ago, tonyk_av said: Коллега! Слишком лестно в мой адрес. Я любитель) В миру же я врач) А железки, байты, транзисторы - это моя вторая натура, ничего с этим не поделаешь) И ведь как тяжело в возрасте после 40-ка вникать в то, что пропустил по молодости. Всякому обучению свое время. Стряхнул пыль с учебников по С++. Блин, я наивно полагал, что если значение указателя это адрес, то и работать с ним можно как с адресом. А оказывается ptr++ увеличивает не на 1 байт, а на размер структуры, на которую ссылается указатель. Удивительное рядом. В итоге работающее решение такое: pAnswerInfo = (tINFO_VAR *)((char*)pAnswerInfo+FData.Length); Я правильно понял суть проблемы и ее решения? Или это случай, когда неверными расчетами случайно пришел к правильному ответу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба On 4/13/2023 at 8:16 PM, MementoMori said: Я правильно понял суть проблемы и ее решения? Или это случай, когда неверными расчетами случайно пришел к правильному ответу? Суть поняли правильно, но ваше решение какое-то не такое )) Лучше так tINFO_VAR ANSWER_INFO_VAR; uint8_t* pAnswerInfo; pAnswerInfo=(uint8_t*)&ANSWER_INFO_VAR; len_rx=0; while(len_rx<sizeof(ANSWER_INFO_VAR)) // гоняем цикл пока не прочитаем всю структуру { FData=Socket->ReceiveData(100); // получаем то, что есть в буфере на текухий момент. len_rx+=FData.Length;// увеличиваем счетчик прочитанных байт memcpy(pAnswerInfo,FData.data(),FData.Length); //копируем то, что есть, в ANSWER_INFO_WAR pAnswerInfo+=FData.Length; //смещаем указатель на число прочитанных байт } Ваш же код, но изменены вторая и третья строчки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба 4 hours ago, MementoMori said: len_rx+=FData.Length;// увеличиваем счетчик прочитанных байт А если при приёме склеится конец одного пакета и начало следующего? У вас излишек данных не переносится в следующий пакет, а просто затирает память за переменной ANSWER_INFO_VAR. Так что вы потеряете кусок следующего пакета, после чего ВСЕ пакеты поедут со сбитыми границами (если конечно ваша программа не навернётся раньше из за испорченной памяти после ANSWER_INFO_VAR) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 13 апреля, 2023 Опубликовано 13 апреля, 2023 · Жалоба 2 hours ago, xvr said: А если при приёме склеится конец одного пакета и начало следующего? А мое устройство молчаливо, говорит только тогда, когда его спрашивают, отвечает строго по уставу и затыкается, пока снова не спросят. Но за замечание спасибо - надо будет перед отправкой запроса предварительно очистить буфер приема. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 42 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба Пробежался по теме. Что мешает реализовать Модбас? Ведь ТС пытается повторить, только по-своему, то же самое. Зачем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 85 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба ...видимо, желание сделать собственный велосипэд 🙂 Ну чтож, это тоже похвально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба 2 hours ago, EdgeAligned said: сделать собственный велосипэд 🙂 Ну зачем ярлычки вешаете? Я тоже повешу свой ярлычок - MODBUS - это стрельба из пушки по воробью (коим является моя задача). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 42 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба 45 minutes ago, MementoMori said: MODBUS - это стрельба из пушки по воробью С чего бы это? В итоге всё равно получится что-то очень похожее на него. Для этой задачи достаточно реализовать команды записи-чтения регистров. Бонусом получится возможность протестировать написанное с помощью туевой хучи ОРС-серверов и утилит для тестов Модбаса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба 3 minutes ago, tonyk_av said: С чего бы это? В итоге всё равно получится что-то очень похожее на него. Для этой задачи достаточно реализовать команды записи-чтения регистров. Бонусом получится возможность протестировать написанное с помощью туевой хучи ОРС-серверов и утилит для тестов Модбаса Не хочу с вами спорить, но мне, с учетом моей задачи, с учетом того, что я все же любитель и некоторые вещи мне нужно, не поверите, осваивать с нуля, с учетом того, что к маю мне бы эту поделку хотелось бы уже эксплуатировать, мне проще сделать следующим образом - взять мой же старый, доказавший свою надежность, проект, в котором обмен осуществлялся текстовыми строками, переделать его с работы со строками на работу со структурами. Это уже получилось. Осталось проработать обработку ошибок и автоматическое восстановление после разрыва связи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться