SII 0 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 11 hours ago, jcxz said: Забываем о суперлупе, переделываем всю работу под любую РТОС. На две задачи: 1) работа с АЦП; 2) работа с файловой системой на SD-карте. Приоритет 2-й задачи ниже чем у 1-й. И проблема решается. Можно даже без DMA и на одном ядре. РТОС для такой задачи даром не нужна и, скорей, лишь усложнит её решение. Достаточно как раз-таки пресловутого цикла -- но только обмен и управление всем этим делом вести через DMA и прерывания, а не тупо "зависая" на каждом устройстве, ожидая его готовности и т.п. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexan300 0 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба Так может есть кто разберется со вторым ядром и сторожевыми собаками? запустив работу библиотеки карты памяти, на втором ядре, можно забыть про PTOC DMA и прочих страшных словах для меня. Я просто уверен, что допускаю какую то неточность в обьяснении из за чего у многих в голове возникают такие сложные объяснения, наверняка простой и стандартной процедуры. Я сегодня выложу сюда код лупа и функции работающим на втором ядре. Сейчас я застрял на том, что не могу передать массив из 16000 значений во второй "луп". Тоесть вроде как мне удалось абстрагироваться от проблем с записью на карту памяти. но за это получив новые. Всех благодарю за обсуждение. Не расходитесь. Призовой фонд ждет своего победителя) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 2 часа назад, Lelikk сказал: Не будет блокировать она ничего - данные будут собираться в прерывании. "Она" - это кто? О ком речь? Middleware реализующая работу с ФС? Есть неблокирующая? Расскажите тогда нам о такой. Я думаю - многим будет полезно узнать о таком. 1 час назад, SII сказал: РТОС для такой задачи даром не нужна и, скорей, лишь усложнит её решение. Чем именно усложнит? Имхо - реализация более-менее сложного автомата состояний внутри ISR для новичка будет гораздо сложнее РТОС. 33 минуты назад, alexan300 сказал: запустив работу библиотеки карты памяти, на втором ядре, можно забыть про PTOC DMA и прочих страшных словах для меня. А Вы уверены, что сможете разобраться в межъядерной синхронизации, если даже межзадачная синхронизация (в пределах одного ядра) у вас вызывает страх? Межъядерная синхронизация заведомо сложнее межзадачной. Да и смысла никакого нет тащить ещё и второе ядро для такой простой задачи. Цитата Сейчас я застрял на том, что не могу передать массив из 16000 значений во второй "луп". Точно так же застрянете при передаче его между ядрами. А там ещё сложнее передавать. PS: Изучайте многозадачную работу и средства межзадачной синхронизации! PPS: Не понимаю - откуда такая боязнь РТОС у множества здешних писателей? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба google "esp32 arduino multithreading" > https://randomnerdtutorials.com/esp32-dual-core-arduino-ide/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rkit 4 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба Массив не надо передавать, он просто статически выделен как глобальная переменная. Нужно открывать семафор, когда половина массива записана. Другой поток по семафору узнает, что из этой половины можно читать. Потом то же самое делать с другой половиной, и чередовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lelikk 0 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 54 minutes ago, jcxz said: "Она" - это кто? О ком речь? Middleware реализующая работу с ФС? Есть неблокирующая? Расскажите тогда нам о такой. Я думаю - многим будет полезно узнать о таком. Надо разобраться в терминах блокировки - блокирующая это что? 1. Функция API крутится в цикле, ожидая желаемого ею события запретив при этом прерывания на все время ожидания? 2. Функция API крутится в цикле, ожидая желаемого ею события? Если случай (2), то ничего не помешает написать обмен по SPI хотя бы в прерывании таймера. Тут можно скорее не говорить о боязни RTOS, а о том, что зачем стрелять из пушки по воробьям. RTOS надо использовать когда есть много разных задач, в остальных случаях она только мешает выживать скорость из аппаратуры, так то можно хоть .NET Micro прикрутить, потом поставить MCU помощнее :))) Если нужно просто в background несколько задач обслужить, то невытесняющий автомат запускающий список задач с разными периодами занимает максимум 100 строк. Использовать RTOS не потому что без нее нельзя, а потому что в остальном лень разбираться - это путь в никуда. 1 hour ago, alexan300 said: Так может есть кто разберется со вторым ядром и сторожевыми собаками? запустив работу библиотеки карты памяти, на втором ядре, можно забыть про PTOC DMA и прочих страшных словах для меня. Я просто уверен, что допускаю какую то неточность в обьяснении из за чего у многих в голове возникают такие сложные объяснения, наверняка простой и стандартной процедуры. Я сегодня выложу сюда код лупа и функции работающим на втором ядре. Сейчас я застрял на том, что не могу передать массив из 16000 значений во второй "луп". Тоесть вроде как мне удалось абстрагироваться от проблем с записью на карту памяти. но за это получив новые. Всех благодарю за обсуждение. Не расходитесь. Призовой фонд ждет своего победителя) Никто вашу задачу решать не будет, пока вы решите заплатить нормальные деньги. Обучение программированию в данной ветке вряд ли будет иметь результат в конечном итоге. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 2 часа назад, Lelikk сказал: Надо разобраться в терминах блокировки - блокирующая это что? "Блокирующий I/O" в отличие от "неблокирующего I/O" - это когда функция API возвращает управление в вызывающую процедуру после завершении I/O-операции. При неблокирующем I/O управление может быть возвращено в вызывающую процедуру до завершения всех I/O-операций, а сигнализация о завершении I/O-операций производится дополнительным механизмом (при помощи семафоров и т.п.). Неблокирующий доступ позволяет не задерживать работу задачи на время выполнения I/O-операций. Но он сложнее. Блокирующий доступ конечно проще, но требует выделения в отдельную задачу ОС, если нужно чтобы выполнение других функций не тормозилось I/O-операциями. В некоторых API есть как блокирующий так и неблокирующий механизмы работы. Например - в WinAPI, неблокирующий доступ называется "overlapped I/O", а блокирующий так и называется. Насчёт FatFS: насколько я знаю она имеет только блокирующий API. Хотя ТС так и не прояснил с помощью какого middleware он работает с SD. Остаётся только гадать. Если он использовал блокирующий механизм, то естественно в работе вызывающей задачи будут задержки на время выполнения каких-то операций (типа ожидания завершения записи или стирания). Цитата Если случай (2), то ничего не помешает написать обмен по SPI хотя бы в прерывании таймера. Вообще-то такой вариант я и предлагал ещё в том сообщении, на которое вы отвечали. Это и получается, что на прерываниях (таймера или чего другого) будет реализована псевдозадача. Т.е. - будет аналог работы 2-х задач в РТОС. Цитата Тут можно скорее не говорить о боязни RTOS, а о том, что зачем стрелять из пушки по воробьям. RTOS надо использовать когда есть много разных задач, в остальных случаях она только мешает выживать скорость из аппаратуры Для задачи ТС-а и его МК какие-то накладные расходы связанные с РТОС настолько несущественны, что ими можно пренебречь. На Cortex-M на частотах в десятки МГц и выше, накладные расходы РТОС - доли процента. Зато когда окажется, что ему вдруг например: нужно выводить отладочные логи из одной задачи и из другой одновременно в один UART и чтобы другу-другу не мешали, вот тогда окажется, что с РТОС это решается за 5 минут штатными механизмами (семафорами и т.п.). А если он то же самое попытается сделать из псевдозадачи на ISR-ах, то скорей всего сядет в лужу. Ну или в лучшем - потратит в разы больше времени на реализацию такого механизма. Цитата Если нужно просто в background несколько задач обслужить, то невытесняющий автомат запускающий список задач с разными периодами занимает максимум 100 строк. Вы посмотрите на МК который у ТС. Это не 8-битный AVR. Каждый байт тут экономить нужды нету. Экономить и оптимизировать нужно только там где это реально нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 1 hour ago, Lelikk said: Никто вашу задачу решать не будет, пока вы решите заплатить нормальные деньги. Обучение программированию в данной ветке вряд ли будет иметь результат в конечном итоге. То что у TC нет денег ясно с самого начала было. RTOS здесь обязательна, а вот два ядра нафиг не нужны. Вот график достигнутых минимальных скоростей в Azure RTOS на некоей SD карте. По оси Х отложены номера итераций, по оси Y минимальная скорость на каждой итерации. Каждая итерация представляет собой запись файла в 1 Гбайт. Скрость измерялась после передачи каждых 4-х килобайт. Как видно можно добиться гарантированной скорости в 60 Кбайт в сек. НО чтобы портировать это на ESP 32 требуется серьезный бюджет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexan300 0 7 августа, 2020 Опубликовано 7 августа, 2020 (изменено) · Жалоба while (pg < 16000) { // //чтение данных из АЦП: 1000 кадров 8 каналов по 2 байта каждый канал while (digitalRead(DRDY) == 1); //{ //ожидание готовности данных DRDY=0 delayMicroseconds(2); digitalWrite(SpiCS, LOW); for (i = 0; i < 3; i++) hspi->transfer(0x00); //пустые чтение Статуса for (i = 0; i < 8; i++) { //hspi->transfer(0x00); //пустое чтение старшего байта Result[pg++] = hspi->transfer(0x00); //чтение и запись старшего байта Result[pg++] = hspi->transfer(0x00); //чтение и запись среднего байта //Result[pg++] = hspi->transfer(0x00); //чтение и запись среднего байта88 hspi->transfer(0x00); //пустое чтение младшего байта } delayMicroseconds(2); digitalWrite(SpiCS, HIGH); } j = 0; while (pg < 16000) { //вывод данных в UART: 1000 кадров 8 каналов по 2 байта каждый канал for (i = 0; i < 8; i++) { pg = 0; pg = ((Result[j++] << 8) | Result[j++]); //преобразовать в 2х байтное слово // pg =>>3; Serial.print(pg, DEC); Serial.print("\t"); //данные каналов разделяются табуляцией // myFile.print(pg);myFile.print("\t"); } Serial.println(""); // } // myFile.close(); } скетч сверху, понятно дело, транслирует данные на сериал порт, по две секунды записи. закоменчены попытки вместо отправки в порт, писать на карту памяти. в этом случае всегда пропадает часть сигнала. скрины с лог анализатора. пакеты с ацп разделяются 3.9 милисек. второй скрин, одномоментная запись на карту памяти и чтение с ацп в буфер. Как видно, что друг другу перефрия не мешает. Но возникает проблема обусловленая ватчдогом, и данные у меня переносятся с одного процесса в другой с нарушением. Каким? пока выясняю. скетч сверху, понятно дело, транслирует данные на сериал порт, по две секунды записи. закоменчены попытки вместо отправки в порт, писать на карту памяти. в этом случае всегда пропадает часть сигнала. скрины с лог анализатора. пакеты с ацп разделяются 3.9 милисек. второй скрин, одномоментная запись на карту памяти и чтение с ацп в буфер. Как видно, что друг другу перефрия не мешает. Но возникает проблема обусловленая ватчдогом, и данные у меня переносятся с одного процесса в другой с нарушением. Каким? пока выясняю. Далее код для второго ядра: void Task1code( void * pvParameters ) { Serial.println("номер процуссора--"); Serial.println(xPortGetCoreID()); //TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; //TIMERG0.wdt_feed=1; //TIMERG0.wdt_wprotect=0; for (;;) { myFile = SD.open("1.txt", FILE_WRITE); j = 0; while (pg < 16000) { //вывод данных в сд: 1000 кадров 8 каналов по 2 байта каждый канал for (i = 0; i < 8; i++) { pg = 0; pg = ((Result[j++] << 8) | Result[j++]); //преобразовать в 2х байтное слово // pg =>>3; // Serial.print(pg, DEC); Serial.print("\t"); //данные каналов разделяются табуляцией myFile.print(pg);myFile.print("\t"); } //Serial.println(""); } vTaskDelay (10); } // vTaskDelete( NULL ); //esp_task_wdt_reset ( ) ; } и да, сверху такое добавил #define CONFIG_INT_WDT_TIMEOUT_MS 3000 частично спасает от собаки. Изменено 7 августа, 2020 пользователем alexan300 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vguard 2 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 1. Код не рабочий. Второй и третий циклы while (pg < 16000) будут либо бесконечными, либо завершаться в разных местах. 2. Писать на SD большой кусок побайтово плохая идея. Пишите большими блоками. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexan300 0 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 32 minutes ago, vguard said: 1. Код не рабочий. Второй и третий циклы while (pg < 16000) будут либо бесконечными, либо завершаться в разных местах. 2. Писать на SD большой кусок побайтово плохая идея. Пишите большими блоками. Я тут и ищу того, кто сделает его рабочим. Как сразу записать блоком? такого в примерах библиотеки не нашел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 24 minutes ago, alexan300 said: Я тут и ищу того, кто сделает его рабочим. Его нельзя сделать рабочим, не переписав полностью. В результате Вы ищете человека, который: а) напишет грамотный код б) сделает это в ардуиновской среде в) научит его использовать далее И все это (особенно последний пункт) за 9 т.р. Так не бывает. 27 minutes ago, alexan300 said: Как сразу записать блоком? такого в примерах библиотеки не нашел. Очевидно, сформировав его сначала в памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexan300 0 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 3 minutes ago, aaarrr said: Его нельзя сделать рабочим, не переписав полностью. В результате Вы ищете человека, который: а) напишет грамотный код б) сделает это в ардуиновской среде в) научит его использовать далее И все это (особенно последний пункт) за 9 т.р. Так не бывает. Очевидно, сформировав его сначала в памяти. А что значит "полностью"? полностью код куда обширнее, включает дополнительные библиотеки, функции управления ацп, библиотеку с оптокодами, и тд и тп. их зачем трогать? Мне лишь надо поместить данные с ацп, на карту памяти. и все. и у меня этих "переписчиков\переразводчиков\схемотехников " было не мало. Простую часть задачи исполнят, деньги возьмут, а далее в кусты.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 7 августа, 2020 Опубликовано 7 августа, 2020 · Жалоба 2 minutes ago, alexan300 said: А что значит "полностью"? полностью код куда обширнее, включает дополнительные библиотеки, функции управления ацп, библиотеку с оптокодами, и тд и тп. их зачем трогать? Показанные фрагменты не оставляют иных вариантов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 8 августа, 2020 Опубликовано 8 августа, 2020 · Жалоба 13 hours ago, SII said: РТОС для такой задачи даром не нужна и, скорей, лишь усложнит её решение. Достаточно как раз-таки пресловутого цикла Пресловутый цикл и даром не нужен для такой задачи, лишь усложнит её решение. Достаточно как раз РТОС. Не все они тяжёлые, как windows. Есть совсем лёгкие, например scmRTOS. 12 hours ago, alexan300 said: запустив работу библиотеки карты памяти, на втором ядре, можно забыть про PTOC DMA и прочих страшных словах для меня. Простите, запуск второго ядра для вас даже проще, чем запуск ОСРВ? Чудеса! На самом деле ОСРВ не так страшна, как кажется. А освоить её всё равно когда-то придётся. Это очень удобный инструмент, без которого решение множества задач программирования встраиваемых систем превращается в мучение. И нередко это мучение выливается в написание нечто подобного ОСРВ, только в своём варианте и с немалым количеством ошибок. 12 hours ago, jcxz said: PPS: Не понимаю - откуда такая боязнь РТОС у множества здешних писателей? Возможно, для некоторых ОСРВ === windows на однокристалке. 11 hours ago, Lelikk said: RTOS надо использовать когда есть много разных задач, Много, это сколько? Я считаю, что две задачи уже достаточны для применения ОСРВ. 11 hours ago, Lelikk said: в остальных случаях она только мешает выживать скорость из аппаратуры Это голословное утверждение. Вы никогда не применяли ОСРВ. А я применяю. С 2006 года) 11 hours ago, Lelikk said: так то можно хоть .NET Micro прикрутить, потом поставить MCU помощнее : Какой "НЭТ Микро"??? Посмотрите на TNKernel, scmRTOS, FreeRTOS (она посложнее чуть, но запускается и на восьмибитках с 1 кб ОЗУ). 11 hours ago, Lelikk said: Если нужно просто в background несколько задач обслужить, то невытесняющий автомат запускающий список задач с разными периодами занимает максимум 100 строк. Использовать RTOS не потому что без нее нельзя, а потому что в остальном лень разбираться - это путь в никуда. Осталось только найти хорошо оттестированный код такого автомата из 100 строк? Ссылочку на гитхаб дадите?) И потом, почему вы говорите о кооперативной многозадачности (невытесняющей)? 11 hours ago, Lelikk said: Никто вашу задачу решать не будет, пока вы решите заплатить нормальные деньги. А вы, похоже, ещё и вредные советы даёте, пока вам деньги не заплатят))) В стиле: никакой ОСРВ. Хотя применеие ОСРВ даёт проекту неоспаримые преимущества. И самое главное из них, ИМХО, это задел на расширение. Захотите вы завтра добавить десять задач, вы их добавите. Расставите приоритеты. Наведёте межпроцессное взаимодействие. И всё будет работать, если для решения данных задач достаточно производительности микроконтроллера и у него есть необходимая периферия. При этом расходы на стэк (каждой задаче он нужен) будут самой меньшей головной болью по сравнению с решением передачи управления "невытесняющим автоматом из 100 строк". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться