pamięć współdzielona IPC czy POSIX ?

0

Planuję napisanie programu rysującego wykresy pod systemy linuksowe, który dane pobierał by z "pamięci współdzielonej". Pod windows jest choćby protokół DDE, w przypadku linuksa mam do wyboru IPC i POSIX. Troszkę już skrobałem kodu używając IPC, o POSIX'owej pamięci współdzielonej tylko czytałem.
Co wybrać ? Może jakieś biblioteki ?

Uprzedzając pytanai po co: Chcę napisać "programik" typu SCADA :)
Dlatego potrzebuję korzystać z pamięci współdzielonej. W programie rysującym wykres definiowało by się jakie zmienne i jakiego typu będą wyświetlane. Znając te zmienne program rysujący pobierał by je z pamięci współdzielonej. Natomiast zadaniem programu sterownika byłoby umieszczenie danych w zmienny w pamięci współdzielonej.

0

A nie da się bezpośrednio podpiąć komunikacji sterownik-scada?

0

Heh, właśnie nie chcę tego robić :) bo:
Wymieniam sterownik rozumiany jako urzadzenie elektroniczne to :

  1. Od nowa piszę program sterownika.
  2. Muszę przerobić programik scada.

Wykorzystująć pamięć dzieloną piszę tylko program sterownika.

0

o_O? Ale niby czemu? Przecież chodzi tylko o wykorzystanie jakiegoś protokołu. Załóżmy że to będzie jakaś komunikacja socketowa:

  • scada nasłuchuje na sockecie i odpowiada na rządania sterownika
  • scada wysyła na podłączonego klienta rządania od operatora
    Nie rozumiem czemu zmiana sterownika miałaby powodować konieczność zmiany scady. Jeśli sterownik będzie komunikował się zgodnie z protokołem to scada nie zauważy różnicy.
    Zadaj sobie inne pytania:
  • czy to ma być komunikacja synchroniczna czy asynchroniczna?
  • czy ma być niezawodna czy też nie?
  • jakie są oczekiwane czasy reakcji?
    Linux udostępnia kupę mechanizmów komunikacji -> sygnały, sockety, kolejki komunikatów, pamięć współdzielona etc
0

Jednak mogłem zacząć od założeń.
Sterownik dane pobrane z przetworników przekazuje do komputera poprzez któryś z interfejsów (RS-232, Ethernet, USB, ...) w celu wizualizacji ich na ekranie komputera.

Ty zakładasz, że sposobem komunikacji pomiędzy programem sterownika, a scadą będzię gniazdo, a ja pamięć współdzielona. Przy takim podejściu do tematu zmaina scady nie jest potrzebna !

Zadaj sobie inne pytania:

  • czy to ma być komunikacja synchroniczna czy asynchroniczna?
  • czy ma być niezawodna czy też nie?
  • jakie są oczekiwane czasy reakcji?
  • oczywiście komunikacja asynchroniczna
  • ma być niezawodna. Pewnie do komunikacji sterownika z programem sterownika wykorzystam Modbus
  • na razie nie :)

Tak wykorzystać protokół, ale jaki ? Ja nie znam pod linuksem gotowca, pod windows jest choćby DDE. Akurat InTouch korzysta z DDE.

0

Ja bym użył tutaj kolejki komunikatów. Jeśli potrzebujesz przykładów komunikacji w unixie to zaopatrz się w książkę pana Stevensa: http://www.kohala.com/start/apue.html

0

Faktycznie po analizie skorzystam z kolejki, nie ma sensu pisać własnego kodu odpowiedzialnego za działanie kolejki w pamięci współdzielonej.
Zatanawiam się nadal, którego typu wybrać IPC, czy POSIX ? Z tego co przeczytałem kolejka POSIX ma możliwość automatycznego wysłania sygnału, że kolejka nie jest pusta.

Ogólna moja koncepcja rozwiązania jest taka:

  1. Stworzenie tablicy w pamięci współdzielonej, która przechowuje: nazwę zmiennej, wartość zmiennej, oczywiście z typem zmiennej oraz czy jest do zapisu/odczytu, ewentualnie jakiś dodatkowy parametr.

  2. Utworzenie kolejki przechowują nazwy zmiennych, których wartość się zmieniła.

Program sterownika odpowiada, za ustawienie w tablicy nazw zmiennych, typu, wartości zmiennej, flag dostępu. Kiedy zmienna zostanie zaktualizowana zostaje dodana do kloejki komunikatów.
Program typu scada odbiera nazwę/y zmiennych z kolejki, pobiera dane z tablicy określone przez nazwe zmienej po czym usuwa ją z kolejki.

Jak to widzisz ?

0

przegapiłem coś o pamięci? czy może używamy różnych słów?

0

@Badmaneq w zasadzie możesz tak zrobić, ale pytanie brzmi: po co ta pamięć współdzielona? Nie da się tak zrobić żeby sterownik wysłał przy "logowaniu" do scady informacje o potencjalnych zmiennych?

0

Chcę zrobić "coś" ogólnego do rysowania wykresów ( może i nie tylko) :) Nie chcę mi się za każdym razem pisać od nowa programu do wizualizacji danych z moich projektów elektronicznych.
Może mi się uda napisać program do projektowania wizualizacji, ala designer GUI Glade, gdzie jego kontrolki będą powiązane ze zmiennymi w pamięci współdzielonej...

0

Tak się zastanawiam - co będzie wpychało dane do kolejki/pamięci współdzielonej? Nie spotkałem się ze sterownikiem, który udostępnia mechanizmy IPC czy POSIX.

Propozycja:

  • jeden program - zmieniając kontrolki w SCADzie lub komunikacje trzeba jakiś program kompilować
  • dwa wątki - 1. komunikacja z PLC 2. wizualizacja

przy tworzeniu klasy z wątkiem odpowiedzialnym za komunikacje można skorzystać z funkcji wirtualnych by stworzyć sobie interfejs typu virtualCom.podajWartoscX() i w ten sposób zapewnić sobie możliwość wymiany sterownika jak się znudzi (zawsze jakiś programik/cześć programu do komunikacji PC-PLC trzeba będzie wykroić)

0

Jeśli chodzi wyłącznie o zbieranie danych na wykresy czyli cykliczne odczytywanie tych samych parametrów to faktycznie asynchronicznie współdzielona pamięć i hardkodowne offsety zmiennych będą prostszym rozwiązaniem, nie trzeba robić całego "protokołu". Ale miej na uwadze, że możliwości takiej pamięci są ograniczone. Jeśli w przyszłości by chcieć wydawać sterownikowi polecenia lub "czatować" na zmianę jakiegoś parametru to trzeba sięgnąć po komunikację synchroniczną. Pamięć współdzielona to raczej do przekazywania całych wektorów/macierzy danych.

0

Tak się zastanawiam - co będzie wpychało dane do kolejki/pamięci współdzielonej? Nie spotkałem się ze sterownikiem, który udostępnia mechanizmy IPC czy POSIX.

Program sterownika będzie wysyłał. Wstępnie będzię to na łapu capu, docelowo funkcję wysyłające będą opakowane bibliotekę, żeby przyjemnie się pisało nowy program sterownika.

Jeśli w przyszłości by chcieć wydawać sterownikowi polecenia lub "czatować" na zmianę jakiegoś parametru to trzeba sięgnąć po komunikację synchroniczną.

Masz na myśli semafory, mutex'y ?

0

Mam na myśli komunikację synchroniczną czyli co tam sobie nie zamarzysz, byle pogaduszki między sterownikiem a klientem były synchronizowane jak się to dzieje np. w przypadku komunikatów.

0

Sychronizowane jak ? W przestrzeni użytkownika, czy jądra ?

0

Nie wskazuję żadnego konkretnego mechanizmu synchronizacji. Chodzi mi o samą jej potrzebę. Jak np. wydasz sterownikowi dwa polecenia to muszą one dotrzeć do sterownika i to w prawidłowej kolejności. Czy też jeśli chcesz wydać polecenie i poczekać na odpowiedź - to są zadania synchronizacji. Wybór mechanizmu to odrębna sprawa, kolejka komunikatów wydaje się być odpowiednia.

0

Fajnie już działa :), kiedy zmienna zostanie zaktualizowana pojawai się kolejce (posix) po czym program klienta pobiera jej nazwę z kolejki. Następnie identyfikuje pozycję w tablicy pamięci współdzielonej na podstawie otrzymanego łańcucha tekstowego z kolejki (kwestia identyfikacji po stringu jeszcze do przemyślenia - porównywanie stringów moim zdaniem jest dość kosztowne) i odczytuje z tej pozycji dane.

Doszło kolejne założenie: wiele programów ma dostawać informacje o aktualizacji zmiennej.
No i tu mam problem, bo mq_recive po pobraniu komunikatu z kolejki usuwa go. Na myśl przyszło mi utworzenie dodatkowego procesu, w którym będą się rejestrowały procesy chcące otrzymywać komunikaty z określonej kolejki. Proces ten odbiera komunikat po czym wysyła do zajestrowanych procesów sygnał np. SIGUSR1.

Czy to dobre rozwiązanie ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1