Skocz do zawartości

[Bascom] CRC32 z sumy wartości wyrazów 0...255


mesmariusz

Pomocna odpowiedź

STK500 tez pracuje w trybie half-duplex. PC wysyla polecenie, AVR odpowiada. Co prawda RS232 pracuje w pelnym dupleksie, ale polowa po prostu nie jest wykorzystywana - wiec akurat ten aspekt RS485 nie powinien byc problemem. Wiecej pracy bedzie przy adresowaniu wiekszej liczby urzadzen podpietych do RS485, ale to tez niewielki problem.

Nie chodzilo mi o kopiowanie, ani nawet wykorzystywanie gotowca, ale popatrzenie co i jak zostalo tam zrobione. Zobacz jaki jest format ramki, jakie sa pola (np. numer pakietu) - na ogol takie formaty powstaja na podstawie wielu doswiadczen, wiec mozna sie z nich sporo nauczyc, zamiast popelniac bledy zaczynajac wszystko od nowa.

Gotowy format ma jeszcze jedna zalete - mozna zaczac pisac od "dzialajacego" kodu, czyli zastosowac cos na wzor refaktoryzacji. Przykladowo najpierw uruchamiasz avrdude i gotowy bootloader - mozesz sprawdzic, czy dziala i oczywiscie powinien dzialac bez problemu. Ale taki niby oczywisty test moze zaoszczedzic mnostwo godzin zmarnowanych na szukanie bledu w kodzie, gdzie np. uszkodzony jest kabelek.

Dalej mozna zastapic fragment dzialajacego systemu, np. napisac pierwszy fragment bootloadera, ktory bedzie tylko odsylal nazwe urzadzenia - i znowu wykorzystujac gotowy avrdude przetestowac.

Dzieki temu duzo latwiej jest pisac program, w razie bledu mozna szybciej sie zorientowac co nie dziala.

A z czasem i zebranym doswiadczeniem, mozna spokojnie przejsc na wlasny format - bo i dlaczego nie.

Link do komentarza
Share on other sites

Hm, ale tu chyba jest trochę inny przypadek. Kolega ma już działającą sieć 485 z jakimś protokołem i jego timingami, ramkami, bla bla bla.. i chce to rozszerzyć o przesyłanie kodów dla bootloadera. Jak rozumiem, ta nowość musi być zgodna z tym co już zrobił, bo trochę szkoda włożonej pracy. Tak więc mamy już węzły końcowe 485, które coś tam nasłuchują, coś już rozumieją i czekają na ramkę zaadresowaną do nich osobiście. A teraz chcemy zrobić nowe ramki niosące kod i te mają być w jakiś sposób inne - bo uzupełnione kodem kontrolnym, czy tak? Weź może napisz jak to co chcesz z robić ma się do tego co już działa. Czy ma to mieć jakieś powiązania, czy robisz zupełnie nową rzecz i może ona być dowolna. Jeżeli to pierwsze, to i tak nie mamy wyjścia, Elvis sobie tylko strzępi język, bo trzeba kontynuować Twoją dotychczasową pracę. Jeżeli to drugie, moje dywagacje o warstwach można potłuc o kant tyłka a Ty powinieneś wziąć gotowy program i nie bawić się - jak to już zostało powiedziane - w wymyślanie koła.

Trochę nie rozumiem (znowu..) tego motywu o kierunku transmisji. Czy ten Twój RS jest dwu- czy czteroprzewodowy? Czy połączyłeś wszystkie węzły tylko jedną parą różnicową? Bo jeśli tak (masz MAX485 więc chyba nie ma innej opcji), to przecież jakoś musisz zmieniać kierunek pracy każdego transceivera i cała ta gadka o pinie sterującym kierunkiem jakoś mi tu nie pasuje. Ogarnij się napisz jak to jest teraz zrobione. Co działa i jak ma się ten nowy bootloader do wszystkiego co już zrobiłeś. Czy możesz/chcesz modyfikować istniejący protokół, co działa na PC, co działa w węzłach itd.. Bo rozmywamy się w dyskusję o wyższości jednych Świąt nad drugimi. Z przykładów z różnych powodów jakoś korzystać nie chcesz/nie możesz a utknąłeś na - wydawałoby się - prostej rzeczy. Gdzie jest problem?

BTW: XMODEM to kolejna warstwa: prosty protokół, ale nie nadaje się do pracy interaktywnej w rodzaju "PC - programator". Został wymyśłony wieki temu do prostego, jednokierunkowego przesyłania plików przez modem telefoniczny i wymaga składania informacji po stronie odbiorczej w całość. O ile pamiętam jedna z jego wersji ma zaimplementowane CRC więc możesz podejrzeć jak to się robi poprawnie. A nie jest to rocket science. Mając funkcję liczenia wielomianu po prostu wołasz ją dla całego kontrolowanego pola danych a potem wysyłasz wynik operacji. Po drugiej stronie robisz to samo tylko zamiast wysyłania - sprawdzasz poprawność. To tyle.

Link do komentarza
Share on other sites

UART przesyła bajt danych, ale oprócz tego (jak już wspomniałem gdzieś wcześniej) może robić parę innych pożytecznych rzeczy. Przede wszystkim nadajnik może opatrywać wysyłane bajty w bit parzystości. Odbiornik może (i powinien) ją sprawdzać - masz do tego specjalną flagę błędu. Czy obsługujesz parzystość? To podstawowa kontrola poprawności przesyłanych bajtów, masz ją zupełnie za darmo i grzechem jest z tego nie skorzystać. Kolejna fajna właściwość UARTa to sztywny format ramki.

Obecnie nie wykorzystuję kontroli parzystości. Parametry transmisji to: 4800,8N1.

Urządzenia pracują w sieci RS485 i połączone są pojedynczą parą przewodów (2 przewody A oraz B). Noga 4 (DI) MAX485 wpięta do TxD mikrokontrolera, noga 1 (DO) MAX485 wpięta do RxD mikrokontrolera, nogi 2 i 3 MAX-a spięte razem i podłączone do któregoś z wyprowadzeń mikrokontrolera. Nie udało mi się znaleźć gotowca bootloadera, który wspiera taki system połączenia).

W moim systemie możliwa jest transmisja wyłącznie w jednym kierunku. Komputer PC z konwerterem RS232 <-> RS485 jest masterem. Kiedy pisałem o automatycznym przełączaniu się kierunku transmisji miałem na myśli taki konwerter RS232 do RS485 (lub USB do RS485), który w zależności od tego czy PC nadaje czy nie przełącza się odpowiednio na nadawanie / odbiór. Innymi słowy konwerter ma po stronie RS485 wyłącznie 2 linie A oraz B (nie posiada linii sterującej kierunkiem transmisji).

Urządzenia sterowane nasłuchują. Gdy urządzenie nasłuchujące zobaczy swój adres (dostanie specjalną informację) uaktywnia się. Od tej pory "bierze do siebie" wszystkie napływające dane, aż do czasu, kiedy zostanie poinformowane, że zostało zwolnione. Wszystkie inne urządzenia ignorują to co się dzieje na linii transmisyjnej. Żadne też nie odezwie się wcześniej nie zapytanie (nie uaktywnione).

Oprócz 8/9 bitów informacyjnych (8 danych + ew.parzystość) nadajnik wysyła tzw. bit startu i 1 lub 2 bity stopu. Odbiornik może (a u Ciebie powinien) to sprawdzać. Gdzieś w rejestrach UARTa masz kolejną flagę - jej ustawienie oznacza, że odbiornik wykrył tzw. błąd ramki czyli brak bitu stopu. Oznacza to jakąś masakrę na linii przesyłowej co praktycznie z definicji powinno wykluczać odebrane dane jako coś sensownego. Taka kaszana w torze przesyłowym może bardzo łatwo zajść właśnie w RS485, gdy dwóch na raz próbuje nadawać.

Nasłuchując napływających danych korzystam z przerwania urxc i wbudowanych funcji Bascom-a. Znaki (bajty) napływające na uart są łączone w string. Po wykryciu enter-a bufor jest czyszczony, zaś string jest parsowany i wyszukiwane są w nim polecenia sterujące. Następuje interpretacja i wykonywanie poleceń. Urządzenie wykona dane zadanie, odpowie coś po uarcie (komputer PC przełączył się przecież automatycznie w tryb odbioru) a następnie znów oczekuje na kolejne napływające polecenia.

Jeżeli to już za Tobą, masz kolejną warstwę - łącza danych - czyli przesyłane ramki. Opowiedz nam o nich. Jak je skonstruowałeś, jak wyglądają ich pola i czy strona odbiorcza ma szansę już teraz - bez CRC - zauważyć, że ramka nie jest pełna, przyszła w części lub w podobny sposób jest uszkodzona.

Jak wyżej. Standardowe 4800, 8N1. Słucham napływających znaków, łączę je w string, po enterze analizuję string jaki się "zlepił", wyszukuję poleceń, wykonuję. Póki co nie kontroluję tego (przekłamane polecenie po prostu nie zostanie rozpoznane, a więc też nie zostanie wykonane - zostanie zignorowane).

Najważniejsza chyba informacja - po stronie PC nie wykorzystuję żadnego softu, który potrafiłby obsłużyć błędy, retransmisję. Na PC po prostu otwieram terminal / port i z palca wydaję komendy, które wykonywane są posłusznie przez zaadresowane urządzenie.

Dopiero gdy tak podstawowe rzeczy jak nagłówek ramki, licznik długości, pole danych i znacznik końca są prawidłowe, można zabierać się za test samej zawartości poprzez liczenie jakiegoś kodu kontrolnego. Czy robisz to wszystko w swoich programach?

Jak wyżej - czyli u mnie wygląda to wszystko dużo bardziej trywialnie.

BTW: Kiepsko, że nie zadbałeś o jakiś sprzętowy mechanizm wymuszania na wszystkich węzłach wejścia w stan RESET i startu bootloadera. Wystarczyło np. sprzętowo wykrywać stan BREAK na czas dłuższy niż ileśtam ms. Taka sytuacja normalnie nigdy nie ma miejsca, a miałbyś wygodny sposób sprowadzania porządku w systemie i restartu każdego węzła. Teraz musisz wierzyć, że napisany program jest przynajmniej na tle dobry, by pozwolił na wejście do bootloadera. Marne to rozwiązanie.

Wcześniej (kiedy nie myślałem jeszcze o bootloaderze nie było to potrzebne. Zormawiało z mną wyłącznie urządzenie wywołane do odpowiedzi. Wszystkie pozostałe (mimo, że otrzymywały te same dane) całkowicie ignorowały transmisję.

Hm, ale tu chyba jest trochę inny przypadek. Kolega ma już działającą sieć 485 z jakimś protokołem i jego timingami, ramkami, bla bla bla.. i chce to rozszerzyć o przesyłanie kodów dla bootloadera. Jak rozumiem, ta nowość musi być zgodna z tym co już zrobił, bo trochę szkoda włożonej pracy. Tak więc mamy już węzły końcowe 485, które coś tam nasłuchują, coś już rozumieją i czekają na ramkę zaadresowaną do nich osobiście. A teraz chcemy zrobić nowe ramki niosące kod i te mają być w jakiś sposób inne - bo uzupełnione kodem kontrolnym, czy tak?

Dokładnie tak. Nie jest dla mnie żadnym problemem dorobienia kolejnej komendy w stylu "przejdź w tryb bootloadera". Urządzenie wywołam po staremu, przy starych parametrach transmisji itd, itp. Na upartego parametry transmisji w trybie bootloadera mogą kompletnie różnić się od tech spoza trybu bootloadera. Jedyne musi pozostać ten sam pin sterujący kierunkiem transmisji (gdyż tak wykonane zostało PCB). Nie znalazłem dotychczas bootloadera (wielu twórców udostępnia aplikację na PC, ale zarówno kod aplikacji jak i bootloadera są zamknięte i pozostają tajemnicą autora) który pozwalałby wybrać pin sterujący kierunkiem transmisji (nawet jeśli jakiś bootloader jest opisany jako "wspierający RS485").

BTW: XMODEM to kolejna warstwa: prosty protokół, ale nie nadaje się do pracy interaktywnej w rodzaju "PC - programator". Został wymyśłony wieki temu do prostego, jednokierunkowego przesyłania plików przez modem telefoniczny i wymaga składania informacji po stronie odbiorczej w całość.

A to jest dobry przykład na spuentowanie ślepego podążania za gotowymi przykładami. XMODULO zostało zaimplementowane przez twórcę Bascom-a w jego kodzie samplowym bootloader.bas. Od próby zrozumienia / interpretacji tego kodu zaczynałem niełatwą przygodę z bootloaderami. Dziś zacząłbym po prostu od noty: http://www.atmel.com/images/doc1644.pdf - bo póki co nie udało mi się znaleźć lepiej opisujących to zagadnienie materiałów.

Link do komentarza
Share on other sites

Nie obraź się, ale że wygląda tak żałośnie, że nie wiadomo w co ręce włożyć. System zrobiony na sznurkach i poparty zapałkami. Niby RS485, ale tylko w jedną stronę. Po co Ci CRC skoro odbiornik nie może w żaden sposób zareagować na błędy? To wygląda jakbyś na pustyni starał się kupić na e-bayu śmigło do budowanego właśnie samolotu nie mając zapasu wody na przeżycie do wieczora.

Zajmij się najpierw protokołem pewnego przesyłania ramek w obie strony. Niezłym startem może być obejrzenie założeń do MODBUSa:

http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf

http://www.modbus.org/docs/Modbus_over_serial_line_V1.pdf

Strasznie wygląda tylko na początku. To uznany, dobry standard przemysłowy mający swoją emanację również na fizycznym łączu RS485. Poczytaj o tym. Każdy węzeł ma pewien zestaw rejestrów i realizuje pewien zestaw komend. Dokładnie określone są działania jednej i drugiej strony w przypadkach różnych błędów. Całość jest duża, nie musisz realizować wszystkiego, ale chociaż przyjrzyj się jak można to zrobić - nawet pod kątem Twoich małych urządzeń. Masz do tego biblioteki na PC i na małe procesorki też:

http://playground.arduino.cc/Code/ModbusMaster

http://www.freemodbus.org/index.php?idx=32

Twój bootloader może realizować minimalnie potrzebną implementację tego protokołu i wciąż będzie zgodny z całym systemem - jeżeli reszta klocków 485 będzie to rozumiała. Zastanów się, bo co prawda na kolanie możemy wymyślić pięć innych - może i prostszych - protokołów, ale powinieneś zacząć doceniać siłę standardów i wsparcie jakie możesz uzyskać je stosując. Po prostu zabierz się za to od dobrej strony.

A tak czy tak, musisz zacząć od dopasowania swojego systemu do transmisji dwukierunkowych. Jak zrozumiałem nie masz half-duplexu tylko simplex - dane idą tylko w jedną stronę. Musisz "ożywić" linię sterowania kierunkiem a MODBUS na takim łączu (wtedy już naprawdę half-duplexowym) pracuje bardzo dobrze w milionach sterowników przemysłowych.

Co Ty na to?

BTW: No i chyba trzeba powiedzieć BASCOMowi papa...

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Po co Ci CRC skoro odbiornik nie może w żaden sposób zareagować na błędy?

Ale gdzie tu jest problem? Przecież może zareagować (zarówno PC jak i uC). Wraz z ciągiem 256 bajtów wysłana może zostać suma kontrolna policzona przez PC. Mikrokontroler po odebraniu 256 bajtów i sumy kontrolnej może policzyć własną sumę kontrolną z otrzymanych danych i porównać z sumą kontrolną policzoną przez PC.

Aplikacja na PC informuje mikrokontroler, że zacznie wysyłać dane, przełącza się na odbiór i oczekuje na odpowiedź. Mikrokontroler odbiera tę informację, przełącza się na nadawanie i potwierdza PC czy jest gotowy na przyjęcie danych, po czym znowu przełącza się na odbiór. PC otrzymawszy potwierdzenie przełącza się na nadawanie i wysyła ciąg 256 bajtów oraz policzoną sumę kontrolną, i znów przełącza się na odbiór. Mikrokontroler liczy własną sumę kontrolną, porównuje z tą otrzymaną, po czym przełącza się na nadawanie i informuje PC o tym, czy udało się odebrać i zapisać do pamięci flash poprawny zestaw danych. Jeśli PC odbierze odpowiedź twierdzącą, poinformuje uC, że będzie wysyłał kolejną stronę pamięci (kolejne 256 bajtów), jeśli otrzyma odpowiedź negatywną, poinformuje mikrokontroler, że ponownie wyśle tą samą stronę. I tak będą ze sobą gadać i gadać, aż flashowanie dobrnie do końca. Ja generalnie nie widzę problemu. Kwestia napisania chcących se sobą gadać aplikacji na PC i bootloadera. Między PC i mikrokontrolerem połączenie wyłącznie po 2 przewodach (brak wyprowadzonej linii sterującej kierunkiem transmisji na zewnątrz urządzeń.

Całą resztę przyjmuję ze zrozumieniem, trudno mi się co najwyżej zgodzić z tezą, że procesu w chwili obecnej nie można kontrolować. Patrząc na to, co napisałem powyżej, wydaje mi się, że można.

PS. Zależy mi na tym, by dla wszystkich było jasne, że (abstrahując już od bootloadera) mój system jest dwukierunkowy. Komendy są wysyłane do slave-ów, one wykonują swoją robotę i odpowiadają. Wykonują swoją pracę i odpowiadają w ułamkach sekund (człowiek i tak nie zdążył by wprowadzić i wysłać kolejnych rozkazów, więc póki jedną stroną jest człowiek problem nie występuje. Jeśli zamiast człowieka za ster posadzimy aplikację i każemy jej poczekać ułamek sekundy przed wysłaniem kolejnych poleceń (choćby po to, by aplikacja mogła zapoznać się z odpowiedzią) również nic złego się nie wydarzy. Obie strony muszą natomiast znać reguły, by nie wysłać jakiejś informacji zbyt szybko.

Link do komentarza
Share on other sites

"W moim systemie możliwa jest transmisja wyłącznie w jednym kierunku" - Zrozumiałem to dosłownie.

OK, my już mniej więcej wiemy jak to Twoje cudo działa, Ty dostałeś wiele propozycji i tematów do przemyślenia. Co proponujesz? Na czym chcesz się teraz skupić? Czytasz, zastanawiasz się i wracasz po tygodniu, czy próbujesz popychać to co już jest? Tematowi potrzeba konkretnych decyzji i pytań.

Link do komentarza
Share on other sites

OK, my już mniej więcej wiemy jak to Twoje cudo działa, Ty dostałeś wiele propozycji i tematów do przemyślenia. Co proponujesz? Na czym chcesz się teraz skupić? Czytasz, zastanawiasz się i wracasz po tygodniu, czy próbujesz popychać to co już jest? Tematowi potrzeba konkretnych decyzji i pytań.

Najpierw przejrzę podlinkowane dokumenty i rozwiązania, aczkolwiek nie czuję jakiejś wielkiej siły i możliwości by brnąć w to głęboko, tym bardziej, że nie wiążę z tym jakoś szczególnie swojej przyszłości zarobkowej. Ciągle widzę to bardziej jako chęć zamknięcia pewnego etapu i zagwarantowania sobie środowiska zapewniającego zdalny rozwój systemu (takie tam dziwne hobby z dzieciństwa). Z jednej strony fajnie byłoby to wszystko zrobić zupełnie od nowa i w C (nawet nie ingerując w sprzęt i zostając przy opisanym wyżej half dupleksie). Z drugiej wiem, że jeśli dotychczas nie udało mi się znaleźć na tyle czasu by zamknąć temat po staremu, to już raczej nie znajdę go teraz na tyle, by zaczynać wszystko od początku. W tej sytuacji (tak podejrzewam), że pójdę raczej w kierunku napisania bootloadera w C++ wg. algorytmu z postu wyżej. Chyba, że rzeczywiście zmieni mi się jakoś sytuacja korpo-praco-rodzinno-życiowa i znajdę "drugie życie" z nową iskrą (na co raczej średnio się zapowiada). Ale nie mówię nie. Temat trudny, ale też ciekawy.

Jak ruszę coś w temacie wrócę, dam znać co słychać. Może przygotuję sobie jakieś środowisko testowe (okrojony firmware udający bootloader), a w C++ zacznę pisać aplikację udającą narzędzie do obsługi bootloadera, zasymuluję komunikację od A do Z. W C++ też raczej nie programuję (też wszystko nowe, trzeba będzie nauczyć się otwierać COM, konfigurować parametry transmisji, pisać i czytać z portu). Zakładam, że biblioteki boost też dają jakieś fajne w tym temacie wsparcie. -> Chyba właśnie znalazłem coś na dobry start: http://www.ridgesolutions.ie/index.php/2012/12/13/boost-c-read-from-serial-port-with-timeout-example/

Ale sobie hobby znalazłem - taka trochę niekończąca się opowieść... A trzeba było znaczki zbierać 😉

Dziękuję i pozdrawiam.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.