Âñòóï
Ô³ðìà
ICP_DAS äîñòàòíüî äàâíî âèïóñêຠêîíòðîëåðè íà ïðîöåñîðàõ ARM àðõ³òåêòóðè ç ïåðåäâñòàíîâëåíèì îòî÷åííÿì ÎÑ Linux, ùî ðîáèòü ö³êàâèì ñòâîðåííÿ çá³ðêè OpenSCADA àáî íîâî¿ ïðîøèâêè ç OpenSCADA.
Äî îñòàííüîãî ÷àñó íèçêà ïðè÷èí ñòàâàëè íà ïåðåïîí³ çá³ðêè OpenSCADA äëÿ ARM-êîíòðîëåð³â ICP DAS:
- â³äñóòí³ñòü íà ðóêàõ æîäíîãî ³ç ARM-êîíòðîëåð³â;
- íåãîòîâí³ñòü OpenSCADA äëÿ ðîáîòè íà ARM-àðõ³òåêòóð³;
- äóæå çàñòàð³ëå îòî÷åííÿ Linux ARM-êîíòðîëåð³â ô³ðìè "ICP DAS".
Íà öåé ÷àñ âñ³ ö³ ïåðåïîíè áóëî óñóíåíî. Òàê, çàâäÿêè Ïåòðó ˳òêîâöþ íà ðóêàõ ç'ÿâèâñÿ êîíòðîëåð LP-5141, à äî öüîãî ÷àñó OpenSCADA ó çíà÷í³é ì³ð³ áóëî âæå àäàïòîâàíî äî ðîáîòè íà ARM-àðõ³òåêòóð³, çà ïîñåðåäíèöòâîì â³äïðàöþâàííÿ òà ñòàá³ë³çàö³¿ íà äîëîííîìó êîìï'þòåð³ ô³ðìè
Nokia -
N800. Ó íàñë³äîê æå ðîáîòè ç êîíòðîëåðîì LP-5141 áóëî óñóíåíî îñòàííþ ïåðåïîíó øëÿõîì îíîâëåííÿ ïî÷àòêîâîãî ïðîãðàìíîãî îòî÷åííÿ ³ç çáåðåæåííÿì ïîòî÷íîãî ôóíêö³îíàëó.
 ö³ëîìó, ìåòîþ äàíîãî ïðîåêòó º â³äïðàöþâàííÿ ìåõàí³çì³â òà ñòâîðåííÿ çá³ðêè OpenSCADA äëÿ êîíòðîëåð³â ñ³ìåéñòâà ARM ô³ðìè "ICP DAS", à òàêîæ ñòâîðåííÿ ïðîøèâîê ï³ä êîíòðîëåðè "ICP DAS", ÿê³ ïîòðàïëÿòèìóòü äî ðóê ðîçðîáíèê³â OpenSCADA.
1. ÏËÊ LP-5141
ÏËÊ (ðèñ.1) êîíñòðóêòèâíî âèêîíàíî ó âèãëÿä³ ìîíîáëîêó, ÿêèé íå ì³ñòèòü âáóäîâàíîãî ÓÑÎ, îêð³ì ìîæëèâîñò³ âñòàíîâëåííÿ îäí³º¿ ñïåö³àëüíî¿ ïëàòè ðîçøèðåííÿ IO, à ï³äêëþ÷åííÿ çîâí³øíüîãî çä³éñíþºòüñÿ çà ïîñåðåäíèöòâîì âáóäîâàíîãî ³íòåðôåéñó RS-485, íàïðèêëàä, ó âèãëÿä³ ìîäóë³â ñå𳿠I-7000, ô³ðìè "ICP DAS".

Ðèñ. 1. ÏËÊ ñå𳿠LP-5xxx.
Ïðîöåñîð êîíòðîëåðó ìຠíàñòóïí³ òåõí³÷í³ õàðàêòåðèñòèêè:
CPU | PXA270 àáî ñóì³ñíèé (32-á³ò òà 520ÌÃö) |
SDRAM | 128 MB |
Flash | 64 MB |
EEPROM | 16 KB
Çáåð³ãàííÿ äàíèõ: 40 ðîê³â; 1,000,000 öèêë³â âèäàëåííÿ/çàïèñó. |
Ðîçøèðåíà Flash ïàì'ÿòü | microSD ñîêåò ç îäí³ºþ microSD êàðòîþ íà 2GB (ìîæå ï³äòðèìóâàòè 16 GB microSDHC êàðòêè) |
64-á³ò Ñåð³éíèé Íîìåð Îáëàäíàííÿ | Íàÿâíèé |
Ïîäâ³éíèé Watchdog òàéìåð | Íàÿâíèé |
VGA | 800 × 600 |
Ethernet ïîðòè | RJ-45 x 2, 10/100 Base-TX Ethernet Êîíòðîëåð (Àâòî-óçãîäæåííÿ, àâòî MDI/MDI-X, LED ³íäèêàòîð) |
USB 1.1 (õîñò) | 1 |
COM1 (/dev/ttySA0) | RS-232 (RxD, TxD and GND); Íå ³çîëüîâàíî |
COM2 (/dev/ttySA1) | RS-485 (D2+,D2-); 2500 VDC; ²çîëüîâàíî |
COM3 (/dev/ttySA3) | RS-232 (RxD, TxD and GND); Íå ³çîëüîâàíî |
Ðîáî÷à òåìïåðàòóðà | -25 ~ +75 °C |
2. Ïðîãðàìíå îòî÷åííÿ íà îñíîâ³ OpenSCADA.
Ïðîãðàìíå îòî÷åííÿ, îñíîâàíå íà ÎÑ Linux, äëÿ ARM êîíòðîëåð³â ô³ðìè ICP DAS çà çâè÷àé ìàþòü: ÿäðî Linux 2.6.19, GLibC 2.2.5 òà GCC 2.95. Äëÿ çá³ðêè ñòîðîííüîãî ÏÇ ô³ðìîþ ICP-DAS íàäàºòüñÿ SDK ç êðîñêîìï³ëÿòîðîì, íàáîðîì á³áë³îòåê òà çàãîëîâê³â äî íèõ (Linux toolchain). ßê ìîæíà áà÷èòè, âåðñ³¿ GLibC òà GCC äóæå ñòàð³, à ñàìå 2001 ðîêó. Çá³ðêà OpenSCADA ó òàêîìó îòî÷åí³ ôàêòè÷íî íåìîæëèâà. ßêùî âèêîðèñòàííÿ GLibC âåðñ³¿ 2.2.5 ùå ìîæëèâå, òî GCC âåðñ³¿ 2.95 ìຠC++ êîìï³ëÿòîð, ÿêèé íà çá³ðö³ êîäó OpenSCADA ïðîñòî ðóøèòüñÿ, à ñòàíäàðòíà á³áë³îòåêà C++ àáî STL äóæå îáìåæåíà òà ï³ä íå¿ ïîòð³áíà çíà÷íà ³ ãîëîâíå áåçãëóçäà àäàïòàö³ÿ. Ç ö³º¿ ïðè÷èíè ïîòð³áíå áóëî îíîâëåííÿ ïåðâèííîãî ïðîãðàìíîãî îòî÷åííÿ äî âåðñ³¿ GCC êîìï³ëÿòîðó, àáî á³áë³îòåêè C++, íå ìåíø 3.
Îñê³ëüêè âíóòð³øíÿ ôëåø-ïàì'ÿòü ìຠïîð³âíÿíî íåâåëèêèé îá'ºì (64 Ìá), à ïîâíà ïåðåçá³ðêà ïî÷àòêîâîãî ïðîãðàìíîãî îòî÷åííÿ êîíòðîëåðà — äîñòàòíüî òðóäîì³ñòêèé ïðîöåñ, òî áóëî âèð³øåíî çàáåçïå÷èòè ñóì³ñí³ñòü áàçîâèõ á³áë³îòåê íîâîãî òà ñòàðîãî îòî÷åííÿ. À ñàìå, ìîæëèâ³ñòü âèêîðèñòîâóâàòè á³áë³îòåêè íà çðàçîê fontconfig, i8k ç ïåðâèííîãî îòî÷åííÿ òà ðîáîòó ïðîãðàì ïåðâèííîãî îòî÷åííÿ ç íîâèìè á³áë³îòåêàìè.
Ó ïðîöåñ³ ï³äáîðó íîâîãî ïðîãðàìíîãî îòî÷åííÿ äëÿ ïðîöåñîðó PXA-270 êîíòðîëåðà "ICP DAS" áóëî àïðîáîâàíî äåê³ëüêà âàð³àíò³â, îñê³ëüêè ÷àñòèíà ç íèõ ìàëà ò³ àáî ³íø³ íåäîë³êè:
-
crosstool-0.43 — ö³êàâèé õî÷à ³ çàñòàð³ëèé ïðîåêò (îñòàííÿ âåðñ³ÿ 2006 ðîêó) ïî çá³ðö³ Linux êðîñîòî÷åííÿ ï³ä ïîòð³áíå îáëàäíàííÿ. Áóëî â³äêëàäåíî ï³ñëÿ äåê³ëüêîõ íåâäàëèõ ñïðîá ç³áðàòè íîâå îòî÷åííÿ äëÿ ðîáîòè ç "Software FP" òà "VFP". ßê íàäàë³ âèÿâèëîñÿ äëÿ îá'ºêòíèõ ôàéë³â ïîïåðåäíüîãî îòî÷åííÿ íåêîðåêòíî â³äîáðàæàºòüñÿ ³íôîðìàö³ÿ ïðî íà÷åáòî íàÿâí³ñòü òàì "Software FP" òà "VFP", õî÷à íàñïðàâä³ îïåðàö³¿ ç ðåàëüíèìè ÷èñëàìè òàì â³äáóâàþòüñÿ çà ïîñåðåäíèöòâîì "FPA". Íà ïðîòÿç³ âèð³øåííÿ ïðîáëåìè, îïèñàííî¿ ó ðàçä³ë³ "Çàóâàæåííÿ", çà äîïîìîãîþ öüîãî ³íñòðóìåíòó áóëî ç³áðàíî ToolChain íà îñíîâ³ ïðîôèëþ "arm-xscale.dat" òà "gcc-4.0.2-glibc-2.3.6-tls.dat", ÿêèé ó ê³íöåâîìó ðàõóíêó áóëî ïîêëàäåíî ó îñíîâó íîâî¿ ïðîøèâêè.
-
PXA-Linux Project — ïðîåêò ïî ñòâîðåííþ íåçàëåæíîãî íàáîðó ³íñòðóìåíò³â Linux äëÿ çá³ðêè ï³ä ïðîöåñîð PXA. Ìຠá³íàðíó çá³ðêó
02-25-2005/bin/arm-linux-toolchain-bin-12-15-04-driscoll.tar.gz. Âèÿâèëîñÿ, ùî öþ çá³ðêó ç³áðàíî ³ç "Software FP" òà "VFP", à òàêîæ íàÿâíî ïðîáëåìè ó âèãëÿä³ âèêëþ÷åííÿ íèçêè ðîçøèðåíü êîìï³ëÿòîðó gcc, íàïðèêëàä: __attribute__((packed)).
-
Voipac — á³íàðíà çá³ðêà ³íñòðóìåíò³â êðîñêîìï³ëÿö³¿ (
arm-linux-gcc-3.4.1.tar.gz) â³ä ô³ðìè "Voipac" äëÿ âëàñíîãî îáëàäíàííÿ íà ïðîöåñîð³ PXA-270. Öåé ToolChain áóëî ç³áðàíî çà äîïîìîãîþ ðàí³ø ðîçãëÿíóòîãî
crosstool.
Çá³ðêà OpenSCADA ç âèêîðèñòàííÿì êðîññêîìï³ëÿòîðó çä³éñíþºòüñÿ íàñòóïíèì ÷èíîì:
# Ðîçïàêóâàííÿ àðõ³âó ³íñòðóìåíòàð³þ
$ cd /opt
$ tar --lzma -xvf lincon.tlz
# ²í³ö³àë³çàö³ÿ îòî÷åííÿ çá³ðêè
$ . /opt/lincon/linpac_new.sh
# Ïåðåõ³ä äî äåðåâà âèõ³äíèõ òåêñò³â OpenSCADA, êîíô³ãóðàö³ÿ òà çá³ðêà
$ cd /opt/lincon/OpenSCADA
$ ./configure --host=arm-xscale-linux-gnu CXXFLAGS="-O2 -D_REENTRANT" CFLAGS="-O2 -D_REENTRANT" --disable-QTStarter --disable-QTCfg --disable-Vision --disable-MySQL --disable-FireBird --disable-PostgreSQL --disable-SoundCard --enable-ICP_DAS
$ make
Ðåçóëüòóþ÷å îòî÷åííÿ êîíòðîëåðó ç OpenSCADA áóëî ñôîðìîâàíî øëÿõîì çàì³íè áàçîâèõ á³áë³îòåê ïåðâèííîãî îòî÷åííÿ íà á³áë³îòåêè ç íîâîãî íàáîðó ³íñòðóìåíò³â, çá³ðêè OpenSCADA òà ðîçòàøóâàííÿ ôàéë³â OpenSCADA ó äåðåâ³ ïåðâèííîãî îòî÷åííÿ.
OpenSCADA áóëî ç³áðàíà ç âèêëþ÷åííÿì íèçêè á³áë³îòåê òà ìîäóë³â. Òàê, áóëè ç³áðàí³ òà ïåðåâ³ðåí³ ìîäóë³ òà ôóíêö³¿ OpenSCADA:
- ßäðî OpenSCADA — ç³áðàíî ³ç á³áë³îòåêîþ LibGD2 (ðîáîòó ïåðåâ³ðåíî). Ó ïðîöåñ³ ïåðåâ³ðêè òà àäàïòàö³¿ ðîçøèðåíî ôóíêö³¿ çáåð³ãàííÿ êîíô³ãóðàö³¿ OpenSCADA ó êîíô³ãóðàö³éíîìó ôàéë³.
- DB.SQLite — ÁÄ SQLite (ðîáîòó ïåðåâ³ðåíî). dzáðàíî á³áë³îòåêó òà ìîäóëü OpenSCADA äëÿ ðîáîòè ç ÁÄ SQLite. Ó ïðîöåñ³ ïåðåâ³ðêè âèÿâëåíî òà âèêîíàíî îáõ³ä ïîìèëêè ó GLibC 2.3.2, ÿêó ïîâ'ÿçàíî ³ç â³äñóòí³ñòþ ïåðåâ³ðêè íà âçàºìî-áëîêóâàííÿ "rw"-ðåñóðñ³â.
- DB.DBF — ÁÄ DBF (ðîáîòó ïåðåâ³ðåíî). Ìîäóëü ðîáîòè ç DBF-ôàéëàìè âåðñ³¿ 3.
- Transport.Sockets — Ìîäóëü òðàíñïîðòó Ñîêåò³â TCP, UDP òà Unix (ðîáîòó ïåðåâ³ðåíî). Ó ïðîöåñ³ âèêîðèñòàííÿ TCP-ñîêåò³â âèÿâëåíî òà óñóíåíî íå³í³ö³àë³çàö³þ ñòðóêòóðè ïåðåâ³ðêè ñòàíó ñîêåòó.
- Transport.SSL — Ìîäóëü òðàíñïîðòó áåçïå÷íèõ ñîêåò³â: SSL, TLS (ðîáîòó ïåðåâ³ðåíî).
- Transport.Serial — Ìîäóëü òðàíñïîðòó ïîñë³äîâíèõ ³íòåðôåéñ³â (ðîáîòó ïåðåâ³ðåíî). Âèÿâèëîñÿ, ùî COM3 ÷îìóñü ðîçòàøîâàíî íà ïðèñòðî¿ /dev/ttySA3.
- Protocol.SelfSystem — Ìîäóëü âëàñíîãî ïðîòîêîëó OpenSCADA (ðîáîòó ïåðåâ³ðåíî).
- Protocol.HTTP — Ìîäóëü ðåàë³çàö³¿ ïðîòîêîëó HTTP (ðîáîòó ïåðåâ³ðåíî).
- Protocol.ModBus — Ìîäóëü ðåàë³çàö³¿ ïðîòîêîëó ModBus (ðîáîòó ïåðåâ³ðåíî). Êîíô³ãóðàö³ÿ ñòàíö³¿ ÿê ñåðâåðó äàíèõ çà ïîñåðåäíèöòâîì ïðîòîêîëó ModBus.
- Protocol.OPC_UA — Ìîäóëü ðåàë³çàö³¿ ïðîòîêîëó OPC UA (ðîáîòó ïåðåâ³ðåíî). Êîíô³ãóðàö³ÿ ñòàíö³¿ ÿê ñåðâåðó äàíèõ çà ïîñåðåäíèöòâîì ïðîòîêîëó OPC UA. Âèÿâëåíî ïðîáëåìó ð³çíèö³ ïðåäñòàâëåííÿ ðåàëüíîãî íà x86 òà ARM FPA!
- Protocol.UserProtocol — Ìîäóëü â³ëüíî¿ ðåàë³çàö³¿ ïðîñòèõ ïðîòîêîë³â êîðèñòóâà÷åì, çà ïîñåðåäíèöòâîì ìîâè ïðîãðàìóâàííÿ OpenSCADA (ðîáîòó ïåðåâ³ðåíî).
- DAQ.System — Ìîäóëü äàíèõ îïåðàö³éíî¿ ñèñòåìè (ðîáîòó ïåðåâ³ðåíî). dzáðàíî áåç âèêîðèñòàííÿ á³áë³îòåêè LibSensors.
- DAQ.JavaLikeCalc — Ìîäóëü ðåàë³çàö³¿ ïîä³áíî¿ äî Java êîðèñòóâàöüêî¿ ìîâè òà îá÷èñëåíü íà ¿¿ îñíîâ³ (ðîáîòó ïåðåâ³ðåíî).
- DAQ.BlockCalc — Ìîäóëü ðåàë³çàö³¿ áëî÷íèõ îá÷èñëåíü (ðîáîòó ïåðåâ³ðåíî).
- DAQ.LogicLev — Ìîäóëü ðåàë³çàö³¿ äæåðåë äàíèõ ëîã³÷íîãî ð³âíÿ (ðîáîòó ïåðåâ³ðåíî).
- DAQ.ModBus — Ìîäóëü ðîáîòè ç äæåðåëàìè äàíèõ çà ïîñåðåäíèöòâîì ïðîòîêîëó ModBus (ðîáîòó ïåðåâ³ðåíî).
- DAQ.DCON — Ìîäóëü ðîáîòè ç äæåðåëàìè äàíèõ çà ïîñåðåäíèöòâîì ïðîòîêîëó DCON (ðîáîòó ïåðåâ³ðåíî). Íàïðèêëàä, ç ïðèñòðîÿìè ICP_DAS ñå𳿠I-7000. Âèÿâëåíî òà âèïðàâëåíî ïàä³ííÿ ï³ä ÷àñ îòðèìàííÿ íåãàòèâíîãî ðîçì³ðó â³äïîâ³ä³. Ðåçóëüòàò â³äïîâ³ä³ òåïåð çàâæäè ïîâåðòຠ>= 0.
- DAQ.ICP_DAS — Ìîäóëü äæåðåë äàíèõ ICP_DAS (íåìຠîáëàäíàííÿ äëÿ ïåðåâ³ðêè). Ïîñë³äîâí³ ñåð³¿: I-87000 òà I-7000; ïàðàëåëüí³ (øâèäê³): ñå𳿠I-8000. Ìîäóëü ç³áðàíî ç á³áë³îòåêîþ libi8k.a äëÿ ARM-àðõ³òåêòóðè.
- DAQ.DAQGate — Ìîäóëü ðåàë³çàö³¿ øëþçóâàííÿ äæåðåë äàíèõ ³íøèõ ñòàíö³é OpenSCADA (ðîáîòó ïåðåâ³ðåíî).
- DAQ.OPC_UA — Ìîäóëü ðîáîòè ç äæåðåëàìè äàíèõ çà ïîñåðåäíèöòâîì ïðîòîêîëó OPC_UA (ðîáîòó ïåðåâ³ðåíî). Âèÿâëåíî ïðîáëåìó ð³çíèö³ ïðåäñòàâëåííÿ ðåàëüíîãî íà x86 òà ARM FPA - äîäàíî ïåðåòâîðåííÿ ï³ä ÷àñ ïåðåäà÷³!
- DAQ.Siemens — Ìîäóëü ðîáîòè ç êîíòðîëåðàìè Siemens, çà ïîñåðåäíèöòâîì Industrial Ethernet (ISO_TCP) (ðîáîòó ïåðåâ³ðåíî).
- DAQ.SNMP — Ìîäóëü çáîðó äàíèõ ìåðåæåâîãî îáëàäíàííÿ çà ïðîòîêîëîì SNMP (ðîáîòó ïåðåâ³ðåíî).
- Archive.DBArch — Ìîäóëü àðõ³âàö³¿ íà ÁÄ (ðîáîòó ïåðåâ³ðåíî).
- Archive.FSArch — Ìîäóëü àðõ³âàö³¿ íà ôàéëîâó ñèñòåìó (ðîáîòó ïåðåâ³ðåíî). Âèÿâëåíî ïðîáëåìó ïðè ïåðåâ³ðö³ àðõ³âó, âèäà÷à ïîâ³äîìëåíü ï³ä ÷àñ çàïóñêó: "Error archive file structure: <ARCHIVES/VAL/1s/CPULoad_load 2011-09-12 17:47:17.val>. Margin = -8 byte. Will try fix it!". Ó ðåçóëüòàò³ ç'ÿñîâàíî, ùî àëãîðèòì øâèäêîãî ï³äðàõóíêó á³ò³â íå âèð³âíÿíî íà 4 áàéòà ï³ä ÷àñ ÷èòàííÿ áóôåðó ïàì'ÿò³ - âèïðàâëåíî.
- UI.WebCfg — Ìîäóëü çàñíîâàíîãî íà Web êîíô³ãóðàòîðó OpenSCADA (ðîáîòó ïåðåâ³ðåíî).
- UI.WebCfgD — Ìîäóëü çàñíîâàíîãî íà Web äèíàì³÷íîãî êîíô³ãóðàòîðó OpenSCADA (ðîáîòó ïåðåâ³ðåíî).
- UI.VCAEngine — Ìîäóëü ðóø³ÿ â³çóàë³çàö³¿ (ðîáîòó ïåðåâ³ðåíî).
- UI.WebVision — Ìîäóëü â³çóàë³çàòîðó êîðèñòóâàöüêèõ ³íòåðôåéñ³â ó UI.VCAEngine çà ïîñåðåäíèöòâîì Web-³íòåðôåéñó (ðîáîòó ïåðåâ³ðåíî).
- UI.WebUser — Ìîäóëü â³ëüíî¿ êîðèñòóâàöüêî¿ â³çóàë³çàö³¿ çà ïîñåðåäíèöòâîì Web-³íòåðôåéñó (ðîáîòó ïåðåâ³ðåíî).
- Special.FLibComplex1 — Á³áë³îòåêà ôóíêö³é ñóì³ñíîñò³ ç Complex1(ÎÎÎ ÍÈÏ "IJß") (ðîáîòó ïåðåâ³ðåíî). Âèêîðèñòîâóºòüñÿ äëÿ áëîêîâîãî ïðîãðàìóâàííÿ.
- Special.FLibMath — Á³áë³îòåêà ñòàíäàðòíèõ ìàòåìàòè÷íèõ ôóíêö³é (ðîáîòó ïåðåâ³ðåíî).
- Special.FLibSYS — Á³áë³îòåêà ñèñòåìíèõ ôóíêö³é ðîçøèðåííÿ OpenSCADA (ðîáîòó ïåðåâ³ðåíî).
Ç ìåòîþ çðó÷íîãî ðîçïîâñþäæåííÿ òà çàñòîñóâàííÿ îòðèìàíî¿ çá³ðêè OpenSCADA äëÿ ARM-êîíòðîëåð³â ô³ðìè "ICP DAS" áóëî âèêîíàíî ðîçá³ð ôîðìàòó ïðîøèâîê äëÿ öèõ êîíòðîëåð³â òà ôîðìóâàííÿ íîâî¿, ÿêà âêëþ÷ຠOpenSCADA. Ïðîøèâêà ARM-êîíòðîëåð³â "ICP DAS" ïðåäñòàâëÿº ç ñåáå á³íàðíèé ôàéë ç íàçâîþ ñõîæó íà "lp5x4x_1.1.bin". Ñòðóêòóðíî öåé ôàéë ì³ñòèòü ÿäðî òà êîðåíåâó ôàéëîâó ñèñòåìó òèïà JFFS2. ijçíàòèñÿ òî÷íå ¿õ ðîçòàøóâàííÿ ìîæíà çà äîïîìîãîþ êîìàíäè ó ïîïåðåäíüîìó îòî÷åí³ êîíòðîëåðó, íàïðèêëàä, äëÿ LP-5141:
$ cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00020000 "Bootloader"
mtd1: 00040000 00020000 "Bootloader Param"
mtd2: 00280000 00080000 "Kernel"
mtd3: 03c80000 00080000 "JFFS2 Filesystem"
²ç îòðèìàíîãî ðåçóëüòàòó êîìàíäè ìîæíà çðîáèòè âèñíîâîê, ùî òî÷êà ïîºäíàííÿ îáðàçó ÿäðà òà ôàéëîâî¿ ñèñòåìè çíàõîäèòüñÿ çà çñóâîì ôàéëó ïðîøèâêè 0x280000, à ðîçì³ð áëîêó ñòèðàííÿ ôëåøó ñêëàäຠ0x80000 (512êÁ). Ìàþ÷è öþ ³íôîðìàö³þ ìè ìîæåìî ðîç³áðàòè ïðîøèâêó òà âíåñòè çì³íè äî îáðàçó ¿¿ ôàéëîâî¿ ñèñòåìè:
# Âèëó÷åííÿ ïîïåðåäí³õ îáðàç³â ÿäðà òà êîðåíåâî¿ ôàéëîâî¿ ñèñòåìè
$ dd if=lp5x4x_1.1.bin of=kernel_orig bs=1K count=2560
$ dd if=lp5x4x_1.1.bin of=jffs2_orig bs=1K skip=2560
# ϳäêëþ÷åííÿ ïîïåðåäíüîãî îáðàçó ôàéëîâî¿ ñèñòåìè
# Ñòâîðåííÿ åìóëÿö³¿ áëîêîâîãî ïðèñòðîþ ó ïàì'ÿò³.
# Ìîæå âèêëèêàòè ïîìèëêó ó âèïàäêó âèêîðèñòàííÿ íåïåðåðâíî¿ îáëàñò³ ïàì'ÿò³ ³íøèìè ïðîãðàìàìè òà ìàëèì ¿¿ ðîçì³ðîì.
# Äëÿ âèð³øåííÿ ö³º¿ ïðîáëåìè ïîòð³áíî äîäàòè ïàðàìåòð êîìàíäíîãî ðÿäêà ÿäðà, ï³ä ÷àñ çàâàíòàæåííÿ, "vmalloc=512MB".
$ modprobe mtdram total_size=65536 erase_size=512
$ modprobe mtdblock
$ dd if=root_orig.img of=/dev/mtdblock0
$ mount -t jffs2 /dev/mtdblock0 /mnt/tmp
# Êîï³þºìî çì³íè òà ôàéëè OpenSCADA ó êîðåíåâó ôàéëîâó ñèñòåìó êîíòðîëåðó
# Ñòâîðþºìî íîâó ôàéëîâó ñèñòåìó ³ç çì³íàìè.
$ mkfs.jffs2 --root=/mnt/tmp --pad=$((61952*1024)) --eraseblock=512 --output=root.img
# Çáèðàºìî íîâèé îáðàç ïðîøèâêè
# cat kernel_orig.img root.img > lp5x4x_oscada_1.1.bin
Òàêèì ÷èíîì ìè îòðèìóºìî íîâó ïðîøèâêó ç OpenSCADA ó ôàéë³ lp5x4x_oscada_1.1.bin, ÿêó ìîæíà çàâàíòàæèòè äî êîíòðîëåðó ñòàíäàðòíèì ÷èíîì, îïèñàíèì ó äîêóìåíòàö³¿ "ICP DAS".
3. Çàóâàæåííÿ
Îñê³ëüêè ç'ÿñóâàëîñÿ, ùî îïåðàö³¿ ç ðåàëüíèìè ÷èñëàìè âèêîíóþòüñÿ çà ïîñåðåäíèöòâîì êîìàíä ñîïðîöåñîðó FPA (Float Point Acceleration), ÿêîãî ó öüîìó ïðîöåñîð³ ïðîñòî íåìàº, à âèêëèêè ñàìèõ êîìàíä çä³éñíþþòüñÿ ÷åðåç âèêëþ÷åííÿ, øëÿõîì ³ì³òàö³¿ ó ÿäð³ Linux, òî ïðîäóêòèâí³ñòü ìàòåìàòè÷íèõ îá÷èñëåíü âèÿâëÿºòüñÿ äóæå íèçüêîþ, íàâ³òü ó ïîð³âíÿíí³ ç ïðÿìèì "Software FP", "VFP". Íàïðèêëàä, îá÷èñëåííÿ îäí³º¿ îïåðàö³¿ sin(pi) çä³éñíþºòüñÿ ~200 ìêñ, ó ïîð³âíÿí³ ³ç ~20 ìêñ íà N800 ç VFP òà ~2 ìêñ íà x86, äåòàëüí³øå ó òàáëèö³ çà öèì ïîñèëàííÿì. Òàêèì ÷èíîì, ðîçãëÿäàòè öåé êîíòðîëåð ÿê ïëàòôîðìó äëÿ õî÷ ÿêèõîñü ñåðéîçíèõ îá÷èñëåíü íå ìîæíà! Ìàëî òîãî, ðåàëüí³ ÷èñëà, ïðè ðîáîò³ ³ç FPA, çáåð³ãàþòüñÿ ïî ³íøîìó, à ñàìå îñîáëèâèé big-endian, ùî âèìàãຠïåðåòâîðåííÿ, ó âèïàäêó ³ç á³íàðíèì çîâí³øí³ì îáì³íîì, äî òèïîâîãî little-endian âèãëÿäó, íàïðèêëàä, äëÿ DAQ.OPC_UA.
Ó ïåðâèíí³é êîíô³ãóðàö³¿ ïîðò COM1 (/dev/ttySA0) âèêîðèñòîâóºòüñÿ ó ðîë³ êîíñîë³, ÿêà ³í³ö³àë³çóºòüñÿ êîìàíäîþ ÿäðà "console=/dev/ttySA0". Îäíàê ï³ñëÿ íàëàøòóâàííÿ öå íå ïîòð³áíî, à ÷àñòî ³ áàæàíî çâ³ëüíèòè ùå îäèí COM-ïîðò äëÿ ³íøèõ ö³ëåé. Çâ³ëüíèòè COM1 â³ä ðîáîòè íà êîíñîëü ìîæíî ïåðåïðèçíà÷èâøè ³íøèé ïðèñòð³é äëÿ ö³º¿ ðîë³, íàïðèêëàä, êîìàíäîþ: $ busybox setconsole /dev/tty1. Îäíàê öåé ìåòîä íå ïîâí³ñòþ çâ³ëüíÿº COM-ïîðò òà çàïèòè âòðà÷àþòüñÿ, âè÷èòóþ÷èñÿ ïàðàëåëüíèì ï³äêëþ÷åííÿì. Éìîâ³ðíî ïîòð³áíî â³äðèãóâàòè ïàðàìåòðè ðÿäêà çàïóñêó ÿäðà ó çàâàíòàæóâà÷³ U-Boot, õî÷à óâ³éòè äî íüîãî ìîæíà ò³ëüêè ó ïîëîæåí³ RS=2, äëÿ ÿêîãî îäíàê ïàðàìåòðè ³í³ö³àë³çàö³¿ â³äîêðåìëåíî â³ä îñíîâíîãî ðåæèìó ðîáîòè RS=0. Ïîòð³áíî äîáèòèñÿ âõîäó äî U-Boot â³ä îñíîâíîãî ðåæèìó ðîáîòè RS=0!
Ó ïðîöåñ³ âèêîðèñòàííÿ ñòâîðåíîãî ïðîãðàìíîãî îòî÷åííÿ ç OpenSCADA âèÿâëåíî äèâíó ïðîáëåìó, ÿêà ïîëÿãຠó ïàä³íí³ OpenSCADA ï³ä ÷àñ äîñòóïó äî åêçåìïëÿðó ðåñóðñíîãî ðÿäêà ³ç ð³çíèõ ïîòîê³â. Ïðîáëåìà â³äòâîðþºòüñÿ ï³ä ÷àñ îïèòóâàííÿ êîíòðîëåðà ïî ïðîòîêîëó ModBus/RTU ç ïåð³îäè÷í³ñòþ 100ìñ, îïèòóâàíí³ â³äñóòíüîãî ìîäóëÿ çà ïîñåðåäíèöòâîì DCON íà òîìó-æ ³íòåðôåéñ³ RS485, ùî ³ ModBus/RTU. Ó òîé æå ÷àñ çä³éñíþºòüñÿ ïåð³îäè÷íà (1 ñåêóíäà) çàïèñ äâîõ ðåã³ñòð³â äî îïèòóâàíîãî çà ïðîòîêîëîì ModBus/RTU êîíòðîëåðà. Ïàä³ííÿ â³äáóâàºòüñÿ íå îäðàçó, à íà ïðîòÿç³ 10 õâèëèí - 5 ãîäèí. Ðîçá³ð ïðîáëåìè:
(*) Ó âèïàäêó âèêëþ÷åííÿ çàïèñó äî êîíòðîëåðà çà ïðîòîêîëîì ModBus/RTU ïàä³ííÿ íå ñïîñòåð³ãàºòüñÿ.
(*) Ç'ÿñîâàíî, ùî ïàä³ííÿ ïî÷èíàþòü â³äáóâàòèñÿ ó âèïàäêó äîñÿãíåííÿ ôóíêö³¿ TMdContr::modBusReq() ìîäóëÿ DAQ.ModBus, à ñàìå ïàðàëåëüíîãî äîñòóïó äî âëàñòèâîñòåé îá'åêòó êîíòðîëåðà "mPrt", ó êîíòåêñò³ êîíñòðóêòîðó "XMLNode req(mPrt);" ³ç ð³çíèõ ïîòîê³â ÷èòàííÿ òà çàïèñó.
(*) Äëÿ ç'ÿñóâàííÿ ïðèðîäè ïðîáëåìè áóëî íàëàøòîâàíî ãåíåðàö³þ ïåðåäñìåðòíîãî äàìïó ïàì'ÿò³, à òàêîæ ç³áðàíî êðîñîâèé íàëàøòîâóâà÷ gdb. ϳä ÷àñ âèâ÷åííÿ ïåðåäñìåðòíîãî äàìïó ïàì'ÿò³ ç'ÿñîâàíî, ùî â³äáóâàºòüñÿ ðóéíóâàííÿ ñòåêó òà ðîçóìíèõ ïðè÷èí ó OpenSCADA äëÿ öüîãî ÿâèùà íåìàº, òîáòî öå ïðîáëåìà ñèñòåìíîãî îòî÷åííÿ äëÿ ñïåöèô³÷íèõ óìîâ.
(*) ϳä ÷àñ äîñòóïó äî âëàñòèâîñò³ "mAddr", ó ïåðøîìó ðÿäêó ôóíêö³¿ TMdContr::modBusReq() òà ïðîáëåìíîãî êîíòåêñòó "XMLNode req(mPrt);" (ïðè íåïîâíîìó çàïèñó), ïàä³ííÿ íå âèÿâëåíî.
(*) Ïåðåâ³ðêà âèêëèêó äðóãîãî ðÿäêó "XMLNode req(mPrt);", ï³ä ÷àñ çàïèñó òà â ö³ëîìó, ç ïîñò³éíîþ "RTU". ϳä ÷àñ çàì³íè íà "RTU" â ö³ëîìó ïàä³ííÿ ñïîñòåð³ãàþòüñÿ âæå ó ³íøîìó ì³ñö³. ϳä ÷àñ çàì³íè ò³ëüêè íåïîâíîãî çàïèñó ïàä³ííÿ íå ñïîñòåð³ãàþòüñÿ. Äðóãèì òà îñòàíí³ì ì³ñöåì ïàä³ííÿ âèÿâèâñÿ íàñòóïíèé ðÿäîê
req.setAttr("id",id()). Çàãàëüíå ì³æ íèìè òå, ùî çä³éñíþºòüñÿ äîñòóï äî åëåìåíòó êîíô³ãóðàö³¿ ñòðîêîâîãî òèïó, ÿêèé âèêîðèñòîâóº îá'ºêò ðåñóðñíîãî òèïó "ResString". Âèñíîâîê, ïîòî÷íå ïðîãðàìíå îòî÷åííÿ íåêîðåêòíî ïðàöþº ç îá'ºêòîì "ResString" ï³ä ÷àñ äîñòóïó íà ÷èòàííÿ (íåìîäèô³êóþ÷îãî) ³ç äâîõ ð³çíèõ ïîòîê³â.
(*) Ìåòîä çáåð³ãàííÿ îá'ºêòó "ResString" ó åëåìåíò³ êîíô³ãóðàö³éíîãî ïîëÿ "TCfg" çíà÷åííÿ íå ìàº, à ñàìå — ïàä³ííÿ ñïîñòåð³ãàºòüñÿ ï³ä ÷àñ ïðÿìîãî çáåð³ãàííÿ "ResString" ó "TCfg", à òàêîæ ïðè áåçïîñåðåäíüîìó çâåðíåí³ äî îá'ºêòó "string" âñåðåäèí³ "ResString", ó âèïàäêó ³ç "id()".
(*) Ïåðåâ³ðêà ïðè âèêëþ÷åí³ îõîïëåííÿ ðåñóðñîì — ïðîáëåìè íå âèð³øóº.
(*) Çá³ðêà íîâîãî îòî÷åííÿ çà äîïîìîãîþ "PTXDist", òà çàïóñê éîãî ÷åðåç "chroot" — ïðè çàïóñêó EABI îòî÷åííÿ, äëÿ TionPro270 ³ç ï³ä chroot, â³äáóâàºòüñÿ ïîìèëêà "Illegal instruction!". Íå çàïóñêàºòüñÿ EABI ÿäðî â³ä TionPro270 ³ç ñõîæîþ ïîìèëêîþ. Ïîáóäîâàíèé ToolChain ³ç ïðîô³ëþ "arm-xscale_hardfloat-linux-gnu_gcc-4.0.4_glibc-2.3.6_binutils-2.17_kernel-2.6.18.ptxconfig" ó "OSELAS.Toolchain-2011.11.0" ïàäຠç ïîìèëêîþ ñåãìåíòàö³¿, ï³ä ÷àñ çàïóñêó OpenSCADA, ç³áðàíî¿ ï³ä ïåðâèííå îòî÷åííÿ.
(*) Ïîáóäîâà OpenSCADA ç âêëþ÷åííÿì âñ³õ ïîòð³áíèõ ìîäóë³â ó á³áë³îòåêó ÿäðà OpenSCADA ïðîáëåìè òàêîæ íå âèð³øóº.
(*) Çä³éñíåíî ïåðåâ³ðêó ò³º¿ æ êîíô³ãóðàö³¿ íà ³íøîìó PXA270-ïðèñòðî¿ (
TionPro270 (RU)) äëÿ îñòàòî÷íîãî ç'ÿñóâàííÿ äæåðåëà ïðîáëåìè (àïàðàòíîãî àáî ïðîãðàìíîãî îòî÷åííÿ) — êîíô³ãóðàö³ÿ áåçïðîáëåìíî â³äïðàöþâàëà äâ³ äîáè.
(*) Çàì³íèòè ó îá'ºêò³ TCfg "ResString" íà çâè÷àéíèé "string" ç âèíîñîì ðåñóðñó äîñòóïó äî îá'ºêòó êîíòåéíåðà TConfig, çà ðàçîì ³ çìåíøèâøè ñïîæèâàííÿ ïàì'ÿò³ çà ïîñåðåäíèöòâîì óçàãàëüíåííÿ ðåñóðñó äîñòóïó äî îá'ºêòó ðÿäêà — çàì³íó çä³éñíåíî, ïðîáëåìà çàëèøèëàñÿ.
(*) Âè÷èòàòè çá³ðêó ñ çàì³íîþ "ResString" íà çâè÷àéíèé "string" ó TCfg òà ïåðåâ³ðèòè ì³ñöå ïîòî÷íîãî ïàä³ííÿ — ì³ñöå ïàä³ííÿ òåæ.
(*) Âçÿòè "crosstool" òà ïîáóäóâàòè äåùî á³ëüø ñâ³æèé toolchain — ïîáóäîâàíî toolchain "gcc-4.0.2-glibc-2.3.6-arm-xscale-linux-gnu", ïðîáëåìà â³äòâîðþºòüñÿ, ñêîð³ø çà âñå ïðîáëåìà ó ðîáîò³ ³ç ïàì'ÿòòþ ïîòî÷íîãî ÿäðà. Ó ïðîöåñ³ âèâ÷åííÿ âèÿâëåí³ ïðåöåäåíòè ³ç ñõîæèìè ïðîáëåìàìè ó glibc-2.2 — 2.7, ÿê³ ì³ñÿòü ðåàë³çàö³þ malloc íåáåçïå÷íó äëÿ ïîòîê³â (nothread-safe).
(*) Çàì³íà àëîêàòîðó ïàì'ÿò³ — íå âäàëîñÿ çíàéòè ðîáî÷ó òà ïðè öüîìó ïðîçîðó ðåàë³çàö³þ ñòîðîííüîãî àëëîêàòîðó, ptmalloc3 ïðîñòî ïàäàº.
(*) Ïîáóäîâà ToolChain òà OpenSCADA ç³ âñ³ìà ìîæëèâèìè ïàðàìåòðàìè âêëþ÷åííÿ thread-safe — ó âñ³õ âàð³àíòàõ ïðîáëåìà ïðèñóòíÿ, à ñàìå íà ToolChain ³ç ïàðàìåòðàìè GLibC: "
--with-tls --with-__thread" òà OpenSCADA ç³áðàíî ³ç ïàðàìåòðàìè: "
-pthread -D_REENTERANT".
(*) Ïåðåõâàò çâåðíåíü àëîêàö³¿ ïàì'ÿò³ òà îáåðíåííÿ ãëîáàëüíèì ðåñóðñîì, ôóíêö³é "Ñ"
malloc,
free òà " new, delete — ïàä³ííÿ ñïîñòåð³ãàþòüñÿ.
(+) Ïåðåâ³ðêà ã³ïîòåçè ïðîáëåìíîñò³ ðåàë³çàö³¿ (àòîìàðíîñò³) COW (Copy on Write) àëãîðèòìó ó îá'ºêò³ "string" — êîï³þâàííÿ ³ç îá'ºêòó "string" ñõîâèùà âèêîíàíî çà ïîñåðåäíèöòâîì
val.c_str(), ùî âèêëþ÷ຠâèêîíàííÿ COW: ï³äòâåðäæåíî, ùî öÿ ïðîáëåìà ïîâ'ÿçàíà ³ç àëãîðèòìîì COW, à ñàìå ³ç àòîìàðí³ñòþ äîñòóïó äî ë³÷èëüíèêà ðÿäê³â "_Atomic_word _M_refcount;", éìîâ³ðíî ³ç-çà çàñòàð³ëî¿ ñèñòåìè ïîòîê³â linuxthread.
4. Çàêëþ÷åííÿ
Ó ðåçóëüòàò³ áóëî îòðèìàíî çá³ðêó OpenSCADA äëÿ Linux êîíòðîëåð³â, ARM-àðõ³òåêòóðè, ô³ðìè "ICP DAS". Çá³ðêó ìîæíà çàâàíòàæèòè áåçïîñåðåäíüî íà áóäü ÿêèé Linux-ARM êîíòðîëåð, ðîçïàêóâàâøè ¿¿ ó êîðí³ ïðàöþþ÷î¿ ïåðâèííî¿ ñèñòåìè. Ïðè öüîìó îäíàê çàëèøàòüñÿ äóáë³êàòè ñòàðèõ áàçîâèõ á³áë³îòåê (/lib/*), ÿê³, ï³ñëÿ âäàëîãî ïåðåâàíòàæåííÿ, ìîæíà âèäàëèòè.
Äëÿ êîíòðîëåð³â ñ³ìåéñòâà LP-5x4x ñòâîðåíî ïðîøèâêó ç³ çá³ðêîþ OpenSCADA, ÿêó ìîæíà çàâàíòàæèòè ñòàíäàðòíèì äëÿ äàíèõ êîíòðîëåð³â ÷èíîì, ÿêèé îïèñàíî ó ô³ðìîâ³é äîêóìåíòàö³¿ "ICP DAS". Ïðîøèâêà äëÿ LP-5x4x ìîæëèâî ï³ä³éäå ³ äëÿ LP-5x3x, îäíàê öå íå ïåðåâ³ðÿëîñÿ!
Ó çâ'ÿçêó ³ç çàñòàð³ëîþ òà íåîïòèìàëüíîþ ïî÷àòêîâîþ çá³ðêîþ Linux îòî÷åííÿ â³ä "ICP_DAS", ùî íàêëàäຠîáìåæåííÿ íà ñâîáîäó çá³ðêè îïòèìàëüíîãî îòî÷åííÿ, ïî çàâåðøåííþ ïðîåêòà ïëàíóºòüñÿ çâåðíóòèñÿ äî ô³ðìè "ICP_DAS" ç ïðîõàííÿì âèïðàâèòè öå ñòàíîâèùå.
(*) Çâåðíåííÿ çä³éñíåíî îäíàê æîäíî¿ ðåàêö³¿, òà íàâ³òü â³äïîâ³ä³ íà çàïèò, íå ïîñë³äóâàëî!
Ïîñèëàííÿ