Эдуард
уважаемые админы, я писал сообщение, а его дробнул ваш антиспам бот.
ㅤ
уважаемые админы, я писал сообщение, а его дробнул ваш антиспам бот.
Всем привет. Кто может рассказать как работает аппаратное прерывание по приёму данных UART2 на esp32 и можно ли его настроить без библиотек ядра? Ядро esp32 by Espressif Systems версия 2.0.11 У меня на esp32 отправляет данные stm32 на скорости 460800. Сейчас в ардуиноIDE я поднимаю UART2 вот так: Serial2.onReceive(handleSerial2Data); Serial2.setRxBufferSize(4096); Serial2.begin(460800); В прерывании esp32 код упростил до вот такого: char Serial2_buff_RX[2]; void handleSerial2Data() { Serial2_buff_size+=Serial2.available(); while (Serial2.available()) { Serial2_buff_RX[0]=Serial2.read(); }; } Если слать данные пачками с паузами (у меня получилось по 78 байт пакеты), то всё отлично принимается и успевает обрабатываться, но если я шлю потоком без пауз, то всё лежит. Передаю 14000байт С паузами получаю в переменной Serial2_buff_size значение 14000 Без пауз получаю 160 в этой же переменной. Кто может объяснить что я не так делаю и как поднять UART и настроить прерывание по приёму данных как это делается например на stm32?
Эдуард
отлично
Эдуард
оказывается не дробнул
ㅤ
оказывается не дробнул
Дропнул. В логах оно остается
Эдуард
Спасибо
Эдуард
Ещё бы так быстро ответ написали бы)))
ㅤ
А если rxbuffer увеличить ?
Эдуард
на сколько?
ㅤ
на сколько?
А ты поясни это что значит " Serial2_buff_RX[0]=Serial2.read();" ?
ㅤ
Почему ты читаешь в одно и тоже место все время?
Эдуард
это не важно. Бизнес-логика будет потом. Сейчас даже с такой простой конструкцией всё валится
ㅤ
это не важно. Бизнес-логика будет потом. Сейчас даже с такой простой конструкцией всё валится
Так смотри тебе пришло прерывание. Там 1000 байт. У тебя 1000 байт прочтется в Serial2_buff_RX[0]. И?
ㅤ
Почему индекс не меняется?
Эдуард
А ты поясни это что значит " Serial2_buff_RX[0]=Serial2.read();" ?
заглушка, что типа я вычитываю данные из буфера в которой где-то там в глубине этик библиотек оно хранится
Эдуард
ㅤ
Мля while (Serial2.available()) { Serial2_buff_RX[0]=Serial2.read(); }; Если этот while будет по кругу у тебя будет в буфере один байт. Я не очень понимаю зачем так делать. Индекс где?
Эдуард
если никуда не читать Serial2.read(), то переполнится буфер внутренний
ㅤ
Это понятно
Эдуард
от того что я напишу реальный код что-то изменится? Вот он: void handleSerial2Data() { Serial2_buff_size+=Serial2.available(); while (Serial2.available()) { // если есть необработанные данные полученные по UART от микроконтроллера stm32 Serial2_buff_RX[Serial2_index_buff_RX_accepted++]=Serial2.read(); if (Serial2_index_buff_RX_accepted>=MAX_SERIAL2_BUFF_UART_RX) { Serial2_index_buff_RX_accepted=0; } if (Serial2_index_buff_RX_processed==Serial2_index_buff_RX_accepted) { Serial2_index_buff_RX_err++; } }; }
Эдуард
теперь мы вычитываем полученные данные из одного кольцевого буфера в другой
Эдуард
мне надо вот это засунуть в прерывание которое возникает при приёме байта по UART и всё тогда у меня заработает
ㅤ
Ты просто приводишь пример и просишь помочь. Я вот вижу что там делается какая-то херня и на это указал. А ты злишься и материшься. Откуда мне знать что у тебя код фейковый?
ㅤ
В этот чат всякие разные кадры ходят и неизвестно их степень "мастерства". Может ты на полном серьезе так делал?
Эдуард
ок
Эдуард
вот что я хочу: void IRAM_ATTR uart2_isr(void* arg) { // Читаем статусный регистр uint32_t status = REG_READ(UART_INT_ST_REG(2)); // Обрабатываем только прерывания приема while (REG_READ(UART_STATUS_REG(2)) & UART_RXFIFO_CNT_M) { // Читаем байт из FIFO Serial2_buff_RX[Serial2_index_buff_RX_accepted++] = REG_READ(UART_FIFO_AHB_REG(2)) & 0xFF; if (Serial2_index_buff_RX_accepted>=MAX_SERIAL2_BUFF_UART_RX) { Serial2_index_buff_RX_accepted=0; } if (Serial2_index_buff_RX_processed==Serial2_index_buff_RX_accepted) { Serial2_index_buff_RX_err++; } } // Сбрасываем флаги прерываний REG_WRITE(UART_INT_CLR_REG(2), status); }
Sergey
14кб данных как то многовато для кода с двумя прослойками, чудо что оно хоть как то работает
Эдуард
14кб данных как то многовато для кода с двумя прослойками, чудо что оно хоть как то работает
есть определённые тайминги и stm32 очень легко справляется с такими скоростями
Эдуард
считаем: 240МГц тактовая и дальше скорость 460800бот. Это 46 080 байт со стартовыми и стоповыми. Если работаем в прерывании, то по 5200 тактов на каждый принятый байт. Моё написанное прерывание должно отлично работать. Там нет никаких сверхфункций.
ㅤ
У меня тоже впечатление что он в прерывании захлебывается в этих враперах ардуиновских
ㅤ
непонял. перефразируйте
Ну тут фреймворк ардуино поверх фреймворка esp-idf.Там очень много лишнего кода выполняется
Эдуард
Есть. Одна только serial read вызывает кучу всего прежде чем доберется до буфера
где? если читать из регистра как я написал в примере с прерыванием то нет никакого serial read
Эдуард
А попробуй rxbuffer увеличить до 14к
ага... а когда у мне нужно будет передать прошивку 2Мб, то совет будет "увеличьте буфер до 2Мб"
Sergey
где? если читать из регистра как я написал в примере с прерыванием то нет никакого serial read
Мне ok-home помогал похожую проблему решить в esp-idf, но здесь ещё ардуина поверх, поэтому хз
ㅤ
ага... а когда у мне нужно будет передать прошивку 2Мб, то совет будет "увеличьте буфер до 2Мб"
Нет, я хотел посмотреть что будет на ардуиновском примере. Изменится ли хоть что нибудь
Эдуард
ща попробуем
ㅤ
Для начала я бы выкинул все эти инициализации ардуиновские и воспользовался бы примерами esp-idf. Ибо что у них под капотом не ясно
ㅤ
Юзал бы классические uart_driver_install и тд
Эдуард
поднял Serial2.setRxBufferSize(24576); после приёма в переменной Serial2_buff_size 160 байт
ㅤ
На стм32 у тебя нет фреймворка поверх фреймворка)
Да и вообще сравнивать есп32 с стм32 такое себе. Ему до стм как до луны
Эдуард
с паузами так же всё исправно работает и получаю 14000байт
Эдуард
реально есть у кого опыт, чтобы не просто кучу советов лепить, а по делу было?
Эдуард
если нет, то предлагаю дробнуть всю ветку до моего вопроса. Там всё коротко написано и по делу.
Эдуард
Для начала я бы выкинул все эти инициализации ардуиновские и воспользовался бы примерами esp-idf. Ибо что у них под капотом не ясно
я и выкинул. и нифига не могу въехать почему у меня прерывание не срабатывает. В примерах прикручивается очередь
Эдуард
а она тоже отъедать будет при работе и тупить всё это
Эдуард
блин. как прекрасен stm32)))
ok-home
с нетерпением жду
ну пришел )) я действительно на ардуине не копенгаген могу посмотреть код ядра, но иметь одновременно serial и забрать у него прерывания мне кажется так себе затея
ok-home
поднял Serial2.setRxBufferSize(24576); после приёма в переменной Serial2_buff_size 160 байт
ровно аппаратный буфер если мне не изменяет память, точнее драйвер вроде столько под rx выделяет
Эдуард
ну пришел )) я действительно на ардуине не копенгаген могу посмотреть код ядра, но иметь одновременно serial и забрать у него прерывания мне кажется так себе затея
в каком смысле иметь одновременно serial и забрать у него прерывание? Я хочу настроить работу UART и подключить своё прерывание для обработки принимаемых байт. Мне не надо оставлять serial как отдельный объект библиотек esp32
Эдуард
ровно аппаратный буфер если мне не изменяет память, точнее драйвер вроде столько под rx выделяет
я игрался с разными таймингами и точно могу сказать что аппаратный буфер 256 байт скорее всего
Эдуард
ну пришел )) я действительно на ардуине не копенгаген могу посмотреть код ядра, но иметь одновременно serial и забрать у него прерывания мне кажется так себе затея
а в чём собираете код? Скорее ж всего ядро от espressif одно и тоже используется? Если есть понимание как сделать в вашей среде разработки, то может быть скинете код, а я уже погляжу и попробую адаптировать под свою задачу в среде arduinoIDE. Ну может быть ещё понадобится версия ядра и где качали, потому что у них там от версии к версии то переменные по разному зовутся, то ещё что-то случается)))
ㅤ
а в чём собираете код? Скорее ж всего ядро от espressif одно и тоже используется? Если есть понимание как сделать в вашей среде разработки, то может быть скинете код, а я уже погляжу и попробую адаптировать под свою задачу в среде arduinoIDE. Ну может быть ещё понадобится версия ядра и где качали, потому что у них там от версии к версии то переменные по разному зовутся, то ещё что-то случается)))
Если есть возможность лучше уйти на esp-idf, от ардуины отказаться полностью https://github.com/espressif/esp-idf/blob/master/examples/peripherals/uart/uart_events/main/uart_events_example_main.c Этот код можно даже собрать на ардуино иде вроде (загнав его в сетап и луп). Правда нужна будет третья версия фреймворка. Но это не точно
ㅤ
Да, 128 по умолчанию
Эдуард
а почему тогда я в прерывании ловлю больше?
ㅤ
а почему тогда я в прерывании ловлю больше?
Это по умолчанию. Что там под капотом ардуины не ясно. Надо смотреть её код.
ok-home
короче если верить коду ядра - уменьшаем bool setRxFIFOFull(uint8_t fifoBytes); https://github.com/espressif/arduino-esp32/blob/0302b4db4741ae51ff45a3b1b533175ee0c0d92c/cores/esp32/HardwareSerial.h#L235 вместо serial.read() используем serial.readbytes() https://github.com/espressif/arduino-esp32/blob/0302b4db4741ae51ff45a3b1b533175ee0c0d92c/cores/esp32/HardwareSerial.h#L275 используем bool setRxTimeout(uint8_t symbols_timeout); https://github.com/espressif/arduino-esp32/blob/0302b4db4741ae51ff45a3b1b533175ee0c0d92c/cores/esp32/HardwareSerial.h#L229 и не лезем в прерывания )) да, и мопед не мой - я правда в ардуине не вижу кайфа и разбираюсь с ней только по просьбам трудящихся, поэтому могу быть неправ
ㅤ
Да вот нахер надо. Потом выйдет обновленная версия ардуино и опять что-то сломают. Фреймворк поверх фреймворка такое себе
ㅤ
а в чём сами собираете код? Какую IDE используете?
esp-idf и плагин esp-idf в vscode. База. При желании там можно присрать и ардуино фреймворк
ok-home
и тупо обычным циклом по одному символу читаем, и даже fifoful в 1 можешь поставить, тогда и переполняться почти гаратировано не будет
Эдуард
У меня к esp32 подключена RGB-матрица 128х64. В ардуино IDE всё завелось с первого раза. Я поставил platformio и столкнулся с проблемой что этот же проект собирается и появляется мерцание на матрице. Я понимаю что скорее всего это проблема с приоритетом прерываний, но где это найти я не капенгаген (как писалось выше). С stm32 у меня всё отлично и понимание полное как работает, куда пишется, когда сработает. А вот esp32 для меня какой-то чёрный ящик. Хрен покопаешь вглубь библиотек при необходимости.
Psina
помогите выбрать модуль с дисплеем для ESP32 пожалуйста..
ㅤ
помогите выбрать модуль с дисплеем для ESP32 пожалуйста..
В чем помощь должна заключаться? Они разные как по диагонали так и по разрешению. Тут надо тебе самому определится
Эдуард
зеленый ответил !
у вас был опыт работы с RGB-матрицами 128x64?
ok-home
А чем евенты не угодили?
а они редко нужны, здесь непонятно они в среде прерываний или нет (если нет то теряем скорость если да то отдаваться только всякими хххххISR), когда действительно нужно можно и event. а так только код усложняют