BorisBritwa 0 Posted November 7, 2020 (edited) · Report post Плата NUCLEO stm32f767ZI . Задача передать поток с камеры ov2640 2-10Мегабит. Делал такое уже на w5500 и stm32f4. Сейчас разогнал мк В кубе включил TCM interface для flash.ART Accelerator,instruction perfetch настройки адреса flash изменил вручную, т.к. куб не прописывает для KEIL почему то.Потребление камня заметно возросло производительность тоже. Использую DMA (для DСMI) оно вроде как и FLASH( по умолчанию) работает через шину AHB->AXI и там вроде как могут пробыть проблемы если включить кэш команд и данных.Поэтому сделал как написал выше. В планах разместись стек и кучу и FIFO буфер в DTCM и обработчики прерываний в ITCM. Работаю без RTOS RAW API.Проблема в том, ЧТО Я НЕ МОГУ ПОЛУЧИТЬ нормальные 10 Мегабит не говоря уже о 10 Мегабайтах в секунду о которых пишут. Передаю пакеты размером 16Кило след. образом. while(ETH_TXBUF_SIZE > get_tcp_sndbuf_free(&CI)) MX_LWIP_Process(); tcp_write(CI.tcp_client_pcb,ETH_TX_buf,ETH_TXBUF_SIZE, 1); tcp_output(CI.tcp_client_pcb); Проблема в том что пришлось выкрутить TCP_TMR_INTERVAL в 1 вместо 250? Иначе не работает на таких скоростях. По идее TCP_TMR_INTERVAL я вообще не должен трогать!!! Сейчас удается передать поток 5 Мегабит с камеры, есть tcp retransmission,tcp dup ACK. Есть логи отладки через stats_display(); там все ОК. lwipopts.h Edited November 7, 2020 by BorisBritwa Quote Ответить с цитированием Share this post Link to post Share on other sites
Сергей Борщ 0 Posted November 7, 2020 · Report post С 7xx не работаю, ничего конкретного подсказать не могу. Посмотрите это письмо из рассылки lwip, возможно найдете что-то полезное в вашем случае. И как модератор предупреждаю вас: прекратите совать свои видео в каждое сообщение, это будет расценено как навязчивая реклама (канала) с соответствующими оргвыводами. При регистрации вы согласились соблюдать Правила форума, прочитайте еще раз пункт 3.6. На первый раз устное предупреждение. Quote Ответить с цитированием Share this post Link to post Share on other sites
BorisBritwa 0 Posted November 9, 2020 · Report post Также читал __DSB у меня такой строчки нет, и ее добавление ничего не решает в моем случае. Вернулся к истокам.Собрал дефолтный проект с lwip и больше ничего, изменил MEM_SIZE 65536,MEMP_NUM_TCP_SEG 401,TCP_SND_BUF 53600. КЭШ НЕ ВКЛЮЧАЛ.Передаю рас в секунду массив размером 16Кило.Передача идет но в wireshark много TCP_DUP_ACK,TCP_retransmission, while (1) { MX_LWIP_Process(); time_ms = HAL_GetTick(); if(time_ms - last_time_ms_task1 > 1000){//TCP_TMR_INTERVAL send_buf_frspace = get_tcp_sndbuf_free(&CI); printf("send_buf_frspace %d\n\r",send_buf_frspace); if (CI.conn_status == S_ESTABLISHED) if(ETH_TXBUF_SIZE < send_buf_frspace){ ret_err = tcp_write(CI.tcp_client_pcb,ETH_TX_buf,ETH_TXBUF_SIZE, 1); if(ret_err != ERR_OK)printf("tcp_write err %d\n\r",ret_err); ret_err = tcp_output(CI.tcp_client_pcb); if(ret_err != ERR_OK)printf("tcp_output err %d\n\r",ret_err); } last_time_ms_task1 = time_ms; } } валит ошибки ERR_USE после вызова tcp_output(); Причина ошибки файл ethernetif.c, тут функция low_level_output(). /* Check if the buffer is available */ if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) { errval = ERR_USE; goto error; } Quote Ответить с цитированием Share this post Link to post Share on other sites
AlanDrakes 0 Posted November 9, 2020 · Report post У меня подозрение на малое количество буферов для передачи. Плюс, в Вашем конфиге: #define TCP_WND 4096 - Размер TCP Окна - всего 4кБ. Это мало. Выставьте хотя бы в 32к. Но возможно дело не в нём. #define MEMP_NUM_PBUF 32 - Подозреваю, что количество буферов (хотя могу ошибиться) - всего 32. Тоже мало. Поднимите хотя бы до 60 (по рекомендации авторов LWIP: http://www.nongnu.org/lwip/2_0_x/group__lwip__opts__memp.html#ga92b30aed958ec59334d936d4ca725418 ). Судя по выделеным под буфер 132кБ, должно влезть вплоть до 86. Возможно чуть меньше из-за накладных расходов от DMA контроллера. Как-то пробовал гонять поток данных (разве что по UDP от железки в сторону компа) и обратно (от компа к железке, но уже по TCP) через tlk105 (mii ethernet физика), так скорость в первом случае упёрлась в потолок (~99Мбит/с), а во втором - была порядка 40Мбит/с. Дамп трафика, к сожалению, не найти. Quote Ответить с цитированием Share this post Link to post Share on other sites
BorisBritwa 0 Posted November 9, 2020 · Report post 12 минут назад, AlanDrakes сказал: У меня подозрение на малое количество буферов для передачи. Плюс, в Вашем конфиге: #define TCP_WND 4096 - Размер TCP Окна - всего 4кБ. Это мало. Выставьте хотя бы в 32к. Но возможно дело не в нём. #define MEMP_NUM_PBUF 32 - Подозреваю, что количество буферов (хотя могу ошибиться) - всего 32. Тоже мало. Поднимите хотя бы до 60 (по рекомендации авторов LWIP: http://www.nongnu.org/lwip/2_0_x/group__lwip__opts__memp.html#ga92b30aed958ec59334d936d4ca725418 ). Судя по выделеным под буфер 132кБ, должно влезть вплоть до 86. Возможно чуть меньше из-за накладных расходов от DMA контроллера. Как-то пробовал гонять поток данных (разве что по UDP от железки в сторону компа) и обратно (от компа к железке, но уже по TCP) через tlk105 (mii ethernet физика), так скорость в первом случае упёрлась в потолок (~99Мбит/с), а во втором - была порядка 40Мбит/с. Дамп трафика, к сожалению, не найти. По буферам запас было видно из статистики, кроме TCP_SND_BUF, иногда не хватает. Сейчас все на минимуме, рас в секунду 16 кило.Проект собрал заново без использования другой периферии ethernet +usart для отладки(скорость 2000000). Размер окна TCP_WND, только на прием будет влиять? Во всяком, ставил больше изменений не видно было. MEMP_NUM_PBUF в порог не упирался исходя из статистики. Quote Ответить с цитированием Share this post Link to post Share on other sites
BorisBritwa 0 Posted November 9, 2020 · Report post Прилепляю лог статистики для нового чистого проекта только с lwip отправка рас в секунду 16 кило, как отправляю указал выше.Есть ошибки ERR_USE после вызова tcp_output(); в текстовом файле они можно найти по строке "tcp_output err -8". Кэш пока не использую, могу скинуть проект если кому это поможет.Пакеты передаются но много ошибок писал выше. Ошибки ERR_USE появляются в функции low_level_output() находится в файле ethernetif.c строки : /* Is this buffer available? If not, goto error */ if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) { errval = ERR_USE; goto error; } Данная проблема уже давно https://community.st.com/s/question/0D50X00009Xkgff/stm32f746-ethernet-dma-transmit-problem statistic.txt Quote Ответить с цитированием Share this post Link to post Share on other sites
BorisBritwa 0 Posted November 10, 2020 (edited) · Report post НАДЕЮСЬ ЭТО СЭКОНОМИТ КОМУ-ТО ВРЕМЯ.МОИ НАБЛЮДЕНИЯ РАЗМЕР СООБЩЕНИЯ КРАТЕН MSS, если одна посылка то <=MSS. РАЗМЕР ОТПРАВЛЯЕМОГО ПАКЕТА НЕ БОЛЕЕ 6*MSS . Кэш не включен MSS1460 куча 60 кило,размер TSP_SND_BUF 60*MSS удается прокачивать до 6 мегабит без ошибок, частота SYSCLK 96MHZ, уменьшал до 10 TCP_TMR_INTERVAL, быстрее буфер освобождается. Можно не уменьшать но буфер тогда надо по шире. В логах статистики запас по буферам и памяти не придраться.Кроме TCP_SND_BUF при ошибках его будет ужирать. ETH_TX_buf его размер меняется и указан в функции "отправки",правильнее сказать функции записи в другой буфер, под который предварительно выделяется память.И после каждой tcp_write() вызывается tcp_output() как выше писал.Настройки lwip прилагаю. Например отправляю рас в 500мс буфер отправки TCP_SND_BUF свободен на 80% : tcp_write(CI.tcp_client_pcb,ETH_TX_buf,1460*6, 1); будет работать без ошибок MSS 1460 tcp_write(CI.tcp_client_pcb,ETH_TX_buf,1500*6, 1); будет работать c ошибками. ERR_USE и повторные отправки tcp_write(CI.tcp_client_pcb,ETH_TX_buf,1460*7, 1);будет работать c ошибками.ERR_USE и повторные отправки tcp_write(CI.tcp_client_pcb,ETH_TX_buf,1460*8, 1);будет работать c ошибками.ERR_USE после вызова tcp_output() повторных оправок нет, но если увеличить скорость передачи думаю появятся . Если включить ART и изменить адрес как выше писал, то опять ошибки при передаче.Если не включать ART поднять частоту выше 216MHZ опять ERR_USE и повторные отправки.Короче одно шайтнство.Корень проблемы указан выше и где он возникает,но решают его каждый по разному . Сейчас добавлю еще работу с DMA и все по хер...ся. lwipopt.txt Edited November 10, 2020 by BorisBritwa Quote Ответить с цитированием Share this post Link to post Share on other sites
mantech 0 Posted November 10, 2020 (edited) · Report post 2 часа назад, BorisBritwa сказал: tcp_write(CI.tcp_client_pcb,ETH_TX_buf,1460*6, 1); будет работать без ошибок MSS 1460 tcp_write(CI.tcp_client_pcb,ETH_TX_buf,1500*6, 1); будет работать c ошибками. ERR_USE и повторные отправки Я б на вашем месте сначала добился безошибочной передачи и приема сырых езернет пакетов между двумя платами аля-пин-понг на максимальной скорости, потом бы прикрутил стек и пошел дальше... Edited November 10, 2020 by mantech Quote Ответить с цитированием Share this post Link to post Share on other sites
AlanDrakes 0 Posted November 11, 2020 · Report post О, и кстати, проверьте, что все буферы, которые используются Ethernet DMA выравнены на 4 байта (можно больше). Один раз я пару дней ловил непонятную ошибку с приёмом данных и зависанием работы на приём по той же причине - дескриптор буфера оказывался недоступен для DMA контроллера. Выяснилось, что если память не была выравнена, то запись происходила в дополнительные места вокругу порции данных. Примерно так: Буфер (16 байт), в памяти с адреса xxx01 вместо xxx00: Адрес: 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10- 11- 12- 13- 14- 15- 16 Данные: x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x Происходит запись 4 байт (01, 02, 04, 08) в адреса 1-4: Адрес: 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10- 11- 12- 13- 14- 15- 16 Данные: 00- 01- 02- 04- 08- 00- 00- 00- x - x - x - x - x - x - x - x - x Следующая запись 4 байт (10, 20, 40, 80) в адреса 4-8: Адрес: 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10- 11- 12- 13- 14- 15- 16 Данные: 00- 01- 02- 04- 08- 10- 20- 40- 80- 00- 00- 00- x - x - x - x - x С заким описанием буфера - заработало без ошибок: uint8_t TX_BUF[ETH_MAX_PACKET_SIZE * BUFFERS_COUNT] __attribute__((aligned(4))); Собиралось НЕ под LWIP, а под чуть более голое железо. Quote Ответить с цитированием Share this post Link to post Share on other sites
BorisBritwa 0 Posted November 11, 2020 · Report post 11 минут назад, AlanDrakes сказал: О, и кстати, проверьте, что все буферы, которые используются Ethernet DMA выравнены на 4 байта (можно больше). Один раз я пару дней ловил непонятную ошибку с приёмом данных и зависанием работы на приём по той же причине - дескриптор буфера оказывался недоступен для DMA контроллера. Выяснилось, что если память не была выравнена, то запись происходила в дополнительные места вокруг порции данных. Примерно так: С таким описанием буфера - заработало без ошибок: uint8_t TX_BUF[ETH_MAX_PACKET_SIZE * BUFFERS_COUNT] __attribute__((aligned(4))); Собиралось НЕ под LWIP, а под чуть более голое железо. Спасибо буду иметь ввиду. Не написал, что кэши и кучу поднимал аж до 0x4000(которые в startup, сейчас 0x1000) для lwip памяти давал за 100К результата ноль. Пока вопрос почему так происходит открыт, но уже можно с этим жить.Сейчас буфер кратен MSS*10.Удалось до 5 мегабит поднять, пока хватит можно стримить. На wiznet w5500 и F4 мне не удалось добиться такой скорости.Там либо SPI медленный,вешаешь на другой канал spi уже быстрый, так уже задействовано одно и тоже ДМА с разными "каналами" и по скорости хуже получается.То есть одно ДМА обслуживает и SPI и DCMI. В итоге на F7 SYSCLK 96MHZ ,если установить в два раза выше то появятся ошибки при передаче( опять дескриптор будет, будет не доступен для ДМА, когда ему вздумается) если их не было. Сейчас задействовано еще одно DMA DCMI, получаю 15 FPS 480x320, c OV2640 в норм качестве, по TCP.Ошибок при вызове функций нет.Если смотреть в wire shark, то не значительно на основном фоне ретрансмиты и dup_ack. Quote Ответить с цитированием Share this post Link to post Share on other sites
AlanDrakes 0 Posted November 17, 2020 · Report post Есть у меня подозрение, что 96МГц маловато для этого кристалла, или этой задачи. Особенно, имея два активных канала DMA. Ощущаю возможные попытки одновременного доступа к памяти, что черевато задержками и не совсем сбоями, но всё же. Можете описать процесс стриминга на примере нескольких кадров? Примерно так: 1. Получаем кадр из камеры через DMAxxx, кладём его по адресу 0x20xxxxxx 2. Канал DMAyyy настраиваем на (%действие%) (адрес?) 3. Собираем пакет в адресах 0x2xxxxxxx <...> И так далее. Это может помочь в понимании, может ли действительно быть борьба за шину памяти. Кстати, посмотрите распределение адресов для разных DMA и разных ведомых на своём контроллере. Если ядро активно что-то делает, то оно будет чаще выигрывать арбитраж шины и тормозить всех остальных. В этом случае - либо отправлять его в WFI/WFE паузы, либо как-то иначе настраивать адресацию. Ну или проще - задрать тактовую частоту выше. Quote Ответить с цитированием Share this post Link to post Share on other sites
BorisBritwa 0 Posted December 7, 2020 · Report post В итоге перешел на RTOS+LWIP проблем никаких нет.Проц на максимальной частоте.Кэш выключен.TCM INTERFACE+ART+PRETHETCH скорость передачи по TCP до 14 Мегабит.Если как у меня на полную используется DMA DCMI, то скорость передачи до 12 мегабит больше пока не удалось получить(ну я сильно не старался).Не замерял какая скорость передачи у ESP32CAM, вблизи точки доступа было бы интересно сравнить. Quote Ответить с цитированием Share this post Link to post Share on other sites
x893 0 Posted December 7, 2020 · Report post 3 hours ago, BorisBritwa said: В итоге перешел на RTOS+LWIP проблем никаких нет.Проц на максимальной частоте.Кэш выключен.TCM INTERFACE+ART+PRETHETCH скорость передачи по TCP до 14 Мегабит.Если как у меня на полную используется DMA DCMI, то скорость передачи до 12 мегабит больше пока не удалось получить(ну я сильно не старался).Не замерял какая скорость передачи у ESP32CAM, вблизи точки доступа было бы интересно сравнить. Отлично ! Ждём на github для тестирования. Quote Ответить с цитированием Share this post Link to post Share on other sites