Алексей ВМ 0 24 апреля, 2020 Опубликовано 24 апреля, 2020 (изменено) · Жалоба Добрый день! Есть задача передать на сервер данные. Используется STM32F4 с FreeRTOS и lwIP. К STM посредством USB подключен модем. В lwIP включена поддержка PPPoS для работы с модемом. Запись данных и ожидание результата производится в отдельной задаче. Данные передаются, но подтверждение от сервера часто (в 90% случаев) приходит в течении нескольких секунд (2-8), а иногда вообще данные до сервера не доходят. При использовании Ethernet таких проблем на данной плате с данным сервером нет. Может, кто сталкивался с подобной проблемой, в какую сторону копать? Изменено 24 апреля, 2020 пользователем Алексей ВМ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 117 24 апреля, 2020 Опубликовано 24 апреля, 2020 · Жалоба 25 минут назад, Алексей ВМ сказал: Может, кто сталкивался с подобной проблемой, в какую сторону копать? Часто такое происходит при ошибках в функциях ввода-вывода в модем. Включать в lwip отладочный вывод с подробной распечаткой содержимого пакетов и искать в этих распечатках какие-то корреляции с проблемами. Отвлечение: По USB модем к lwip не подключал, только через УСАПП. Можно кратенько (или подробнее) о вашем решении: какой модем, как программно организовано это подключение? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Алексей ВМ 0 24 апреля, 2020 Опубликовано 24 апреля, 2020 (изменено) · Жалоба 21 minutes ago, Сергей Борщ said: Отвлечение: По USB модем к lwip не подключал, только через УСАПП. Можно кратенько (или подробнее) о вашем решении: какой модем, как программно организовано это подключение? Если кратко, то Модем - HUAWEI E3372h, АТ команды - с использованием CDC поверх USB. PPP_Conn = pppos_create(&ppp_netif, PPPoutputCB, PPPlinkStatusCB, &GLOB_PPP_ConnStatus); static u32_t PPPoutputCB(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) { return USBH_CDC_SendData(data, len); } Прием USBH_BulkReceiveData(&USB_OTG_Core,&bDatIN[datPtr],64,MSC_Machine.hc_num_in); xTaskCreate(vUSBH, "vtUSBH", configMINIMAL_STACK_SIZE, NULL, 0, NULL); xTaskCreate(vUSBHrx, "vtUSBHrx", configMINIMAL_STACK_SIZE, NULL, 3, NULL); xTaskCreate(vlwIP_PPPinit, "vtlwIP_PPPinit", configMINIMAL_STACK_SIZE, NULL, 0, NULL); void vUSBH(void *pvParameters) { USBH_Init(&USB_OTG_Core,USB_OTG_HS_CORE_ID,&USB_Host,&USBH_MSC_cb,&USR_Callbacks); while (1) { USBH_Process(&USB_OTG_Core, &USB_Host); } } void vUSBHrx(void *pvParameters) { uint32_t datPtr=0; while (1) { if (usbUP == 1) { taskENTER_CRITICAL(); USBH_BulkReceiveData(&USB_OTG_Core,&bDatIN[datPtr],64,MSC_Machine.hc_num_in); taskEXIT_CRITICAL(); if (xSemaphoreTake(SemRxURB_DONE,(200/portTICK_RATE_MS))==pdPASS) { //If URB status is set to URB_DONE in interrupt service routine DatIN=HCD_GetXferCnt(&USB_OTG_Core,MSC_Machine.hc_num_in); if (GLOB_PPP_ConnStatus>=20) { //if already in PPP mode if ((DatIN>=64)&&(datPtr<(64*3))) { datPtr+=DatIN; DatIN=0; } else if ((DatIN+datPtr)>0) { pppos_input_tcpip(PPP_Conn,bDatIN,(DatIN+datPtr)); DatIN=0; datPtr=0; } } else { //if not in PPP mode yet if ((DatIN>=64)&&(datPtr<(64*3))) { datPtr+=DatIN; DatIN=0; } else if ((DatIN+datPtr)>0) { DatIN=DatIN+datPtr; datPtr=0; } } } } else { vTaskDelay(100/portTICK_RATE_MS); } } } void OTG_HS_IRQHandler(void) { static signed portBASE_TYPE xHPTW; //GSH addon USBH_OTG_ISR_Handler(&USB_OTG_Core); if (usbUP != 0) { if (HCD_GetURB_State(&USB_OTG_Core, MSC_Machine.hc_num_in) == URB_DONE) { USB_OTG_Core.host.URB_State[MSC_Machine.hc_num_in] = URB_IDLE; xSemaphoreGiveFromISR(SemRxURB_DONE,&xHPTW); portYIELD_FROM_ISR(xHPTW); } } } При включении LWIP_STATS появляются ошибки tcp drop и proterr. А вот куда дальше копать - пока в затруднении Изменено 24 апреля, 2020 пользователем Алексей ВМ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 117 24 апреля, 2020 Опубликовано 24 апреля, 2020 · Жалоба 18 минут назад, Алексей ВМ сказал: АТ команды - с использованием CDC поверх USB. cmux не поднимали? Или модем определяется как несколько CDC? 20 минут назад, Алексей ВМ сказал: При включении LWIP_STATS Я имел ввиду PPP_DEBUG и PRINTPKT_SUPPORT. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Алексей ВМ 0 24 апреля, 2020 Опубликовано 24 апреля, 2020 · Жалоба 2 minutes ago, Сергей Борщ said: cmux не поднимали? Или модем определяется как несколько CDC? cmux не задействован. CDC скорей всего один. Код обмена с модемом писал не я, могу ошибаться. CDC используется для AT команд управления, а данные читаются/пишутся c помощью MSC. Инициализация USB хоста USBH_Init(&USB_OTG_Core,USB_OTG_HS_CORE_ID,&USB_Host,&USBH_MSC_cb,&USR_Callbacks); USBH_Class_cb_TypeDef USBH_MSC_cb = { USBH_MSC_InterfaceInit, USBH_MSC_InterfaceDeInit, USBH_MSC_ClassRequest, USBH_MSC_Handle, }; хм, инициализируется только MSC. Мне кажется, CDC тут фиктивный(?). Вот код передачи по CDC. Видно, что используется MSС. uint32_t USBH_CDC_SendData(uint8_t *data, uint32_t len) { URB_STATE urb_tx = URB_IDLE; uint32_t i = 0; uint32_t size = 0; uint8_t txState = 0; uint8_t j; while (i < len) { urb_tx = HCD_GetURB_State(&USB_OTG_Core, MSC_Machine.hc_num_out); switch (txState) { case 0: //Prepare and send data switch (urb_tx) { case URB_DONE: case URB_IDLE: case URB_NOTREADY: if ((len - i) > MSC_Machine.MSBulkOutEpSize) { size = MSC_Machine.MSBulkOutEpSize; } else { size = (len - i); } taskENTER_CRITICAL(); USBH_BulkSendData(&USB_OTG_Core, (data + i), size, MSC_Machine.hc_num_out); taskEXIT_CRITICAL(); txState = 1; j = 0; break; } break; case 1: switch (urb_tx) { case URB_DONE: i += size; txState = 0; break; case URB_NOTREADY: txState = 0; //printf("\nUSB_TX_NOTREADY"); vTaskDelay(1/portTICK_RATE_MS); //def 5 break; case URB_IDLE: txState = 0; // AlexM 181118 break; case URB_ERROR: vTaskDelay(1/portTICK_RATE_MS); printf("\nUSB_TX_ERR_TOUT"); j++; if (j >= 5) { i += size; txState = 0; printf("\nUSB_TX_ERR"); } break; } break; } } //printf("\nlen=%u, sent=%u",len,i); return i; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Алексей ВМ 0 24 апреля, 2020 Опубликовано 24 апреля, 2020 (изменено) · Жалоба Воткнул модем в ноут - COM портов нет. Думаю, модем каким-то хитрым образом сконфигурирован. Дров не было. Установил - появился СОМ порт. Изменено 24 апреля, 2020 пользователем Алексей ВМ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 32 24 апреля, 2020 Опубликовано 24 апреля, 2020 · Жалоба 1 час назад, Алексей ВМ сказал: Воткнул модем в ноут - COM портов нет. Думаю, модем каким-то хитрым образом сконфигурирован. Эти модемы насколь помню, типа "HiLink-модем" задействуют особый режим наподобии RNDIS только как хост, а не устройство, особо не вникал, но это несколько иной режим, чем старые 3Г-шки с вирт. ком портами... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Алексей ВМ 0 25 апреля, 2020 Опубликовано 25 апреля, 2020 · Жалоба Может кто-нибудь прокомментировать, что происходит: Посылаем данные TCP CONNECTED tcp_write(pcb=2000db28, data=20001492, len=178, apiflags=1) tcp_write: queuelen: 0 tcp_write: queueing 6516:6694 tcp_write: 1 (after enqueued) tcp_output: snd_wnd 14600, cwnd 4380, wnd 4380, effwnd 178, seq 6516, ack 6516 tcp_output: snd_wnd 14600, cwnd 4380, wnd 4380, effwnd 178, seq 6516, ack 6516, i 0 tcp_output_segment: 6516:6694 pppos_netif_output[0]: proto=0x21, len = 218 И после этого начинается TCP SEND OK!!! tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 4380, wnd 4380, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 4380, wnd 4380, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 4380, wnd 4380, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: rtime 6 pcb->rto 6 tcp_slowtmr: cwnd 1360 ssthresh 2720 tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, effwnd 178, seq 6516, ack 6516 tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, effwnd 178, seq 6516, ack 6516, i 0 tcp_output_segment: rtseq 6516 tcp_output_segment: 6516:6694 pppos_netif_output[0]: proto=0x21, len = 218 tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: rtime 12 pcb->rto 12 tcp_slowtmr: cwnd 1360 ssthresh 2720 tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, effwnd 178, seq 6516, ack 6516 tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, effwnd 178, seq 6516, ack 6516, i 0 tcp_output_segment: rtseq 6516 tcp_output_segment: 6516:6694 pppos_netif_output[0]: proto=0x21, len = 218 tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb tcp_slowtmr: processing active pcb tcp_slowtmr: polling application tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 tcp_slowtmr: processing active pcb NO DATA TO RECEIVE tcp_close: closing in State: ESTABLISHED tcp_enqueue_flags: queuelen: 1 tcp_enqueue_flags: queueing 6694:6695 (0x1) tcp_enqueue_flags: 2 (after enqueued) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, effwnd 178, seq 6694, ack 6516 tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, effwnd 178, seq 6694, ack 6516, i 0 tcp_output_segment: 6694:6694 pppos_netif_output[0]: proto=0x21, len = 40 Отладка не получила АСК от сервера и пытается периодически что-то на сервер отправить? tcp_output: nothing to send (00000000) tcp_output: snd_wnd 14600, cwnd 1360, wnd 1360, seg == NULL, ack 6516 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 117 25 апреля, 2020 Опубликовано 25 апреля, 2020 · Жалоба Проверьте, не отключено ли у вас программное вычисление CRC (CHECKSUM_GEN_xxx, CHECKSUM_CHECK_xxx). В проектах на STM32 его выключают чтобы использовать аппаратное вычисление в MAC, но при работе с модемом данные через MAC не проходят и CRC остается нерасчитанным. А если вы захотите использовать аппаратный расчет для проводного соединения и программный для модема в одной системе - надо использовать LWIP_CHECKSUM_CTRL_PER_NETIF. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Алексей ВМ 0 25 апреля, 2020 Опубликовано 25 апреля, 2020 · Жалоба Спасибо! Программное вычисление CRC включено, в противном случае до сервера вообще бы ничего не доходило, в моем случае доходит 90% посылок, из них 50% с большой задержкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться