LWPM Comfort Module/Tworzenie akcji

Z LWPM
Przejdź do nawigacji Przejdź do wyszukiwania

Moduł daje możliwość wykonania dowolnej akcji.

W tym miejscu opisany jest format akcji oraz możliwości i polecenia jakie mogą być zawarte w akcji.

Wszystkie liczby i wartości są podane w formacie szesnastkowym (HEX).

Format akcji

Ogólny format akcji przedstawia się następująco:

<informacje o akcji> <ilość powtórzeń> <początek akcji> <koniec akcji> <pętla>

Z tego wynika, że najprostsza akcja, która nic nie robi wygląda następująco:

00 00 00 00 00

Informacje o akcji

Informacje o akcji zawierają bardziej szczegółowe informacje na temat akcji opisujące przede wszystkim sposób wykonania akcji. Przykładowo można tutaj określić szczegółowo warunki uruchomienia akcji, a także w tym miejscu możesz zdefiniować jak mają wykonywać się poszczególne etapy pętli.

Format danych

<informacje o akcji> = <długość informacji> <informacje>*
<długość informacji>
określa długość wszystkich informacji w bajtach
<informacje>
to szczegółowy opis zachowania akcji. Takich informacji może być kilka dla każdej akcji, przy czym każda musi być innego typu.

Każda informacja jest zapisana w ten sam sposób:

<informacje> = <typ informacji> <długość danych> <dane>

Pierwszym polem jest <typ informacji> (1 bajt) następnie podana jest <długość danych> w bajtach (1 bajt) oraz <dane>, których format zależy od typu danych.

Informacje o etapach wykonania pętli

<typ informacji> == 01

TODO:

Informacje o warunkach wykonania akcji

<typ informacji> == 02

Ten typ informacji określa szczegółowo, jakie muszą zajść warunki by akcja została uruchomiona.

Format informacji
<dane> = <index> <flagi> <start> <stop> <instrukcja>*
<index>
miejsce zapisu o aktualnym stanie akcji.
Dostępne są 4 takie miejsca (00 - 03).
Każda akcja warunkowa powinna być wykonywana we własnym miejscu (każda powinna mieć inną wartość <index>) aby akcje ze sobą nie interferowały. Oczywiście akcje będą działały na tym samym indeksie, jednak może być trudno zapanować nad poprawności warunków.
<flagi>
flagi zmieniające zachowanie kalkulatora wyliczającego warunek.
Domyślna wartość to 00.
Dostępne są następujące flagi:
01
w przypadku jakiegokolwiek błędu odczytu któregokolwiek parametru pracy modułu, obliczenia zostaną uznane za poprawne - wynik obliczeń będzie prawidłowo, a wiec może dojść do uruchomienia akcji. Domyślnie jakikolwiek błąd w obliczeniach powoduje, że akcja zostanie przerwana lub się nie uruchomi.
<start>
określa ilość prawidłowych obliczeń jaka jest wymagana by akcja się uruchomiła. W przypadku gdy wartość jest równa 00 - akcja wykona się zawsze (wartość ta w zasadzie nie ma większego sensu)
<stop>
określa ilość prawidłowych obliczeń jaka jest wymagana by akcja się zakończyła. W przypadku gdy wartość jest równa 00 - akcja zakończy się zawsze (wartość ta w zasadzie nie ma większego sensu)
<instrukcja>*
ciąg instrukcji dla kalkulatora
Zasada działania kalkulatora

Obliczenia warunku są wykonywane na zasadzie zbliżonej do kalkulatora działającego na zasadzie RPN (odwrócona polska notacja). Tj: najpierw podajemy argumenty instrukcji, następnie operacje jaką chcemy na tych argumentach wykonać. Wynikiem kalkulatora jest wartość 0 jeśli warunek jest niespełniony, lub wartość różna od 0 jeśli warunek jest prawdziwy i kalkulator możesz przejść do uruchomienia akcji (po określonej ilości poprawnych obliczeń).

Kalkulator posiada następujące rejestry:

  • a - rejestr 32-bitowy (liczba ze znakiem)
  • b - rejestr 32-bitowy (liczba ze znakiem)
  • save[x] - 4 elementowa tablica 32-bitowych liczb ze znakiem. Do tymczasowego przechowywania danych. Na tych liczbach nie można wykonywać bezpośrednio operacji - należy je najpierw przenieść do rejestrów a lub b.
Dostępne instrukcje

W kalkulatorze dostępnych jest szereg instrukcji które są wykorzystywane do wykonywania obliczeń. W poniższej tabeli jest zestawienie tych instrukcji.

Instrukcja Operacja Opis
operacje ładowania stałych wartości (liczb)
00
a = b
b = 0
Load 0
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b wartość 0
01
a = b
b = 1
Load 1
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b wartość 1
02
a = b
b = -1
Load -1
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b wartość -1 (0xFFFFFFFF)
03 <xx>
a = b
b = <xx> 
LoadSignedByte
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b wartość <xx>, która interpretowana jest jako 8-bitowa liczba ze znakiem
04 <xx>
a = b
b = <xx> 
LoadUnsignedByte
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b wartość <xx>, która interpretowana jest jako 8-bitowa liczna bez znaku
05 <xxxx>
a = b
b = <xxxx> 
LoadSignedWord
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b wartość <xxxx>, która interpretowana jest jako 16-bitowa liczba ze znakiem
06 <xxxx>
a = b
b = <xxxx> 
LoadUnsignedWord
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b wartość <xxxx>, która interpretowana jest jako 16-bitowa liczba bez znaku
07 <xxxxxxxx>
a = b
b = <xxxxxxxx> 
LoadDoubleWord
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b wartość <xxxxxxxx>, która interpretowana jest jako 32-bitowa liczba ze znakiem
10 <nn>
save[<nn>] = a
SaveB
przepisz zawartość rejestru b do rejestru save[n] (rejestr save na pozycji n)
11 <nn>
save[<nn>] = b
SaveB
przepisz zawartość rejestru b do rejestru save[n] (rejestr save na pozycji n)
14 <nn>
a = save[<nn>]
RestoreA
przepisz zawartość rejestru save[n] (rejestr save na pozycji n) do rejestru a
15 <nn>
b = save[<nn>]
RestoreB
przepisz zawartość rejestru save[n] (rejestr save na pozycji n) do rejestru b
operacje ładowania parametru pracy silnika (modułu)
20 <nn>
a = b
b = ReadSTD(<nn>)
LoadStandardValue
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b jedną ze standardowych wartości (aktualnych parametrów pracy silnika)

Dostępne wartości to:

indeks wartość
00 szybkość pojazdu (w km/h)
01 obroty silnika (RPM)
02 temperatura czynnika chłodzącego (w °C)
21 <nn>
a = b
b = ReadOBD2(<nn>)
LoadOBD2Value
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b jedną z wartości odczytaną z systemu OBD2 sterownika silnika

Dostępne wartości to:

indeks wartość
TODO TODO
22 <nn>
a = b
b = ReadECUInfo(<nn>)
LoadECUInfoValue
przepisz zawartość rejestru b do rejestru a oraz
wpisz do rejestru b jedną z wartości odczytaną z systemu ECUInfo modułu

Dostępne wartości to:

indeks wartość
TODO TODO
operacje konwersji danych
30
b = SignExtend8(b)
ExtendSignedByte
rozszerz zawartość rejestru b z 8-bitowej liczby ze znakiem do 32-bitowej liczby ze znakiem
31
b = ZeroExtend8(b)
ExtendUnsignedByte
rozszerz zawartość rejestru b z 8-bitowej liczby bez znaku do 32-bitowej liczby ze znakiem
32
b = SignExtend16(b)
ExtendSignedWord
rozszerz zawartość rejestru b z 16-bitowej liczby ze znakiem do 32-bitowej liczby ze znakiem
33
b = ZeroExtend16(b)
ExtendSignedWord
rozszerz zawartość rejestru b z 16-bitowej liczby bez znaku do 32-bitowej liczby ze znakiem
34
b = SignExtend1(b)
ExtendBit
rozszerz zawartość rejestru b z 1-bitowej liczby ze znakiem do 32-bitowej liczby ze znakiem
operacje arytmetyczne
40
<tmp> = a
a = b
b = <tmp>
Exchange
zamień miejscami zawartość rejestru a z rejestrem b
41
b = b + a
Add
Dodaj do rejestru b wartość rejestru a i zapisz wynik w rejestrze b
42
b = b - a
Subtract
Odejmij od rejestru b wartość rejestru a i zapisz wynik w rejestrze b
43
b = b * a
Multiply
Pomnóż wartość z rejestru b i wartość rejestru a i zapisz wynik w rejestrze b
44
b = b / a
Divide
Podziel wartość z rejestru b przez wartość rejestru a i zapisz wynik w rejestrze b (część całkowita wyniku dzielenia)
45
b = b % a
Modulo
Podziel wartość z rejestru b przez wartość rejestru a i zapisz wynik w rejestrze b (reszta z wyniku dzielenia)
46
b = -b
Negate
zmień znak liczby w rejestrze b na przeciwny
47
b = b << a
ShiftLeft
przesuń wartość bitową w rejestrze b w lewo o ilość bitów określoną w rejestrze a i zapisz wynik w rejestrze b
48
b = b >> a
ShiftRight
przesuń wartość bitową w rejestrze b w prawo o ilość bitów określoną w rejestrze a i zapisz wynik w rejestrze b
operacje bitowe
50
b = b & a
ArithmeticalAnd
wykonaj bitową operację AND na rejestrach a oraz b i zapisz wynik w rejestrze b
51
b = b | a
ArithmeticalOr
wykonaj bitową operację OR na rejestrach a oraz b i zapisz wynik w rejestrze b
52
b = b ^ a
ArithmeticalXor
wykonaj bitową operację XOR na rejestrach a oraz b i zapisz wynik w rejestrze b
53
b = ~b
ArithmeticalNot
wykonaj bitową operację NOT na rejestrze b i zapisz wynik w rejestrze b
operacje logiczne
60
if a <> 0 and b <> 0:
    b = 1
else:
    b = 0
LogicalAnd
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy wartości w rejestrach a oraz b są różne od 0. W przeciwnym przypadku wpisuje wartość 0
61
if a <> 0 or b <> 0:
    b = 1
else:
    b = 0
LogicalOr
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy przynajmniej jedna z wartości w rejestrach a oraz b jest różna od 0. W przeciwnym przypadku wpisuje 0
62
if a <> 0 xor b <> 0:
    b = 1
else:
    b = 0
LogicalXor
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy dokładnie jedna z wartości w rejestrach a oraz b jest różna od 0. W przeciwnym przypadku wpisuje 0
63
if b <> 0:
    b = 1
else:
    b = 0
LogicalNot
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy zawartość rejestru b jest różna od 0. W przeciwnym przypadku wpisuje 0
instrukcje porównujące dane
F0
if b == 0:
    b = 1
else:
    b = 0
CompareZero
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy wartość w rejestrze b jest równa 0. W przeciwnym przypadku wpisuje wartość 0
F1
if b <> 0:
    b = 1
else:
    b = 0
CompareNotZero
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy wartość w rejestrze b jest różna od 0. W przeciwnym przypadku wpisuje wartość 0
F2
if b < 0:
    b = 1
else:
    b = 0
CompareLessThanZero
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy wartość w rejestrze b jest mniejsza od 0. W przeciwnym przypadku wpisuje wartość 0
F3
if b <= 0:
    b = 1
else:
    b = 0
CompareLessThanOrEqualZero
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy wartość w rejestrze b jest mniejsza lub równa 0. W przeciwnym przypadku wpisuje wartość 0
F4
if b > 0:
    b = 1
else:
    b = 0
CompareGreaterThanZero
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy wartość w rejestrze b jest większa od 0. W przeciwnym przypadku wpisuje wartość 0
F5
if b >= 0:
    b = 1
else:
    b = 0
CompareGreaterThanOrEqualZero
wpisuje do rejestru b wartość 1 wtedy i tylko wtedy gdy wartość w rejestrze b jest większa lub równa 0. W przeciwnym przypadku wpisuje wartość 0
koniec obliczeń
FD
if b <> 0:
    return 1
ReturnIfNotZero
zwraca 1, jeśli zawartość rejestru b jest różna 0. Operacja ta pozwoli na rezygnację z dalszych obliczeń, jeśli już teraz wiadomo, że cały warunek będzie spełniony
FE
if b == 0:
    return 0
ReturnIfZero
zwraca 0, jeśli zawartość rejestru b wynosi 0. Operacja ta pozwoli na rezygnację z dalszych obliczeń, jeśli już teraz wiadomo, że cały warunek nie będzie spełniony
FF
return b
Return
zwraca w wyniku zawartość rejestru b. Gdy wartość ta jest różna od 0, warunek uznaje się za spełniony

Ilość powtórzeń

Początek akcji

Koniec akcji

Pętla

Dostępne polecenia