Перейти к содержанию
    

IvanPletnev

Участник
  • Постов

    68
  • Зарегистрирован

  • Посещение

Весь контент IvanPletnev


  1. Точно! Вы правы! У меня включен аппаратный расчет контрольных сумм. Я просто закомментировал функцию расчета контрольной суммы iecho->chksum = inet_chksum(iecho, len); и всё заработало!!!! Спасибо огромное!.
  2. Так, кое-что заработало. Теперь у меня отправляется один 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. Похоже, я нашел причину. В отладчике 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. Ну так можно посчитать клиентов, и если их больше заданного количества принудительно разрывать соединение, не создавая задач.
  6. Попробовал сделать так, через создание новых задач, работает отлично! Если от клиента мы получаем запрос на закрытие соединения (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. На одном из форумов нашёл решение. После успешного 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. Добрый вечер всем! Протестировал схему, предложенную уважаемым TSerg, ниже представлю картинку. Вместо эмиттерного повторителя на транзисторе, включил LM358 по схеме повторителя. Т.е. отрицательный вход соединил с выходом. В итоге выходной сигнал режется на уровне 2В. На картинке 2 канал (голубой) - сигнал на входе ОУ, ограниченный по амплитуде напряжением питания, 1 канал (желтый) - сигнал на выходе ОУ. Что сделал не так? :)
  16. Это вряд ли получится, поскольку скорость АЦП в моём МК 1MSPS, а каналов 16. 60 с небольшим кГц максимум. Но тесты показывают, что даже на 44 кГц очень неплохо работает.
  17. Это как раз и нужно! Сейчас займусь, соберу на макетке, по результатам представлю отчет! Вот, только что осциллограмму записал. Но немного не в тех условиях, какие будут в барабанах. Это я просто по датчику ударил. Это обычные китайские пьезодатчики по 100 рублей за кучку. Но такие, как ни странно, стоят и в дорогих брендах тоже))
  18. Ух ты, круто! Обязательно попробую в ближайшее время! А обрезать отрицательную поуволну входного сигнала? Он же симметричен относительно ноля?
  19. Этот проект - электронные барабаны. USB MIDI модуль. на 16 каналов. В каждом триггере (пэде) (барабане) - пьезодатчик. Источнику звука (синтезатору, семплеру) передается MIDI сообщение, где среди прочего, есть сила удара по пэду. ЦОС нужна для того, чтобы в функции настройки пэда, можно было несколько раз ударить по нему с максимальной силой, чтобы авотматически откалибровать вход под текущий пэд или тарелку и т.п. и обеспечить максимальный динамический диапазон.
  20. На картинке - выход вышеприведенной схемы при напряжении питания 12V. Тест. Нужно оцифровывать 16 каналов с целью нахождения максимума сигнала. Эта задача уже решена. А цифровая регулировка по входу нужна для интерактивной настройки системы, дабы не допускать перегруза.
  21. Это пьезодатчик. Соответственно, сопротивление очень большое. Частота 1200 - 2000 Гц. На выходе этой схемы получается вот такая картинка, только это тест с большим, чем 5V напряжением питания Надежность в описанном Вами случае низкая, действительно.
  22. Вы имеете ввиду цифровой потенциометр после входного делителя на подстроечном резисторе? Операционник, как мне кажется, нужен по причине подключения этой схемы к АЦП. Во-первых, чтобы ограничить максимальную амплитуду на входе АЦП, а во-вторых, чтобы зарядка входного конденсатора АЦП происходила быстрее.
  23. Уважаемые гуру электроники, здравствуйте! Не пинайте сильно, к сожалению, в аналоговой электронике полный профан. Требуется приведение затухающего синусоидального сигнала максимальной амплитудой 80V, к положительному сигналу максимальной амплитудой 3,3V. Схема должна обладать высоким входным и низким выходным сопротивлением. И иметь возможность регулировки входной амплитуды с микроконтроллера. Поиск в интернете дал мне вот такую схему Я ее протестировал, она работает, правда, чтобы получить 3,3V max амплитуды, ее приходится питать от 5V, вероятно, из-за падения на диоде. В целом, она меня устраивает, но, может вы подскажете что-то дельное? И какое решение подскажете для регулировки уровня входного сигнала с микроконтроллера? SPI, I2C и т.п.
  24. Ребят, подскажите, как из PCB editor открыть для редактирования библиотеку текущего (выделенного) компонента. В Eagle просто - клик правой кнопкой на компоненте, затем Open Device. А в этой дорогущей программе как-то возможно сделать подобным образом?
×
×
  • Создать...