LWPM Comfort Module/Tworzenie akcji: Różnice pomiędzy wersjami
(Nie pokazano 37 pośrednich wersji utworzonych przez tego samego użytkownika) | |||
Linia 8: | Linia 8: | ||
Ogólny format akcji przedstawia się następująco: | Ogólny format akcji przedstawia się następująco: | ||
− | <code> | + | ;:<code><[[#Informacje o akcji|informacje o akcji]]> <[[#Ilość powtórzeń|ilość powtórzeń]]> <[[#Początek akcji|początek akcji]]> <[[#Koniec akcji|koniec akcji]]> <[[#Pętla|pętla]]></code> |
− | <[[#Informacje o akcji|informacje o akcji]]> <[[#Ilość powtórzeń|ilość powtórzeń]]> <[[#Początek akcji|początek akcji]]> <[[#Koniec akcji|koniec akcji]]> <[[#Pętla|pętla]]> | + | |
− | </code> | + | Z tego wynika, że najprostsza akcja, która nic nie robi wygląda następująco: |
+ | : <code>00 00 00 00 00</code> | ||
=== Informacje o akcji === | === Informacje o akcji === | ||
Linia 17: | Linia 18: | ||
==== Format danych ==== | ==== Format danych ==== | ||
− | <code> | + | ;:<code><informacje o akcji> = <długość informacji> <informacje>*</code> |
− | <informacje o akcji> = <długość informacji> <informacje>* | ||
− | </code> | ||
− | <code><długość informacji></code> określa długość wszystkich informacji w bajtach | + | ;<code><długość informacji></code>: określa długość wszystkich informacji w bajtach |
− | <code><informacje></code> to szczegółowy opis zachowania akcji. Takich informacji może być kilka dla każdej akcji, przy czym każda musi być innego typu. | + | ;<code><informacje></code>: 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: | Każda informacja jest zapisana w ten sam sposób: | ||
− | <code><informacje> = <typ informacji> <długość danych> <dane></code> | + | ;:<code><informacje> = <typ informacji> <długość danych> <dane></code> |
− | Pierwszym polem jest <code><typ | + | Pierwszym polem jest <code><typ informacji></code> (1 bajt) następnie podana jest <code><długość danych></code> w bajtach (1 bajt) oraz <code><dane></code>, których format zależy od typu danych. |
==== Informacje o etapach wykonania pętli ==== | ==== Informacje o etapach wykonania pętli ==== | ||
− | <code><typ informacji> == | + | :<code><typ informacji> == 01</code> |
TODO: | TODO: | ||
==== Informacje o warunkach wykonania akcji ==== | ==== Informacje o warunkach wykonania akcji ==== | ||
− | <code><typ informacji> == | + | :<code><typ informacji> == 02</code> |
Ten typ informacji określa szczegółowo, jakie muszą zajść warunki by akcja została uruchomiona. | Ten typ informacji określa szczegółowo, jakie muszą zajść warunki by akcja została uruchomiona. | ||
===== Format informacji ===== | ===== Format informacji ===== | ||
− | <code> | + | ;:<code><dane> = <index> <flagi> <start> <stop> <instrukcja>*</code> |
− | <dane> = < | + | |
− | </code> | + | ;<code><index></code>: miejsce zapisu o aktualnym stanie akcji. |
+ | :Dostępne są 4 takie miejsca (<code>00</code> - <code>03</code>). | ||
+ | :Każda akcja warunkowa powinna być wykonywana we własnym miejscu (każda powinna mieć inną wartość <code><index></code>) 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. | ||
+ | :Możliwe jest także wpisanie wartości <code>FF</code> która spowoduje, że wynik obliczeń nie będzie nigdzie zapisywany. | ||
+ | :Wartość (<code>00</code> - <code>03</code>) powinna być użyta dla akcji działających jako akcje w tle, natomiast wartość <code>FF</code> dla pozostałych akcji. | ||
+ | |||
+ | ;<code><flagi></code>: flagi zmieniające zachowanie kalkulatora wyliczającego warunek. | ||
+ | :Domyślna wartość to <code>00</code>. | ||
+ | :Dostępne są następujące flagi: | ||
+ | :;<code>01</code>: 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. | ||
+ | |||
+ | ;<code><start></code>: określa ilość prawidłowych obliczeń jaka jest wymagana by akcja się uruchomiła. W przypadku gdy wartość jest równa <code>00</code> - akcja wykona się zawsze (wartość ta w zasadzie nie ma większego sensu) | ||
+ | |||
+ | ;<code><stop></code>: określa ilość prawidłowych obliczeń jaka jest wymagana by akcja się zakończyła. W przypadku gdy wartość jest równa <code>00</code> - akcja zakończy się zawsze (wartość ta w zasadzie nie ma większego sensu) | ||
+ | |||
+ | ;<code><instrukcja>*</code>: 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ść <code>0</code> jeśli warunek jest niespełniony, lub wartość różna od <code>0</code> 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: | |
− | <code> | + | * <code>a</code> - rejestr 32-bitowy (liczba ze znakiem) |
− | + | * <code>b</code> - rejestr 32-bitowy (liczba ze znakiem) | |
− | + | * <code>save[x]</code> - 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 <code>a</code> lub <code>b</code>. | |
− | <code>< | + | ===== 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. | ||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Instrukcja | ||
+ | ! Operacja | ||
+ | ! Opis | ||
+ | |- | ||
+ | ! colspan="3"|operacje ładowania stałych wartości (liczb) | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>00</code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ; Load 0: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wartość <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>01</code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = 1</pre> | ||
+ | | | ||
+ | ;Load 1: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wartość <code>1</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>02</code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = -1</pre> | ||
+ | | | ||
+ | ;Load -1: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wartość <code>-1</code> (<code>0xFFFFFFFF</code>) | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>03 <xx></code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = <xx> </pre> | ||
+ | | | ||
+ | ;LoadSignedByte: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wartość <code><xx></code>, która interpretowana jest jako 8-bitowa liczba ze znakiem | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>04 <xx></code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = <xx> </pre> | ||
+ | | | ||
+ | ;LoadUnsignedByte: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wartość <code><xx></code>, która interpretowana jest jako 8-bitowa liczna bez znaku | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>05 <xxxx></code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = <xxxx> </pre> | ||
+ | | | ||
+ | ;LoadSignedWord: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wartość <code><xxxx></code>, która interpretowana jest jako 16-bitowa liczba ze znakiem | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>06 <xxxx></code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = <xxxx> </pre> | ||
+ | | | ||
+ | ;LoadUnsignedWord: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wartość <code><xxxx></code>, która interpretowana jest jako 16-bitowa liczba bez znaku | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>07 <xxxxxxxx></code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = <xxxxxxxx> </pre> | ||
+ | | | ||
+ | ;LoadDoubleWord: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wartość <code><xxxxxxxx></code>, która interpretowana jest jako 32-bitowa liczba ze znakiem | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>10 <nn></code> | ||
+ | | | ||
+ | <pre>save[<nn>] = a</pre> | ||
+ | | | ||
+ | ;SaveB: przepisz zawartość rejestru <code>b</code> do rejestru <code>save[n]</code> (rejestr <code>save</code> na pozycji <code>n</code>) | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>11 <nn></code> | ||
+ | | | ||
+ | <pre>save[<nn>] = b</pre> | ||
+ | | | ||
+ | ;SaveB: przepisz zawartość rejestru <code>b</code> do rejestru <code>save[n]</code> (rejestr <code>save</code> na pozycji <code>n</code>) | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>14 <nn></code> | ||
+ | | | ||
+ | <pre>a = save[<nn>]</pre> | ||
+ | | | ||
+ | ;RestoreA: przepisz zawartość rejestru <code>save[n]</code> (rejestr <code>save</code> na pozycji <code>n</code>) do rejestru <code>a</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>15 <nn></code> | ||
+ | | | ||
+ | <pre>b = save[<nn>]</pre> | ||
+ | | | ||
+ | ;RestoreB: przepisz zawartość rejestru <code>save[n]</code> (rejestr <code>save</code> na pozycji <code>n</code>) do rejestru <code>b</code> | ||
+ | |- | ||
+ | ! colspan="3"|operacje ładowania parametru pracy silnika (modułu) | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>20 <nn></code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = ReadDiagnosticsValue(<nnnn>)</pre> | ||
+ | | | ||
+ | ;ReadDiagnosticsValue: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz wpisz do rejestru <code>b</code> jedną z wartości z diagnostyki | ||
− | + | Spisz wszystkich dostępnych parametrów na [[LWPM_Comfort_Module/ECUInfo|tej stronie]]. | |
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>23 <lan> <tx> <rx> <sts> <id> <byte></code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = ReadModuleStatus(<id>)</pre> | ||
+ | | | ||
+ | ;ReadModuleStatus: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> wybrane 4 bajty z rejestru statusu modułu do <code>b</code> | ||
+ | Parametry: | ||
+ | {| class="wikitable" | ||
+ | ! parametr | ||
+ | ! znaczenie | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code><lan></code> | ||
+ | | | ||
+ | ;szyna CAN na której znajduje się moduł | ||
+ | :<code>00</code> - LSCAN | ||
+ | :<code>01</code> - MSCAN | ||
+ | :<code>02</code> - HSCAN | ||
+ | :<code>03</code> - CHCAN | ||
− | <code>01</code> - w przypadku | + | |- |
+ | |style="white-space: nowrap;"|<code><tx></code> | ||
+ | | | ||
+ | ;adres na którym moduł nasłuchuje na CAN | ||
+ | :<code><xxxx></code>, np dla sterownika silnika: <code>07E0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code><rs></code> | ||
+ | | | ||
+ | ;adres na którym moduł odpowiada na CAN | ||
+ | :<code><xxxx></code>, np dla sterownika silnika: <code>07E8</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code><srs></code> | ||
+ | | | ||
+ | ;adres na którym moduł wysyła statusy na CAN | ||
+ | :<code><xxxx></code>, np dla sterownika silnika: <code>05E8</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code><id></code> | ||
+ | | | ||
+ | ;identyfikator statusu do odczytania | ||
+ | :<code><xx></code>, np <code>03</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code><byte></code> | ||
+ | | | ||
+ | ;bajt od którego zostanie wczytana wartość | ||
+ | :<code><xx></code>, np dla odczytanego statusu <code>01 02 03 04 05 06 07</code> wartość <code>02</code> spowoduje wpisanie do <code>a</code> wartości <code>0x03040506</code>. Korzystając z pozostałych instrukcji można dotrzeć do dowolnego bajtu/bitu ze statusu. | ||
+ | |} | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>24</code> | ||
+ | | | ||
+ | <pre>a = b | ||
+ | b = ReadIOStatus()</pre> | ||
+ | | | ||
+ | ;ReadIOStatus: przepisz zawartość rejestru <code>b</code> do rejestru <code>a</code> oraz | ||
+ | :wpisz do rejestru <code>b</code> stan wszystkich wyjść/wejść modułu (np AUX) | ||
+ | Wartości poszczególnych pinów IO są zapisane w następujący sposób (jedna wartość na każdym bicie rejestru <code>b</code>): | ||
+ | {| class="wikitable" | ||
+ | ! bit | ||
+ | ! wartość | ||
+ | ! IO | ||
+ | |- | ||
+ | | <code>0</code> | ||
+ | | <code>0x01</code> | ||
+ | | C2D | ||
+ | |- | ||
+ | | <code>1</code> | ||
+ | | <code>0x02</code> | ||
+ | | LED- | ||
+ | |- | ||
+ | | <code>2</code> | ||
+ | | <code>0x04</code> | ||
+ | | UART TX | ||
+ | |- | ||
+ | | <code>3</code> | ||
+ | | <code>0x08</code> | ||
+ | | UART_RX | ||
+ | |- | ||
+ | | <code>4</code> | ||
+ | | <code>0x10</code> | ||
+ | | AUX1 | ||
+ | |- | ||
+ | | <code>5</code> | ||
+ | | <code>0x20</code> | ||
+ | | AUX2 | ||
+ | |- | ||
+ | | <code>6</code> | ||
+ | | <code>0x40</code> | ||
+ | | AUX3 | ||
+ | |} | ||
+ | Lokalizacja poszczególnych pinów jest przedstawiona na [[LWPM_Comfort_Module/PCB|tej stronie]]. | ||
+ | |- | ||
+ | ! colspan="3"|operacje konwersji danych | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>30</code> | ||
+ | | | ||
+ | <pre>b = SignExtend8(b)</pre> | ||
+ | | | ||
+ | ;ExtendSignedByte: rozszerz zawartość rejestru <code>b</code> z 8-bitowej liczby ze znakiem do 32-bitowej liczby ze znakiem | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>31</code> | ||
+ | | | ||
+ | <pre>b = ZeroExtend8(b)</pre> | ||
+ | | | ||
+ | ;ExtendUnsignedByte: rozszerz zawartość rejestru <code>b</code> z 8-bitowej liczby bez znaku do 32-bitowej liczby ze znakiem | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>32</code> | ||
+ | | | ||
+ | <pre>b = SignExtend16(b)</pre> | ||
+ | | | ||
+ | ;ExtendSignedWord: rozszerz zawartość rejestru <code>b</code> z 16-bitowej liczby ze znakiem do 32-bitowej liczby ze znakiem | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>33</code> | ||
+ | | | ||
+ | <pre>b = ZeroExtend16(b)</pre> | ||
+ | | | ||
+ | ;ExtendSignedWord: rozszerz zawartość rejestru <code>b</code> z 16-bitowej liczby bez znaku do 32-bitowej liczby ze znakiem | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>34</code> | ||
+ | | | ||
+ | <pre>b = SignExtend1(b)</pre> | ||
+ | | | ||
+ | ;ExtendBit: rozszerz zawartość rejestru <code>b</code> z 1-bitowej liczby ze znakiem do 32-bitowej liczby ze znakiem | ||
+ | |- | ||
+ | ! colspan="3"|operacje arytmetyczne | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>40</code> | ||
+ | | | ||
+ | <pre><tmp> = a | ||
+ | a = b | ||
+ | b = <tmp></pre> | ||
+ | | | ||
+ | ;Exchange: zamień miejscami zawartość rejestru <code>a</code> z rejestrem <code>b</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>41</code> | ||
+ | | | ||
+ | <pre>b = b + a</pre> | ||
+ | | | ||
+ | ;Add: Dodaj do rejestru <code>b</code> wartość rejestru <code>a</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>42</code> | ||
+ | | | ||
+ | <pre>b = b - a</pre> | ||
+ | | | ||
+ | ;Subtract: Odejmij od rejestru <code>b</code> wartość rejestru <code>a</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>43</code> | ||
+ | | | ||
+ | <pre>b = b * a</pre> | ||
+ | | | ||
+ | ;Multiply: Pomnóż wartość z rejestru <code>b</code> i wartość rejestru <code>a</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>44</code> | ||
+ | | | ||
+ | <pre>b = b / a</pre> | ||
+ | | | ||
+ | ;Divide: Podziel wartość z rejestru <code>b</code> przez wartość rejestru <code>a</code> i zapisz wynik w rejestrze <code>b</code> (część całkowita wyniku dzielenia) | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>45</code> | ||
+ | | | ||
+ | <pre>b = b % a</pre> | ||
+ | | | ||
+ | ;Modulo: Podziel wartość z rejestru <code>b</code> przez wartość rejestru <code>a</code> i zapisz wynik w rejestrze <code>b</code> (reszta z wyniku dzielenia) | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>46</code> | ||
+ | | | ||
+ | <pre>b = -b</pre> | ||
+ | | | ||
+ | ;Negate: zmień znak liczby w rejestrze <code>b</code> na przeciwny | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>47</code> | ||
+ | | | ||
+ | <pre>b = b << a</pre> | ||
+ | | | ||
+ | ;ShiftLeft: przesuń wartość bitową w rejestrze <code>b</code> w lewo o ilość bitów określoną w rejestrze <code>a</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>48</code> | ||
+ | | | ||
+ | <pre>b = b >> a</pre> | ||
+ | | | ||
+ | ;ShiftRight: przesuń wartość bitową w rejestrze <code>b</code> w prawo o ilość bitów określoną w rejestrze <code>a</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | ! colspan="3"|operacje bitowe | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>50</code> | ||
+ | | | ||
+ | <pre>b = b & a</pre> | ||
+ | | | ||
+ | ;ArithmeticalAnd: wykonaj bitową operację <code>AND</code> na rejestrach <code>a</code> oraz <code>b</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>51</code> | ||
+ | | | ||
+ | <pre>b = b | a</pre> | ||
+ | | | ||
+ | ;ArithmeticalOr: wykonaj bitową operację <code>OR</code> na rejestrach <code>a</code> oraz <code>b</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>52</code> | ||
+ | | | ||
+ | <pre>b = b ^ a</pre> | ||
+ | | | ||
+ | ;ArithmeticalXor: wykonaj bitową operację <code>XOR</code> na rejestrach <code>a</code> oraz <code>b</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>53</code> | ||
+ | | | ||
+ | <pre>b = ~b</pre> | ||
+ | | | ||
+ | ;ArithmeticalNot: wykonaj bitową operację <code>NOT</code> na rejestrze <code>b</code> i zapisz wynik w rejestrze <code>b</code> | ||
+ | |- | ||
+ | ! colspan="3"|operacje logiczne | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>60</code> | ||
+ | | | ||
+ | <pre>if a <> 0 and b <> 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;LogicalAnd: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy wartości w rejestrach <code>a</code> oraz <code>b</code> są różne od <code>0</code>. W przeciwnym przypadku wpisuje wartość <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>61</code> | ||
+ | | | ||
+ | <pre>if a <> 0 or b <> 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;LogicalOr: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy przynajmniej jedna z wartości w rejestrach <code>a</code> oraz <code>b</code> jest różna od <code>0</code>. W przeciwnym przypadku wpisuje <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>62</code> | ||
+ | | | ||
+ | <pre>if a <> 0 xor b <> 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;LogicalXor: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy dokładnie jedna z wartości w rejestrach <code>a</code> oraz <code>b</code> jest różna od <code>0</code>. W przeciwnym przypadku wpisuje <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>63</code> | ||
+ | | | ||
+ | <pre>if b <> 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;LogicalNot: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy zawartość rejestru <code>b</code> jest różna od <code>0</code>. W przeciwnym przypadku wpisuje <code>0</code> | ||
+ | |- | ||
+ | ! colspan="3"|instrukcje porównujące dane | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>F0</code> | ||
+ | | | ||
+ | <pre>if b == 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;CompareZero: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy wartość w rejestrze <code>b</code> jest równa <code>0</code>. W przeciwnym przypadku wpisuje wartość <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>F1</code> | ||
+ | | | ||
+ | <pre>if b <> 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;CompareNotZero: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy wartość w rejestrze <code>b</code> jest różna od <code>0</code>. W przeciwnym przypadku wpisuje wartość <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>F2</code> | ||
+ | | | ||
+ | <pre>if b < 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;CompareLessThanZero: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy wartość w rejestrze <code>b</code> jest mniejsza od <code>0</code>. W przeciwnym przypadku wpisuje wartość <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>F3</code> | ||
+ | | | ||
+ | <pre>if b <= 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;CompareLessThanOrEqualZero: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy wartość w rejestrze <code>b</code> jest mniejsza lub równa <code>0</code>. W przeciwnym przypadku wpisuje wartość <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>F4</code> | ||
+ | | | ||
+ | <pre>if b > 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;CompareGreaterThanZero: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy wartość w rejestrze <code>b</code> jest większa od <code>0</code>. W przeciwnym przypadku wpisuje wartość <code>0</code> | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>F5</code> | ||
+ | | | ||
+ | <pre>if b >= 0: | ||
+ | b = 1 | ||
+ | else: | ||
+ | b = 0</pre> | ||
+ | | | ||
+ | ;CompareGreaterThanOrEqualZero: wpisuje do rejestru <code>b</code> wartość <code>1</code> wtedy i tylko wtedy gdy wartość w rejestrze <code>b</code> jest większa lub równa <code>0</code>. W przeciwnym przypadku wpisuje wartość <code>0</code> | ||
+ | |- | ||
+ | ! colspan="3"|koniec obliczeń | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>FD</code> | ||
+ | | | ||
+ | <pre>if b <> 0: | ||
+ | return 1</pre> | ||
+ | | | ||
+ | ;ReturnIfNotZero: zwraca <code>1</code>, jeśli zawartość rejestru <code>b</code> jest różna <code>0</code>. Operacja ta pozwoli na rezygnację z dalszych obliczeń, jeśli już teraz wiadomo, że cały warunek będzie spełniony | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>FE</code> | ||
+ | | | ||
+ | <pre>if b == 0: | ||
+ | return 0</pre> | ||
+ | | | ||
+ | ;ReturnIfZero: zwraca <code>0</code>, jeśli zawartość rejestru <code>b</code> wynosi <code>0</code>. Operacja ta pozwoli na rezygnację z dalszych obliczeń, jeśli już teraz wiadomo, że cały warunek nie będzie spełniony | ||
+ | |- | ||
+ | |style="white-space: nowrap;"|<code>FF</code> | ||
+ | | | ||
+ | <pre>return b</pre> | ||
+ | | | ||
+ | ;Return: zwraca w wyniku zawartość rejestru <code>b</code>. Gdy wartość ta jest różna od <code>0</code>, warunek uznaje się za spełniony | ||
+ | |} | ||
=== Ilość powtórzeń === | === Ilość powtórzeń === | ||
Linia 66: | Linia 509: | ||
=== Pętla === | === Pętla === | ||
+ | |||
+ | == Dostępne polecenia == |
Aktualna wersja na dzień 11:32, 15 sty 2024
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).
Spis treści
Format akcji
Ogólny format akcji przedstawia się następująco:
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. - Możliwe jest także wpisanie wartości
FF
która spowoduje, że wynik obliczeń nie będzie nigdzie zapisywany. - Wartość (
00
-03
) powinna być użyta dla akcji działających jako akcje w tle, natomiast wartośćFF
dla pozostałych akcji.
<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ówa
lubb
.
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 |
| ||||||||||||||||||||||||
01
|
a = b b = 1 |
| ||||||||||||||||||||||||
02
|
a = b b = -1 |
| ||||||||||||||||||||||||
03 <xx>
|
a = b b = <xx> |
| ||||||||||||||||||||||||
04 <xx>
|
a = b b = <xx> |
| ||||||||||||||||||||||||
05 <xxxx>
|
a = b b = <xxxx> |
| ||||||||||||||||||||||||
06 <xxxx>
|
a = b b = <xxxx> |
| ||||||||||||||||||||||||
07 <xxxxxxxx>
|
a = b b = <xxxxxxxx> |
| ||||||||||||||||||||||||
10 <nn>
|
save[<nn>] = a |
| ||||||||||||||||||||||||
11 <nn>
|
save[<nn>] = b |
| ||||||||||||||||||||||||
14 <nn>
|
a = save[<nn>] |
| ||||||||||||||||||||||||
15 <nn>
|
b = save[<nn>] |
| ||||||||||||||||||||||||
operacje ładowania parametru pracy silnika (modułu) | ||||||||||||||||||||||||||
20 <nn>
|
a = b b = ReadDiagnosticsValue(<nnnn>) |
Spisz wszystkich dostępnych parametrów na tej stronie. | ||||||||||||||||||||||||
23 <lan> <tx> <rx> <sts> <id> <byte>
|
a = b b = ReadModuleStatus(<id>) |
Parametry:
| ||||||||||||||||||||||||
24
|
a = b b = ReadIOStatus() |
Wartości poszczególnych pinów IO są zapisane w następujący sposób (jedna wartość na każdym bicie rejestru
Lokalizacja poszczególnych pinów jest przedstawiona na tej stronie. | ||||||||||||||||||||||||
operacje konwersji danych | ||||||||||||||||||||||||||
30
|
b = SignExtend8(b) |
| ||||||||||||||||||||||||
31
|
b = ZeroExtend8(b) |
| ||||||||||||||||||||||||
32
|
b = SignExtend16(b) |
| ||||||||||||||||||||||||
33
|
b = ZeroExtend16(b) |
| ||||||||||||||||||||||||
34
|
b = SignExtend1(b) |
| ||||||||||||||||||||||||
operacje arytmetyczne | ||||||||||||||||||||||||||
40
|
<tmp> = a a = b b = <tmp> |
| ||||||||||||||||||||||||
41
|
b = b + a |
| ||||||||||||||||||||||||
42
|
b = b - a |
| ||||||||||||||||||||||||
43
|
b = b * a |
| ||||||||||||||||||||||||
44
|
b = b / a |
| ||||||||||||||||||||||||
45
|
b = b % a |
| ||||||||||||||||||||||||
46
|
b = -b |
| ||||||||||||||||||||||||
47
|
b = b << a |
| ||||||||||||||||||||||||
48
|
b = b >> a |
| ||||||||||||||||||||||||
operacje bitowe | ||||||||||||||||||||||||||
50
|
b = b & a |
| ||||||||||||||||||||||||
51
|
b = b | a |
| ||||||||||||||||||||||||
52
|
b = b ^ a |
| ||||||||||||||||||||||||
53
|
b = ~b |
| ||||||||||||||||||||||||
operacje logiczne | ||||||||||||||||||||||||||
60
|
if a <> 0 and b <> 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
61
|
if a <> 0 or b <> 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
62
|
if a <> 0 xor b <> 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
63
|
if b <> 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
instrukcje porównujące dane | ||||||||||||||||||||||||||
F0
|
if b == 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
F1
|
if b <> 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
F2
|
if b < 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
F3
|
if b <= 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
F4
|
if b > 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
F5
|
if b >= 0: b = 1 else: b = 0 |
| ||||||||||||||||||||||||
koniec obliczeń | ||||||||||||||||||||||||||
FD
|
if b <> 0: return 1 |
| ||||||||||||||||||||||||
FE
|
if b == 0: return 0 |
| ||||||||||||||||||||||||
FF
|
return b |
|