Ruslan
Эдуард
уважаемые админы, я писал сообщение, а его дробнул ваш антиспам бот.
ㅤ
уважаемые админы, я писал сообщение, а его дробнул ваш антиспам бот.
Всем привет. Кто может рассказать как работает аппаратное прерывание по приёму данных 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();" ?
ㅤ
Почему ты читаешь в одно и тоже место все время?
Эдуард
это не важно. Бизнес-логика будет потом. Сейчас даже с такой простой конструкцией всё валится
ㅤ
Почему индекс не меняется?
Эдуард
ㅤ
Мля
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кб данных как то многовато для кода с двумя прослойками, чудо что оно хоть как то работает
Эдуард
Sergey
Эдуард
считаем: 240МГц тактовая и дальше скорость 460800бот. Это 46 080 байт со стартовыми и стоповыми. Если работаем в прерывании, то по 5200 тактов на каждый принятый байт. Моё написанное прерывание должно отлично работать. Там нет никаких сверхфункций.
ㅤ
У меня тоже впечатление что он в прерывании захлебывается в этих враперах ардуиновских
Эдуард
ㅤ
ㅤ
непонял. перефразируйте
Ну тут фреймворк ардуино поверх фреймворка esp-idf.Там очень много лишнего кода выполняется
ㅤ
ㅤ
ㅤ
Эдуард
ща попробуем
Эдуард
ㅤ
ㅤ
Для начала я бы выкинул все эти инициализации ардуиновские и воспользовался бы примерами esp-idf. Ибо что у них под капотом не ясно
ㅤ
Юзал бы классические uart_driver_install и тд
Эдуард
поднял
Serial2.setRxBufferSize(24576);
после приёма в переменной Serial2_buff_size 160 байт
Эдуард
с паузами так же всё исправно работает и получаю 14000байт
Эдуард
реально есть у кого опыт, чтобы не просто кучу советов лепить, а по делу было?
ㅤ
Эдуард
если нет, то предлагаю дробнуть всю ветку до моего вопроса. Там всё коротко написано и по делу.
Эдуард
Эдуард
Эдуард
а она тоже отъедать будет при работе и тупить всё это
Эдуард
блин. как прекрасен stm32)))
ok-home
с нетерпением жду
ну пришел ))
я действительно на ардуине не копенгаген
могу посмотреть код ядра, но иметь одновременно serial и забрать у него прерывания мне кажется так себе затея
Эдуард
ㅤ
ㅤ
ㅤ
Эдуард
а почему тогда я в прерывании ловлю больше?
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
и не лезем в прерывания ))
да, и мопед не мой - я правда в ардуине не вижу кайфа и разбираюсь с ней только по просьбам трудящихся, поэтому могу быть неправ
ㅤ
Да вот нахер надо. Потом выйдет обновленная версия ардуино и опять что-то сломают. Фреймворк поверх фреймворка такое себе
Эдуард
ok-home
и тупо обычным циклом по одному символу читаем, и даже fifoful в 1 можешь поставить, тогда и переполняться почти гаратировано не будет
ㅤ
Эдуард
У меня к esp32 подключена RGB-матрица 128х64. В ардуино IDE всё завелось с первого раза.
Я поставил platformio и столкнулся с проблемой что этот же проект собирается и появляется мерцание на матрице. Я понимаю что скорее всего это проблема с приоритетом прерываний, но где это найти я не капенгаген (как писалось выше). С stm32 у меня всё отлично и понимание полное как работает, куда пишется, когда сработает. А вот esp32 для меня какой-то чёрный ящик. Хрен покопаешь вглубь библиотек при необходимости.
ok-home
Psina
помогите выбрать модуль с дисплеем для ESP32 пожалуйста..
ok-home
А чем евенты не угодили?
а они редко нужны, здесь непонятно они в среде прерываний или нет (если нет то теряем скорость если да то отдаваться только всякими хххххISR), когда действительно нужно можно и event. а так только код усложняют
ok-home
Psina