Jump to content

    

pokk

Участник
  • Content Count

    202
  • Joined

  • Last visited

Community Reputation

0 Обычный

About pokk

  • Rank
    Местный

Recent Profile Visitors

2798 profile views
  1. Да вот это и меня мучило, не хотел вводить ещё одни модуль, но по ходу без него не как Заведу модуль InitTask В си файле будет void WaitInitTask(uint16_t event) // WaitInitTask(WAIT_EVENT_INIT_MEM | WAIT_EVENT_INIT_LCD) xEventGroupWaitBits(xEventAnyName,event, 0, pdTRUE, portMAX_DELAY); } В H файле #define WAIT_EVENT_INIT_MEM (1<<0) #define WAIT_EVENT_INIT_LCD (1<<1) Он будет иклудиться практически во все задачи. Надеюсь 8-16 бит хватит.
  2. Как правильно заблокировать задачу. Есть vTaskMenu, она с определенным интервалом запускает функции из модуля LCD на перерисовку экрана с учетом как было сконфигурировано устройство (данные во внешнем ПЗУ модуль mem) поэтому в момент включения устройства ставлю ожидание, на инициализации LCD и mem (MemWaitInitLcd() и WaitInitMem() находяться в соответственных модулях (LCD и Mem).) void vTaskMenu (void *pvParameters){ WaitInitLcd(); WaitInitMem(); xEventGroupSetBits(xEventMenuStart,WAIT_EVENT_INIT_MENU); while(1){ MsgDisplayUpdate((uint8_t*)LcdMsgShow.msg,TEXT_NORMAL); vTaskDelay( LcdMsgShow.time/ portTICK_RATE_MS ); } void WaitInitLcd(void){ xEventGroupSync(xCreatedEventLcdInit,0,WAIT_EVENT_INIT_LCD,portMAX_DELAY); } void WaitInitMem(void){ xEventGroupSync(xCreatedEventGroup,0,WAIT_EVENT_INIT_MEMORY,portMAX_DELAY); } Так вот проблема возникла, когда я случайно поменял местами WaitInitMem(); WaitInitLcd(); получилось из за того что WaitInitMem(); инициализируеться гораздо дольше за это время задача инициализации LCD уже отрабатывает и выставляет xEventGroupSetBits(xCreatedEventLcdInit,WAIT_EVENT_INIT_LCD); и после отработки WaitInitMem программа зависает на WaitInitLcd(); Знаю, что можно xEventGroupSync поставить ждать несколько флагов Но как это сделать в рамках трех модулей menu LCD и mem ? Где создать общую переменную xCreatedEvent.... (для всех задач ?)
  3. В даташите написано, что максимальный уровень выходного сигнала с ЦАП равен 5.6 В (p-p). Хотя питание 5В, но да ладно. Настроил ЦАП на частоту дискретизации 190 кГц, 24 бита и выдаю с него пилу (0-0xFFFFFF) На осциллографе вижу пилу с 2.7 в (p-p), как выжать с него заданный диапазон до 5 в (p-p) ? Пробовал крутить уровень канала, через SPI уровень сигнала уменьшается, но не увеличивается.
  4. Это актуально когда, надо большой размер данных проигнорировать, пока таких задач нету, а если и будет то настрою DMA на прием из буфера wiznet без инкремента памяти процессора.
  5. Ну вот поменяли, W5300 подключается только по параллельной шине, по этому что бы не городить большое количество линий адреса, они сделал доступ к буферу RX/TX через небольшой буфер FIFO. И доступ к указателям убрали.
  6. Нет нет, вы не правильно меня поняли, я имел ввиду когда принимаешь поток данных, в протоколе может быть номер какой это поток данных, и что бы один поток от другого отфильтровать, можно принять сначала шапку, посмотреть на этот номер и дальше принять решения считывать данные или нет, в w5500 такое можно сделать, а вот в w5300 увы что бы заигнорить пакет его надо считать целиком.
  7. Вот это прямо то что надо!!, это одна из основных причин сделать все по уму. Я хотел заложить чуть другую логику, считывание самого пакета переложить на задачу A и B. Для того что бы в задаче A можно было считывать не весь пакет, а только шапку пакета, и если она битая (либо по адресу пакета если есть такой внутри протокола), то игнорировать пакет целиком не копируя его в процессор, но по факту я таким пользовался только раз. И походу именно это не дает сделать универсально и разделить, работу через буфер. На передачу, все так же складываем в буфер и передает сигнал из задачи А в задачу О ?
  8. А если одна задача ждет одно событие (прием пакета), из разных сокетах, что бы при одновременно срабатывании прерывании можно было установить приоритет какой сокет первый обрабатывать.
  9. juvf, хорошая идея, по прерыванию запускать задачу обработки прерываний, а из неё уже передавать события в задачу обработки пакета сокетом. А как сделать так что бы в задача ждала одно событие из нескольких сокетах, типа ожидает событие "прием пакета" либо со второго сокета или с первого. В задаче обработке прерываний думаю сгруппировать событие следующим образом. Создать битовые группы на каждое событие свое, а внутри каждый бит будет указывать какой сокет вызвал это событие. Тогда я смогу, в udp server ждать прием с любых сокетов (2,3 или 6) и с заданным приоритетом вызвать задачу обработчика пакета данных. Только для TCP приодеться, много групп городить.
  10. Что-то не припомню можно ли так сделать в STM32, завтра гляну. Главный вопрос как с этим дальше работать. То ли в очередь сразу байт с набором событий записывать, то ли разобрать все биты из байта и их в очередь записывать. Либо вообще передавать только факт того что произошло прерывание (через xEventGroupSetBits), и уже на месте вычитывать из байт с событиями и принимать решения. В последний варианте конечно, будет происходить активация задачи даже не по своему что не очень нравиться.
  11. Добрый день, пишу модуль UDP сервера для wiznet 5300 подключенный по параллельной шине. Столкнулся с такой проблемой, при роботе с ним по выводу прерывании INT, процессор может потерять событие, принятие пакета сокетом. У w5300 есть 8 сокетов и если сокет принимает пакет UDP то выставляется логический уровень (1) на вывод прерывания (INT) и записывает событие в регистр прерываний сокета, так вот если во время прерывания wiznet примет пакет в другой сокет вывод INT так и будет находиться в единице, без переключения 1/0/1 и тем самым процессор может пропустить этот сигнал если он работает по прерыванию вывода INT, хотя в регистре прерывания другого сокета будет стоять бит приема. Но все же для максимальной реакции (в будущем планирую принимать UDP поток данных) приема UDP пакета, хочу заложить работу по прерыванию + периодический опрос размера данных в сокете. Модуль сервера UDP хочу заложить таким образом: 1) Есть основная задача (FreeRTOS), которая периодически проверяет размер данных в сокетах, именно в нескольких (которые настроены в режиме UDP), и если в каком из сокетов появились данные, то запускаем отдельную задачу на обработку этого пакета. Таким образом обработка пакетов на разных сокетах происходит независимо друг от друга. Для того что бы ожидать прерывание wiznet, на нескольких сокетах, решил в обработке прерывания их складывать с одну очередь а в главной задаче считывать эту очередь, а по таймауту производить опрос количество данных в сокете. Для, одного событие (приема), это логика заработало, но как добавилось событие (передача завершена), тут застрял. Уже думаю, в прерывании от wiznet, разбирать регистр прерываний wiznet на события и записывать их в разные очереди, но если взять TCP сокет там событий много.. каша, получиться. В общем как правильно обработать прерывание INT от wiznet и выдать сигналы на продолжение работы задачам, в разных режимах TCP, UDP . Главная задача получилась такая Обработка прерывания вышла так
  12. Что-то похожее пытался сделать, но тут же сразу возникла проблема Дело в том что у меня модуль АЦП выдает 2 ввида среднего значение по работа введется по нему. 1) Большое количество отсчетов (за 200ms) , для отображение параметра на экране 2) Парочку значений , для зашиты. Так вот что бы запустить функцию Protect она должна быть внутри функции GetDataFromAdc.
  13. Да именно так, это я и назвал смешивание логики работы. Примерно так, и есть и вот их хочу разделить на 2 независимых модуля, по крайне мере что бы первый работал независимо, есть модуль защиты или нет, АЦП же все равно. Для этого и хотел модуль защиты сделать в в виде отдельной задачи. На данный момент переработал, логику работы этих двух модулей и сделал следующее, создал структуру параметра такую: typedef __packed struct{ int32_t adc; //Текушее значение АЦП с учетом компенсации нуля !! uint32_t RealAdc; //Текушее значение АЦП без компенсации !! ParamMem_t mem; ParamCallback_t callback; ParamDec_t dec; uint8_t TypeParam; uint8_t NumInAdc; // физически номер канала АЦП Limit_t lim; uint8_t status; }ParamValue_t; И с выхода модуля ShareParam получаем: 1) Каждый параметр содержит свой АЦП 2) Расчитанно десятичное значение параметра в вольтах амперах ваттах, на основе коэфициента считанного из памяти в структуру mem (по включению). 2) Расчитанный статус параметра на основе, его порогов. 3) В случае перехода статуса параметра (нормы -> аварию, авария->норма) вызывает соответственный callback, который и находиться модуле защиты. И модуль защиты получился чисто из функций инициализации Callback параметров и самих Callback по требуемым параметрам + прерывание INT по выводам которые требуют обработку.
  14. Подскажите как правильнее сделать взаимодействие двух модулей. Первый модуль (ShareParam) считывает значения с АПЦ, суммирует их и пересчитывает в реальные значения параметра в общем на выходе получаем глобальную структуру к которой имеет доступ любой модуль (экран, web … ). Второй модуль эта защита , он должен брать реальные значения(пересчитанные значения) из первого модуля, сравнивать с пороговыми значениями параметра и делать действия (выключать, блокировать...) Вижу два взаимодействие между ними: Первый вариант это из модуля ShareParam выходит сигнал готовности данных, а во втором модуле находиться задача которая ожидает этот сигнал и по нему включает проверку параметра. В принципе мне такое взаимодействие нравиться тем, что модуль ShareParam, развязан и может работать независимо есть ли второй модуль или нет. Но в данном варианте не нравиться: 1) То что используется лишняя задача в модуле защите, так как можно обойти без неё. 2) То что будет достаточно частое, отправлять сигнала готовности т.е частое переключение контента. Второй вариант это в модуле защиты написать функцию, и её вызывать в модуле ShareParam, это исключает все недостатки первого варианта, но логически модули становятся смешанными друг с другом и модуль ShareParam не сможет работать, без модуля защиты. У меня частично старые проекты написаны по второму варианту, и очень раздражает когда ты подключаешь всего один модуль (переносишь в новый проект), а он тянет за собой другой а тот, что-то ещё и ещё и так пока весь проект не перекопируешь. По этому хотелось бы сделать по первому варианту, можно ли как нибудь обойти его недостатки ?