Jump to content

    

pokk

Участник
  • Content Count

    191
  • Joined

  • Last visited

Community Reputation

0 Обычный

About pokk

  • Rank
    Частый гость

Recent Profile Visitors

2443 profile views
  1. Что-то похожее пытался сделать, но тут же сразу возникла проблема Дело в том что у меня модуль АЦП выдает 2 ввида среднего значение по работа введется по нему. 1) Большое количество отсчетов (за 200ms) , для отображение параметра на экране 2) Парочку значений , для зашиты. Так вот что бы запустить функцию Protect она должна быть внутри функции GetDataFromAdc.
  2. Да именно так, это я и назвал смешивание логики работы. Примерно так, и есть и вот их хочу разделить на 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 по выводам которые требуют обработку.
  3. Подскажите как правильнее сделать взаимодействие двух модулей. Первый модуль (ShareParam) считывает значения с АПЦ, суммирует их и пересчитывает в реальные значения параметра в общем на выходе получаем глобальную структуру к которой имеет доступ любой модуль (экран, web … ). Второй модуль эта защита , он должен брать реальные значения(пересчитанные значения) из первого модуля, сравнивать с пороговыми значениями параметра и делать действия (выключать, блокировать...) Вижу два взаимодействие между ними: Первый вариант это из модуля ShareParam выходит сигнал готовности данных, а во втором модуле находиться задача которая ожидает этот сигнал и по нему включает проверку параметра. В принципе мне такое взаимодействие нравиться тем, что модуль ShareParam, развязан и может работать независимо есть ли второй модуль или нет. Но в данном варианте не нравиться: 1) То что используется лишняя задача в модуле защите, так как можно обойти без неё. 2) То что будет достаточно частое, отправлять сигнала готовности т.е частое переключение контента. Второй вариант это в модуле защиты написать функцию, и её вызывать в модуле ShareParam, это исключает все недостатки первого варианта, но логически модули становятся смешанными друг с другом и модуль ShareParam не сможет работать, без модуля защиты. У меня частично старые проекты написаны по второму варианту, и очень раздражает когда ты подключаешь всего один модуль (переносишь в новый проект), а он тянет за собой другой а тот, что-то ещё и ещё и так пока весь проект не перекопируешь. По этому хотелось бы сделать по первому варианту, можно ли как нибудь обойти его недостатки ?
  4. Ну вот же на первом шаге, конфликт возникает если клиента другой клиент перебьет, в момент модификации confing. Под клиентом я понимаю задачу клиент freertos. Да из задач, одна задача вызывается, когда пользователь физически кнопку ок нажал в меню, а вторая задача вызывается, когда прилетел WEB запрос. Но это так частный случай, пока интересуюсь как в общем это разрулить.
  5. И как это происходит в предложенно вами третьем варианте ?
  6. Ну вы же сами все правильно написали Именно из за этого и хочу их разделить.
  7. Для атомарного доступа к переменной confing В том то и дело клиентов несколько может быть и они все могут модифицировать confing
  8. Вообще то нет, это я описал функцию модификацию параметра на клиенте. Если флаг был сброшен, то модифицируем параметр, иначе ждем когда флаг сброситься.
  9. А можно по подробнее как это используеться? Если использовать в лоб то это как то так char volatile flag; void ModConfing(void){ //------------------------------------ while(1){ // ожидаем флаг if(flag==1){ break; }else{ taskYIELD(); } } //------------------------------------ //изменение конфигурации //------------------------------------ flag=0; } не вижу чем отличаеться от mutex, он даже проше. А в чем преимущество такого разделение ? Что задачи клиенты не будут подтупливать на момент записи ? Это да запись идет всем блоком, я про такой момент ModAndSaveConfing(VAR1,100); ModAndSaveConfing(VAR2,100); ModAndSaveConfing(VAR3,100); на такой случий надо отдельные функции модификации городить confing.var1=100; confing.var2=200; confing.var3=300; SaveConfing();
  10. Флаг занятости, это же mutex? А зачем выделять функцию записи в отдельную задачу?
  11. В том то и дело, что эти процессы не сильно то и повторяющиеся, их вызывает пользователь когда нажимает кнопки в меню и в web странице. По этому и решил сразу же в этих обработчиках сделать запись конфигурации в память(внешнуюю), а если все таки наложаться, то по семафором должно все разрулиться.
  12. Что бы корректно произошла модификация параметра, ведь его может модифицировать другая задача. Хотя да, для одного и того же параметра наврятли, но структура модифицировать из другой задачи точно может.
  13. Задача такая, есть несколько обработчиков вызываемые через FREERTOS из разных задач. В них должна происходить модификация параметра и запись всей структуру конфигурации в память. Из за того что обработчики вызываются из разных задач, что бы не было переключение контента при модификации параметра его надо заблокировать через mutext. Первое что приходит на ум в лоб xSemaphoreTake(xConfing,portMAX_DELAY); confing.var1=100; confingClcCrc(); SaveConfing(); xSemaphoreGive(xConfing); Но такой вариант не нравиться (загромождает логику). Потом подумал завернуть это все в функцию типа такого: SaveConfing(&confing.var1,100); В принципе, уже более понятно, но тут другая проблема вылезла, функций надо большое количество под каждый тип под массив, под одинарную переменную, а если надо записать больше 1 параметра в одном вызове ? Не гонять же всю структуру в память после каждого байт. В общем подскажите, как это делается что бы было удобно? Или набор функций каких используете ? Была мысль, что бы, передавать сохраняемые данные в одну задачу через очереди, а там производить, модификацию конфигурации + запись. Но отказался от такого нагромождения из за того что, очень малая вероятность, что два обработчика вызовутся одновременно.
  14. Все понял, да походу к данным проще добавить CRC, чем внутри записи его реализовывать А что тут находиться ? Как то тут много типов на увеличенный размер шифрованных данных. Нет нет, я про блок данных (конфигурации/журнала), допустим что было записано 5 аварий(разными блоками COBS) и теперь их надо прочитать, т.е с начала надо прочитать последнюю, аварию(блок COBS), и потом продолжить считать в глубь. И где производить сброс, что при следующий итерации считывание всех 5 аварий, надо считывать с начала, записи а не продолжать, считывать из глубины.