jenya7 0 16 июня, 2021 Опубликовано 16 июня, 2021 (изменено) · Жалоба Чип STM32L475VC + ISM43362 WIFI Module. Настраиваю модуль, подключаюсь к AP, запускаю сервер. Spoiler if(ISM43362_Init() == WIFI_STATUS_OK) { USART_SendString(SYS_USART, "WIFI INIT OK\r"); if(WIFI_GetMAC_Address(mac_addr) == WIFI_STATUS_OK) { USART_SendString(SYS_USART, "MAC ADDRESS "); USART_SendHex(SYS_USART, mac_addr[0],0); USART_SendString(SYS_USART, ":"); USART_SendHex(SYS_USART, mac_addr[1],0); USART_SendString(SYS_USART, ":"); USART_SendHex(SYS_USART, mac_addr[2],0); USART_SendString(SYS_USART, ":"); USART_SendHex(SYS_USART, mac_addr[3],0); USART_SendString(SYS_USART, ":"); USART_SendHex(SYS_USART, mac_addr[4],0); USART_SendString(SYS_USART, ":"); USART_SendHex(SYS_USART, mac_addr[5],1); } } else USART_SendString(SYS_USART, "WIFI INIT ERROR\r"); if( WIFI_Connect(SSID, PASSWORD, WIFI_ECN_WPA2_PSK) == WIFI_STATUS_OK) { if(WIFI_GetIP_Address(ip_addr) == WIFI_STATUS_OK) { USART_SendString(SYS_USART, "Connected: got IP Address "); USART_SendInt(SYS_USART, ip_addr[0], 0); USART_SendString(SYS_USART, "."); USART_SendInt(SYS_USART, ip_addr[1], 0); USART_SendString(SYS_USART, "."); USART_SendInt(SYS_USART, ip_addr[2], 0); USART_SendString(SYS_USART, "."); USART_SendInt(SYS_USART, ip_addr[3], 1); } else { USART_SendString(SYS_USART , "ERROR: CANNOT get IP address\r"); } } if (WIFI_StartServer(SOCKET, WIFI_TCP_PROTOCOL, 1, "", PORT) == WIFI_STATUS_OK) USART_SendString(SYS_USART, "Start server - SUCCESS\r"); else USART_SendString(SYS_USART, "Start server - ERROR\r"); все проходит на ура Quote WIFI INIT OK MAC ADDRESS C4:7F:51:7:B5:A5 Connected: got IP Address 172.16.1.120 Start server - SUCCESS в мэйн запускаю обработку комманды пользователя с терминала while (1) { if (uart4_rx_ready) { uart4_rx_ready = 0; PARSER_ParseCommand(uart4_rx_buf); } } все отлично. команды принимаются. добавляю получение данных с модуля while (1) { if (uart4_rx_ready) { uart4_rx_ready = 0; PARSER_ParseCommand(uart4_rx_buf); } if (WIFI_STATUS_OK == WIFI_ReceiveData(SOCKET, udp_rx_buf, 1000, &udp_rx_len, 0 )) { if (udp_rx_len > 0) USART_SendInt(SYS_USART, udp_rx_len, 1); } } и тут прием с UART ломается. по чару принимает, но если послать весь стринг то принимает первый чар и подымается флаг ORE: Overrun error. я думал WIFI_ReceiveData блокирующий, но если ставлю точку останова в любой строке кода все бежит без задержек. в чем может быть проблема? Изменено 16 июня, 2021 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 16 июня, 2021 Опубликовано 16 июня, 2021 · Жалоба Ну раз правда не блокирующий, то Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 34 16 июня, 2021 Опубликовано 16 июня, 2021 · Жалоба 1 час назад, jenya7 сказал: я думал WIFI_ReceiveData блокирующий, но если ставлю точку останова в любой строке кода все бежит без задержек. Ничего не понятно, но очень интересно, продолжайте... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 16 июня, 2021 Опубликовано 16 июня, 2021 (изменено) · Жалоба ну скажем так, нечего блокировать. никаких данных не приходит он сразу выходит с DEBUG("setting socket for read failed\n"); есть проекты с более массивным чтением где я в цикле вычитываю массивы данных и ничего прием по UART работает чётко. обращение к модулю по SPI. чары с UART я собираю в массив по прерыванию. ну пусть он вычитывает по SPI буфер, я приму свою команду и подниму флаг. ORE: Overrun error - это пришёл новый чар а я не успел считать старый? как такое может быть, я в прерывании сразу его считываю. что может блокировать прерывание? Изменено 16 июня, 2021 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 34 16 июня, 2021 Опубликовано 16 июня, 2021 · Жалоба 3 часа назад, jenya7 сказал: Overrun error - это пришёл новый чар а я не успел считать старый? Да. 3 часа назад, jenya7 сказал: что может блокировать прерывание? Очевидно что-то в вашей программе, которую никто, кроме вас не видит.. 3 часа назад, jenya7 сказал: обращение к модулю по SPI. чары с UART я собираю в массив по прерыванию. ну пусть он вычитывает по SPI буфер, я приму свою команду и подниму флаг. Причем тут уарт и спи? СПИ тоже по прерываниям работает? Тогда может там и "давит"... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 28 июня, 2021 Опубликовано 28 июня, 2021 · Жалоба On 6/16/2021 at 5:18 PM, jenya7 said: ORE: Overrun error - это пришёл новый чар а я не успел считать старый? как такое может быть, я в прерывании сразу его считываю. что может блокировать прерывание? Как я понял, есть два источника данных. Оба работают по прерыванию. Один из источников переполняет буфер приема. Может с приоритетами прерываний поиграть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 июня, 2021 Опубликовано 28 июня, 2021 (изменено) · Жалоба 1 hour ago, KnightIgor said: Как я понял, есть два источника данных. Оба работают по прерыванию. Один из источников переполняет буфер приема. Может с приоритетами прерываний поиграть? если убрать if (WIFI_STATUS_OK == WIFI_ReceiveData(SOCKET, udp_rx_buf, 1000, &udp_rx_len, 0 )) { if (udp_rx_len > 0) USART_SendInt(SYS_USART, udp_rx_len, 1); } то все нормально. наверное обращение к неоткрытому сокету делает проблему. правда как это связано с UART я так и не понял. Изменено 28 июня, 2021 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 28 июня, 2021 Опубликовано 28 июня, 2021 · Жалоба 20 minutes ago, jenya7 said: если убрать if (WIFI_STATUS_OK == WIFI_ReceiveData(SOCKET, udp_rx_buf, 1000, &udp_rx_len, 0 )) { if (udp_rx_len > 0) USART_SendInt(SYS_USART, udp_rx_len, 1); } то все нормально. наверное обращение к неоткрытому сокету делает проблему. правда как это связано с UART я так и не понял. 1. Кто писал _ReceiveData? Может там есть код, который запрещает прерывания на время? 2. _SendInt посылает через прерывания? Если да, то может приоритет этого прерывания выше приема UART, да еще в прерывании достаточно длительная предобработка ведется? Попробуйте закомментировать именно _SendInt, а если есть полный контроль над этой функцией, попробовать передавать с помощью DMA. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 июня, 2021 Опубликовано 28 июня, 2021 · Жалоба 1 hour ago, KnightIgor said: 1. Кто писал _ReceiveData? Может там есть код, который запрещает прерывания на время? 2. _SendInt посылает через прерывания? Если да, то может приоритет этого прерывания выше приема UART, да еще в прерывании достаточно длительная предобработка ведется? Попробуйте закомментировать именно _SendInt, а если есть полный контроль над этой функцией, попробовать передавать с помощью DMA. ReceiveData не трогает прерывания Spoiler WIFI_Status_t WIFI_ReceiveData(uint8_t socket, uint8_t *pdata, uint16_t Reqlen, uint16_t *RcvDatalen, uint32_t Timeout) { WIFI_Status_t ret = WIFI_STATUS_ERROR; EsWifiObj.Timeout = Timeout; //1000 if(ES_WIFI_ReceiveData(&EsWifiObj, socket, pdata, Reqlen, RcvDatalen, Timeout) == ES_WIFI_STATUS_OK) //if(ES_WIFI_AltReceiveData(&EsWifiObj, socket, pdata, Reqlen, RcvDatalen, Timeout) == ES_WIFI_STATUS_OK) { ret = WIFI_STATUS_OK; } return ret; } ES_WIFI_Status_t ES_WIFI_ReceiveData(ES_WIFIObject_t *Obj, uint8_t Socket, uint8_t *pdata, uint16_t Reqlen, uint16_t *Receivedlen, uint32_t Timeout) { uint32_t wkgTimeOut; ES_WIFI_Status_t ret = ES_WIFI_STATUS_ERROR; if (Timeout == 0) { wkgTimeOut = NET_DEFAULT_NOBLOCKING_READ_TIMEOUT; } else { wkgTimeOut = Timeout; } LOCK_WIFI(); if(Reqlen <= ES_WIFI_PAYLOAD_SIZE ) { sprintf((char*)Obj->CmdData,"P0=%d\r", Socket); ret = AT_ExecuteCommand(Obj, Obj->CmdData, Obj->CmdData); if(ret == ES_WIFI_STATUS_OK) { sprintf((char*)Obj->CmdData,"R1=%d\r", Reqlen); ret = AT_ExecuteCommand(Obj, Obj->CmdData, Obj->CmdData); if(ret == ES_WIFI_STATUS_OK) { sprintf((char*)Obj->CmdData,"R2=%lu\r", wkgTimeOut); ret = AT_ExecuteCommand(Obj, Obj->CmdData, Obj->CmdData); if(ret == ES_WIFI_STATUS_OK) { sprintf((char*)Obj->CmdData,"R0\r"); ret = AT_RequestReceiveData(Obj, Obj->CmdData, (char *)pdata, Reqlen, Receivedlen); if (ret != ES_WIFI_STATUS_OK) { DEBUG("AT_RequestReceiveData failed\n"); } } else { DEBUG("setting timeout failed\n"); } } else { DEBUG("setting requested len failed\n"); *Receivedlen = 0; } } else { DEBUG("setting socket for read failed\n"); issue15++; } } UNLOCK_WIFI(); return ret; } LOCK_WIFI() пустышка. до USART_SendInt я не дохожу так как условие if (WIFI_STATUS_OK == WIFI_ReceiveData(SOCKET, udp_rx_buf, 1000, &udp_rx_len, 1000 )) не выполняется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 28 июня, 2021 Опубликовано 28 июня, 2021 (изменено) · Жалоба 22 minutes ago, jenya7 said: ReceiveData не трогает прерывания Reveal hidden contents WIFI_Status_t WIFI_ReceiveData(uint8_t socket, uint8_t *pdata, uint16_t Reqlen, uint16_t *RcvDatalen, uint32_t Timeout) { WIFI_Status_t ret = WIFI_STATUS_ERROR; EsWifiObj.Timeout = Timeout; //1000 if(ES_WIFI_ReceiveData(&EsWifiObj, socket, pdata, Reqlen, RcvDatalen, Timeout) == ES_WIFI_STATUS_OK) //if(ES_WIFI_AltReceiveData(&EsWifiObj, socket, pdata, Reqlen, RcvDatalen, Timeout) == ES_WIFI_STATUS_OK) { ret = WIFI_STATUS_OK; } return ret; } ES_WIFI_Status_t ES_WIFI_ReceiveData(ES_WIFIObject_t *Obj, uint8_t Socket, uint8_t *pdata, uint16_t Reqlen, uint16_t *Receivedlen, uint32_t Timeout) { uint32_t wkgTimeOut; ES_WIFI_Status_t ret = ES_WIFI_STATUS_ERROR; if (Timeout == 0) { wkgTimeOut = NET_DEFAULT_NOBLOCKING_READ_TIMEOUT; } else { wkgTimeOut = Timeout; } LOCK_WIFI(); if(Reqlen <= ES_WIFI_PAYLOAD_SIZE ) { sprintf((char*)Obj->CmdData,"P0=%d\r", Socket); ret = AT_ExecuteCommand(Obj, Obj->CmdData, Obj->CmdData); if(ret == ES_WIFI_STATUS_OK) { sprintf((char*)Obj->CmdData,"R1=%d\r", Reqlen); ret = AT_ExecuteCommand(Obj, Obj->CmdData, Obj->CmdData); if(ret == ES_WIFI_STATUS_OK) { sprintf((char*)Obj->CmdData,"R2=%lu\r", wkgTimeOut); ret = AT_ExecuteCommand(Obj, Obj->CmdData, Obj->CmdData); if(ret == ES_WIFI_STATUS_OK) { sprintf((char*)Obj->CmdData,"R0\r"); ret = AT_RequestReceiveData(Obj, Obj->CmdData, (char *)pdata, Reqlen, Receivedlen); if (ret != ES_WIFI_STATUS_OK) { DEBUG("AT_RequestReceiveData failed\n"); } } else { DEBUG("setting timeout failed\n"); } } else { DEBUG("setting requested len failed\n"); *Receivedlen = 0; } } else { DEBUG("setting socket for read failed\n"); issue15++; } } UNLOCK_WIFI(); return ret; } LOCK_WIFI() пустышка. до USART_SendInt я не дохожу так как условие if (WIFI_STATUS_OK == WIFI_ReceiveData(SOCKET, udp_rx_buf, 1000, &udp_rx_len, 1000 )) не выполняется. Тогда я лично в потемках. Явно кто-то грузит процессор так, что прерывание не успевает выбрать регистр данных, и возникает переполнение. Это может быть связано с длинной пост-обработкой принятого прерыдущего байта в самом прерывании. Попробуйте "зациклиться" в прерывании по приему, пока не упадет флаr RXNE: то есть, не "сработало прерывание по RXNE - байт выбран, обработали, вышли", а "сработало прерывание по RXNE - выбираем байты в цикле с проверкой RXNE, пока он не упадет, потом вышли". Еще идеи: 1. Наверное AT_ExecuteCommand() посылает что-то через UART/SPI? Это то, о чем я говорил в части интенсивной передачи и DMA. 2. Может ваш приемный буфер, куда складываются принятые байты, по глубине равен 1? Типа недоглядели какой #define... Изменено 28 июня, 2021 пользователем KnightIgor Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться