Перейти к содержанию
    

Взаимодействие двух модулей, task или include ?

Подскажите как правильнее сделать взаимодействие двух модулей.
Первый модуль (ShareParam) считывает значения с АПЦ, суммирует их и пересчитывает в реальные значения параметра в общем на выходе получаем глобальную структуру к которой имеет доступ любой модуль (экран, web … ).
Второй модуль эта защита , он должен брать реальные значения(пересчитанные значения) из первого модуля, сравнивать с пороговыми значениями параметра и делать действия (выключать, блокировать...)
Вижу два взаимодействие между ними:
Первый вариант это из модуля ShareParam выходит сигнал готовности данных, а во втором модуле находиться задача которая ожидает этот сигнал и по нему включает проверку параметра. В принципе мне такое взаимодействие нравиться тем, что модуль ShareParam, развязан и может работать независимо есть ли второй модуль или нет.  
Но в данном варианте не нравиться:
1) То что используется лишняя задача в модуле защите, так как можно обойти без неё.  
2) То что будет достаточно частое, отправлять сигнала готовности т.е частое переключение контента.
 
Второй вариант это в модуле защиты написать функцию, и её вызывать в модуле ShareParam, это исключает  все недостатки первого варианта, но логически модули становятся смешанными друг с другом и модуль ShareParam не сможет работать, без модуля защиты.
У меня частично старые проекты написаны по второму варианту, и очень раздражает когда ты подключаешь всего один модуль (переносишь в новый проект), а он тянет за собой другой а тот, что-то ещё и ещё и так пока весь проект  не перекопируешь.
По этому хотелось бы сделать по первому варианту,  можно ли как нибудь обойти его  недостатки ?

 

Изменено пользователем pokk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, pokk said:

По этому хотелось бы сделать по первому варианту,  можно ли как нибудь обойти его  недостатки ?

Не знаю, какая у вас вычислительная платформа. Но если это микроконтроллер, то можно задействовать программный вызов прерывания по готовности данных. И у вас:

1. Не будет лишней задачи.

2. Контекст по выходу из прерывания будет переключаться только по мере необходимости если значение параметров вышло из ОБР (область безопасной работы).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

25 minutes ago, haker_fox said:

Не знаю, какая у вас вычислительная платформа

Stm32+FreeRTOS

24 minutes ago, haker_fox said:

Контекст по выходу из прерывания будет переключаться только по мере необходимости если значение параметров вышло из ОБР (область безопасной работы).

Можно  подробнее про это.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 minutes ago, pokk said:

Stm32+FreeRTOS

Stm32 Cortex-M какой?)

17 minutes ago, pokk said:

Можно  подробнее про это.

Вы вызываете программно любое свободное прерывание. Вектор может принадлежать и какой-либо периферии. Но эта периферия не используется, либо не использует вектор. В контроллере прерываний (NVIC) вы настраиваете прерывание как и для обычной периферии, но активироать его будете программно, используя функцию NVIC_SetPengingIRQ либо свою. Неважно. Главное, она должна устанавливать соответстующий бит (номер совпадает с номером вектора) в единицу в регистре ISPR. После этого процессор прерывает текущий процесс и входит в ваш обработчик. Там вы проверяете свои параметры, и если они не выходят за границу, то просто выходите из прерывания и возращаетесь к перванному процессу (любому). Если параметры плохие, то вы сигнализируете задаче, которая это разрулит. Сигнализируете семафором или, что лучше, сервисом Task Notify (см. примеры на сайте и обратите внимание на макрос portYIELD_FROM_ISR, именно он "говорит" о необходимости перепланировки по выходу из прерывания). А вот в этом случа уже может потребоваться переключение контекста, но в том случае, если есть задача, готовая к исполнению с приоритетом выше прерванной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

26.08.2020 в 12:04, pokk сказал:

Второй вариант это в модуле защиты написать функцию, и её вызывать в модуле ShareParam, это исключает  все недостатки первого варианта, но логически модули становятся смешанными друг с другом и модуль ShareParam не сможет работать, без модуля защиты.

а если закомментировать вызов этой функции, то модуль ShareParam не сможет работать без модуля защиты? Что-то с каркасом не так.

Цитата

2) То что будет достаточно частое, отправлять сигнала готовности т.е частое переключение контента.

на сколько я понял, у вас два последовательный действия:

1) вычитка с ацп

2) проверка данных (модуль защиты).

зачем их параллелить в 2 задачи?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 10/2/2020 at 3:20 PM, juvf said:

а если закомментировать вызов этой функции, то модуль ShareParam не сможет работать без модуля защиты? Что-то с каркасом не так.

Да именно так, это я и назвал смешивание  логики работы.

On 10/2/2020 at 3:20 PM, juvf said:

на сколько я понял, у вас два последовательный действия:

1) вычитка с ацп

2) проверка данных (модуль защиты).

зачем их параллелить в 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 по выводам которые требуют обработку.

Изменено пользователем pokk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

или вы задачу не правильно формулируете.... или ....

Если не нужно выполнять два действия "параллельно", то зачем 2 задачи? У вас действия выполняются последовательно. Для того, что бы модули были независимы, не нужно разносить их в отдельные задачи, нужно их сделать независимыми. Например... первый модуль в ShareParam .h

void getDataFromAdc(void *data) {.....};

второй модуль Protection.h

void protection(void *data) {....};

Вот вам два абсолютно независимых модуля. Нет ни какого смешения логики. Оба модуля абсолютно абстрагированы др от др.

 

Теперь задача mainTask.c

#include "ShareParam.h"
#include "Protection.h"
  
void mainTask(void *context)
{

  uint8_t data[128];
  for(;;)
  {
  	getDataFromAdc(data);
  	pronection(data);
  	delayMs(10);
  }

}


 

оба модуля работают совершенно независимо и последовательно. Если нужно собрать без защиты, просто закомментировать функцию protection() и #include "Protection.h" в задаче.

Конечно, для практики с РТОС можно getDataFromAdc() вызывать в одной задаче, protection() вызывать в другой.... можно выделять память uint8_t data[128] в третей..... Можно и холоворд разбить на количество задач, равным кол-ву букв. Оверинженеринг.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то похожее пытался сделать, но тут же сразу возникла проблема
Дело в том что у меня модуль АЦП выдает 2 ввида среднего значение по  работа введется по нему.
1)    Большое количество отсчетов (за 200ms) , для отображение параметра на экране  
2)    Парочку значений ,  для зашиты.
 
Так вот что бы запустить функцию Protect  она должна быть внутри функции GetDataFromAdc.   

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно передать указатель на  Protect  в фунцию GetDataFromAdc, потом сможете любой Protect  подставить.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

23 часа назад, pokk сказал:

Что-то похожее пытался сделать, но тут же сразу возникла проблема
Дело в том что у меня модуль АЦП выдает 2 ввида среднего значение по  работа введется по нему.
1)    Большое количество отсчетов (за 200ms) , для отображение параметра на экране  
2)    Парочку значений ,  для зашиты.
 
Так вот что бы запустить функцию Protect  она должна быть внутри функции GetDataFromAdc.   

 

ShareParam .h

bool getDataFromAdc(void *data) {.....};

Protection.h

void protection(void *data) {....};

 mainTask.c

 

#include "ShareParam.h"
#include "Protection.h"
 
void mainTask(void *context)
{

  uint8_t data[128];
  for(;;)
  {
      if(getDataFromAdc(data));
          protection(data);
      delayMs(10);
  }

}


Это на вскидку.... можно void getDataFromAdc(void *data, bool *isNeedProtection = 0); Внутри getDataFromAdc, если isNeedProtection  != 0, то вернуть бул....  можно как antis

Даже если не нужна ртос и не нужно 2 задачи... то всё равно нужно отделять мух от котлет модули др от др.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...