Jump to content

    

IvanPletnev

Участник
  • Content Count

    43
  • Joined

  • Last visited

Community Reputation

0 Обычный

About IvanPletnev

  • Rank
    Участник

Recent Profile Visitors

594 profile views
  1. LWIP Socket API SOCK_RAW Не создаётся сокет.

    Точно! Вы правы! У меня включен аппаратный расчет контрольных сумм. Я просто закомментировал функцию расчета контрольной суммы iecho->chksum = inet_chksum(iecho, len); и всё заработало!!!! Спасибо огромное!.
  2. LWIP Socket API SOCK_RAW Не создаётся сокет.

    Так, кое-что заработало. Теперь у меня отправляется один ICMP пакет тык. Но вылезла очередная проблема. Вот моя функция подготовки пакета: static void ping_prepare_echo(struct icmp_echo_hdr *iecho, u16_t len) { size_t i; size_t data_len = len - sizeof(struct icmp_echo_hdr); ICMPH_TYPE_SET(iecho, ICMP_ECHO); ICMPH_CODE_SET(iecho, 0); iecho->chksum = 0; iecho->id = PING_ID; iecho->seqno = htons(++ping_seq_num); /* fill the additional data buffer with some data */ for (i = 0; i < data_len; i++) { ((char*) iecho)[sizeof(struct icmp_echo_hdr) + i] = (char) i; } iecho->chksum = inet_chksum(iecho, len); } Wireshark говорит мне, что некорректная контрольная сумма. 0x0000 вместо 0x574e тык. Хотя контрольная сумма считается правильно и заносится в заголовок ICMP пакета тык. Все остальные поля структуры передаются правильно, а контрольная сумма при передаче куда-то исчезает. Видимо поэтому, когда я пытаюсь пинговать windows компьютер, он на этот пакет ничего не отвечает.
  3. LWIP Socket API SOCK_RAW Не создаётся сокет.

    Похоже, я нашел причину. В отладчике Atollic TrueStudio я обратил внимание на то, что задача виснет, когда в стеке находятся функции, отправляющие сообщения в очередь. Начал копать LWIP и обнаружил, что DEFAULT_RAW_RECVMBOX_SIZE в файле opt.h равен 0. Поэтому, наверное, задача и виснет. Пока не пробовал, но должно помочь.
  4. Уважаемые коллеги, здравствуйте! Столкнулся с такой проблемой. STM32F429, стек LWIP v.2.0.3, FreeRTOS. Пытаюсь создать сокет SOCK_RAW для периодического пинга подключенного клиента, он не создаётся. Причем, похоже, задача виснет, потому что диагностические сообщение не выводятся. При этом сокеты SOCK_STREAM и SOCK_DGRAM создаются без проблем. Кто-нибудь подскажет, куда копнуть? if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { puts("PING socket error"); return; } printf("Socket No %u created\r\n", s);
  5. LWIP Socket API блокировка задачи

    Ну так можно посчитать клиентов, и если их больше заданного количества принудительно разрывать соединение, не создавая задач.
  6. LWIP Socket API блокировка задачи

    Попробовал сделать так, через создание новых задач, работает отлично! Если от клиента мы получаем запрос на закрытие соединения (FIN), в задаче, в которой крутится функция recv, корректно закрываем сокет, удаляем созданные задачи. newconn = accept(sock, (struct sockaddr *)&remotehost, (socklen_t *)&size);//принимаем входящее подключение if ((newconn>1)||(newconn<1)){ close(newconn); } else if (newconn==1){ HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin, GPIO_PIN_SET); socketReceiveTaskHandle=sys_thread_new("sockRecvTask",socketReceiveTask,(void*)newconn,256,osPriorityNormal); socketSendTaskHandle=sys_thread_new("sockSendTask",socketSendTask,(void*)newconn,256,osPriorityNormal); } Еще нужно сделать, чтобы по прерыванию от PHY, сигнализирующему о какой-либо ошибке соединения, делалось тоже самое. Надо тестировать, конечно. Нет, в моём случае количество соединений ограничено, мне не нужно создавать много.
  7. LWIP Socket API блокировка задачи

    На одном из форумов нашёл решение. После успешного accept создаётся задача, которой в качестве аргумента передаётся идентификатор сокета. И уже в этой задаче обрабатывается функция recv. Еще не пробовал, но, думаю, должно получиться.
  8. Доброго времени суток, уважаемые коллеги! Встала задача принимать пакеты из UART и передавать их в сеть. Запустил задачу-сервер на Socket API из примера ST, проверил, send - receive работает. Но когда дело дошло до реальной реализации, выяснилось, что функции accept и receive намертво блокируют задачу. Блокировку функцией accept решил вот такой нехитрой конструкцией: if (accept_state==0){ newconn = accept(sock, (struct sockaddr *)&remotehost, (socklen_t *)&size);//принимаем входящее подключение accept_state=1; } То есть, сервер принимает только одно входящее подключение. Общий вид главного цикла задачи-сервера: while (1) { if (accept_state==0){ newconn = accept(sock, (struct sockaddr *)&remotehost, (socklen_t *)&size);//принимаем входящее подключение accept_state=1; } event=osMessageGet(UART_RX_QHandle,10);//получаем указатель на структуру, которую нужно передать в сокет if (event.status==osEventMessage){ printf ("Queue received at %lu\r\n", osKernelSysTick()); pDataToSend=(UART_RX_Data*)event.value.v; HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin); send(newconn, pDataToSend->payload, pDataToSend->size, 0);//отправляем данные в сокет HAL_UART_Receive_IT(&huart3,uartRXBuffer,UART3RX_BUF_SIZE);//включаем приём в UART printf ("Switch context at %lu\r\n", osKernelSysTick()); osThreadYield(); } } в общем, циклично, по приходу пакета в UART, в задачу-сервер через очередь передается указатель на данные, которые нужно отправить в сокет. Вот теперь возникли два вопроса. Первый - как корректно завершить соединение по запросу от клиента? Попробовал сделать так: nbytes=recv(newconn, rxBuf, BUFLEN, MSG_PEEK); if (nbytes<=0){ close(newconn); } Сразу перестала работать очередь, потому что функция recv наглухо блокирует задачу. Что подскажете? И второй вопрос. Как отслеживать физический дисконнект? Может, кто уже решал эту задачу?
  9. Коллеги, вопрос закрыт. Оказывается, в сети 220В ноль был смещен относительно земли. Причем он двигался от 3 до 85 В RMS. Поэтому такая свистопляска и была. Запитали от нормального ввода и проблема решилась Всем спасибо за участие
  10. Посмотрел осциллографом сеть, синусоида ломаная вся, куча гармоник, из-за этого, наверное, это и происходит. Смещается минус питания. С заземленным минусом работает идеально. Я таких хороших показателей по шуму никогда не видел на этом аналого-цифровом устройстве.
  11. Нет, на устройстве 23,8В. Потребление очень маленькое, меньше 100mA. На устройстве хороший DC-DC преобразователь Aimtec AM-3T.
  12. Да, я не сказал, на аналого-цифровом устройстве используется ADM2587, изолированный интерфейс. А на другой стороне нет.
  13. Уважаемые коллеги, здравствуйте. Прошу помощи вот в каком вопросе. Есть аналого-цифровой прибор, работающий "в поле", от которого идут две пары проводов. +24В, 0В, Data+(RS485), Data-(RS485). На другой стороне имеется блок коммутации и питания, с цепями защиты интерфейса (газовые разрядники и Tvs-диоды) В цепях защиты, естественно, используется заземление. Заземление выполнено по всем правилам. В качестве источника питания 24В используется БП MEAN WELL IRM15-24.Таких устройств эксплуатируется уже довольно много без особых проблем. Но сейчас столкнулся с тем, что разность потенциалов между землёй и минусом питания составляет порядка 7,5В, (мерял в режиме переменного напряжения) открываются защитные диоды, связь теряется. Причём, аналого-цифровое устройство при этом ощутимо шумит. И естественно, пропадают пакеты по RS485. Проблема решилась соединением минуса питания с землёй. При этом всё работает просто идеально. Что думаете по этому поводу? Так ведь, по идее, нельзя делать? С чем это может быть связано?
  14. Уважаемые коллеги, доброго времени суток! Правильно ли я понимаю, что в этой конструкции while (netconn_recv(newconn, &buf) == ERR_OK) { do { netbuf_data(buf, &data, &len); printf ("%u Bytes received, netbuf_next() = %d\r\n", len, netbuf_next(buf)); } while (netbuf_next(buf) >= 0); printf ("netbuf_next() = %d\r\n", netbuf_next(buf)); copiedBytes=netbuf_copy(buf, (uint8_t*)&train,sizeof(train)); printf("%u bytes are copied to structure\r\n", copiedBytes); netbuf_delete(buf); } В случае, если размер входящих данных будет больше, чем TCP_MSS (Maximum segment size), который в данном случае 536 байт, то каждый последующий сегмент данных будет перезаписывать предыдущий в в буфере buf? То есть, функция netbuf_next() всегда будет возвращать -1? На практике у меня так и происходит. Вот результат выполнения этого кода при отправке 1024 байт. 536 Bytes received, netbuf_next() = -1 netbuf_next() = -1 536 bytes are copied to structure 488 Bytes received, netbuf_next() = -1 netbuf_next() = -1 488 bytes are copied to structure Тогда непонятно, зачем организован этот цикл, если условие while никогда не наступит? А чтобы полностью скопировать пришедшие данные, мне по приёму каждого сегмента нужно двигать смещение относительно начала моей структуры, или я в чем-то не прав? Заранее благодарю за ответы.
  15. Цитата(Alexashka @ Jan 24 2017, 14:16) ОУ не тот. Возьмите rail-to-rail ОУ (LM358 отнимает примерно 1.5в от верхнего питания) Хорошо, попробую rail-to-rail, спасибо!