Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 27 lis 2024, o 11:29


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 21 ] 
Autor Wiadomość
PostNapisane: 28 mar 2014, o 09:31 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

Jak wiadomo jedna ramka CAN potrafi przesyłać jednorazowo 8 bajtów danych. W niektórych przypadkach jest to wystarczająca ilość, jednak ja lubię komunikację ASCII z wykorzystaniem komend AT lub innych poleceń zapisywanych językiem, który ma choć trochę wspólnego z językiem naturalnym. W przypadku RS232 nie ma z tym żadnego problemu (w wymianie komunikatów uczestniczą tylko dwie strony), podobnie jak przy zastosowaniu Internetu/Ethernetu (stos TCP/IP załatwia kwestię adresowania i na końcu dostajemy już całą wiadomość oznaczoną numerem IP nadawcy i odbiorcy).

Natomiast nie bardzo wyobrażam sobie, jak samemu mógłbym rozwiązać kwestię takiej komunikacji przy zastosowaniu magistrali CAN. Wiadomo, że do bufora odbiorczego będą trafiały kolejno znaki od różnych nadawców. Istnieje duża możliwość, że w pewnym momencie, podczas transmisji wtrąci się nam inne urządzenie i poszczególne komunikaty się ze sobą przemieszają.

W tej chwili do głowy przychodzi mi tylko jedno rozwiązanie:

Ustawiamy odpowiednio duży bufor pierścieniowy, kilkukrotnie większy niż największa spodziewana długość przychodzącego komunikatu. Do bufora zapisujemy treść kolejno przychodzących ramek, oznaczając je identyfikatorem nadawcy i ewentualnie odbiorcy (w razie, gdybyśmy chcieli odróżnić te adresowane bezpośrednio do nas od broadcastowych). Wychodzi więc na to, że bufor raczej nie może być tablicą typu char, ale raczej tablicą typu strukturalnego, mieszczącą kolejno przychodzące ramki.
W trakcie odbioru analizujemy na bieżąco treść danych, poszukując znaku końca komendy (np. "\r\n\"). Jeśli go wykryjemy, ustawiamy odpowiednią flagę, przekazując identyfikator nadawcy.

Jeśli flaga zostanie ustawiona, w pętli głównej wywołuje się zdarzenie, które czyta kolejne komórki bufora sprawdzając, czy pochodzą od naszego nadawcy. Jeśli tak, kopiuje je do stringa, który potem będzie analizowany.
Widzę tu jednak kilka problemów. Po pierwsze podczas sprawdzania bufora trzeba by kopiować niepasujące ramki na początek, żeby fragment przesyłanej informacji od innego nadawcy nie odszedł w niebyt po jednorazowym odczytaniu. Problem mógłby się pojawić, gdyby w trakcie tej czynności w przerwaniu RX pojawiła się nowa ramka. Po drugie należałoby ustawić jakiś timeout inicjujący selektywne czyszczenie bufora, żeby w przypadku otrzymania niepełnej komendy jej fragment nie zaśmiecał pamięci.

Czy takie podejście wystarczy, czy też istnieje prostsze/lepsze/bardziej standardowe rozwiązanie?
Może jest już jakaś gotowa biblioteka i nie muszę wcale wyważać otwartych drzwi?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 10:31 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 maja 2013
Posty: 174
Lokalizacja: Kraków
Pomógł: 8

Czy ty zamierzasz programowo obłsugiwać transmisję CAN?
Bo mam wrażenie że zbytnio kombinujesz.
Magistrala Can jest bardzo łatwa i przyjemna w implementacji.
W procku np. AT90CAN32 jest cała sprzętowa obsługa CAN.
Nie potrzeba żadnej biblioteki i kombinowania z "pierścieniami".
Możesz sobie wysyłać dane w ASCII, dla CAN to bez różnicy.

_________________
Rozwój i utrzymywanie Oprogramowania



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 10:33 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

0livaw napisał(a):
W procku np. AT90CAN32 jest cała sprzętowa obsługa CAN.
Nie potrzeba żadnej biblioteki i kombinowania z "pierścieniami".
Możesz sobie wysyłać dane w ASCII, dla CAN to bez różnicy.


Hmm... Czyżbym czegoś nie wiedział? Bo zawsze wydawało mi się, że od strony sprzętowej możliwe jest przesyłanie ramek zawierających jedynie 8 bajtów danych. Jeśli chce się wysłać więcej (a zwykle trzeba, gdy wysyłamy zapytania albo odpowiedź ASCII w formie komendy AT) konieczne jest użycie kilku ramek i ich programowe poskładanie.
Chyba, że ta część także jest obsługiwana sprzętowo, przez kontroler?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 10:45 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 maja 2013
Posty: 174
Lokalizacja: Kraków
Pomógł: 8

Atlantis napisał(a):
Hmm... Czyżbym czegoś nie wiedział? Bo zawsze wydawało mi się, że od strony sprzętowej możliwe jest przesyłanie ramek zawierających jedynie 8 bajtów danych. Jeśli chce się wysłać więcej (a zwykle trzeba, gdy wysyłamy zapytania albo odpowiedź ASCII w formie komendy AT) konieczne jest użycie kilku ramek i ich programowe poskładanie.
Chyba, że ta część także jest obsługiwana sprzętowo, przez kontroler?


No tak, jest 8 bajtów danych. Nie wiem jak duże liczby zamierzasz przesyłać, możesz sobie podzielić że np. jedna liczba to 16 bitów (2 bajty).
A jak ci branie miejsca w jednej ramce to wysyłasz następną. Nie rozumiem w czym problem ...

_________________
Rozwój i utrzymywanie Oprogramowania



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 10:59 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

0livaw napisał(a):
No tak, jest 8 bajtów danych. Nie wiem jak duże liczby zamierzasz przesyłać, możesz sobie podzielić że np. jedna liczba to 16 bitów (2 bajty).
A jak ci branie miejsca w jednej ramce to wysyłasz następną. Nie rozumiem w czym problem ...


Wydaje mi się, że dosyć dokładnie opisałem problem w mojej pierwszej wypowiedzi.
Ja nie chcę wysyłać danych w formie binarnej, ale w formie ciągów ASCII.
Innymi słowy zamiast komunikacji wyglądającej następująco:
zapytanie: 0F05
odpowiedź: 0F0501

Chcę przesłać coś takiego:
zapytanie: AT+LED?5\r\n
odpowiedź: +LED5: ON\r\n

Jak widzisz nie mieścimy się w jednej ramce... Musimy wysłać wiadomość w kilku, a to rodzi problemy, które opisałem powyżej.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 11:08 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 maja 2013
Posty: 174
Lokalizacja: Kraków
Pomógł: 8

Atlantis napisał(a):
Wydaje mi się, że dosyć dokładnie opisałem problem w mojej pierwszej wypowiedzi.
Ja nie chcę wysyłać danych w formie binarnej, ale w formie ciągów ASCII.
Innymi słowy zamiast komunikacji wyglądającej następująco:
zapytanie: 0F05
odpowiedź: 0F0501

Chcę przesłać coś takiego:
zapytanie: AT+LED?5\r\n
odpowiedź: +LED5: ON\r\n

Jak widzisz nie mieścimy się w jednej ramce... Musimy wysłać wiadomość w kilku, a to rodzi problemy, które opisałem powyżej.



W CAN chodzi o to że (podobnie jak w modbus) że wysyłasz/odbierasz ramki danych z identyfikatorem. Możesz przypisać numery identyfikacyjne konkretnym komendom AT.

_________________
Rozwój i utrzymywanie Oprogramowania



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 11:21 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

0livaw napisał(a):
W CAN chodzi o to że (podobnie jak w modbus) że wysyłasz/odbierasz ramki danych z identyfikatorem. Możesz przypisać numery identyfikacyjne konkretnym komendom AT.


Tak, wiem. Jednak to nie rozwiązuje wszystkich problemów. Co z sytuacją, gdy będę chciał przesłać ciąg znaków ASCII do wyświetlenia na ekranie współpracującego urządzenia?
Poza tym zaproponowane przez Ciebie podejście wymaga tworzenia osobnych funkcji, które zajmowałyby się tłumaczeniem komend i obsługą poleceń w formie binarnej. Gdybym mógł przesyłać ciągi znaków, mógłbym nimi karmić standardowe funkcje parsujące. Jakoś taka forma komunikacji bardziej mi odpowiada.

CAN to przecież tylko medium transmisyjne. Byłbym mocno zaskoczony, gdyby nie dało się na nim odpalić żadnej wyższej warstwy, która zajmowałaby się przesyłaniem większej ilości danych, bez mieszania ze sobą różnych komunikatów, których fragmenty przychodzą naprzemiennie. Modbus też nie jest przecież jedynym zastosowaniem RS485, którą to magistralę można wykorzystać do komunikacji via ASCII.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 11:40 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 maja 2013
Posty: 174
Lokalizacja: Kraków
Pomógł: 8

Atlantis napisał(a):

Tak, wiem. Jednak to nie rozwiązuje wszystkich problemów. Co z sytuacją, gdy będę chciał przesłać ciąg znaków ASCII do wyświetlenia na ekranie współpracującego urządzenia?
Poza tym zaproponowane przez Ciebie podejście wymaga tworzenia osobnych funkcji, które zajmowałyby się tłumaczeniem komend i obsługą poleceń w formie binarnej. Gdybym mógł przesyłać ciągi znaków, mógłbym nimi karmić standardowe funkcje parsujące. Jakoś taka forma komunikacji bardziej mi odpowiada.

CAN to przecież tylko medium transmisyjne. Byłbym mocno zaskoczony, gdyby nie dało się na nim odpalić żadnej wyższej warstwy, która zajmowałaby się przesyłaniem większej ilości danych, bez mieszania ze sobą różnych komunikatów, których fragmenty przychodzą naprzemiennie. Modbus też nie jest przecież jedynym zastosowaniem RS485, którą to magistralę można wykorzystać do komunikacji via ASCII.


Tak coś czułem że myślisz o przesyłaniu np. grafiki.
Ale nic nie stoi na przeszkodzie aby pchać w CAN-a dane z grafiką. Po prostu tam gdzie byś to wpychał monitorowałbyś czy procek za każdym razem dostał arbitraż do magistrali.
Jeśli by nie dostał arbitrażu to wtedy powtórzyć transmisję ramki.
A z drugiej strony magistrali odbierałby dane Twoje funkcje parsujące.
Może mało widziałem, ale dotychczas nie spotkałem się w przemyśle z transmisją tak dużej ilości danych po CAN, a tym bardziej w modbus.

_________________
Rozwój i utrzymywanie Oprogramowania



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 11:53 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

0livaw napisał(a):
Tak coś czułem że myślisz o przesyłaniu np. grafiki.


Grafiki w mniejszym stopniu, głównie chodzi mi o teksty. A jeśli już miałbym przesyłać teksty, to wolałbym, żeby cała komunikacja była realizowana za pomocą w miarę czytelnych komend, a nie pojedynczych bitów kodujących poszczególne instrukcje i odpowiedzi.

Cytuj:
Ale nic nie stoi na przeszkodzie aby pchać w CAN-a dane z grafiką. Po prostu tam gdzie byś to wpychał monitorowałbyś czy procek za każdym razem dostał arbitraż do magistrali.
Jeśli by nie dostał arbitrażu to wtedy powtórzyć transmisję ramki.


No dobrze. Może nie zrozumiałem do końca tej idei, ale to chyba nie rozwiązuje problemu o którym pisałem. CAN to magistrala multimaster. W każdym momencie może się zdarzyć, że inne urządzenie zażyczy sobie nadawać do tego, które już odbiera jakąś wiadomość. Ramki się ze sobą przemieszają w jednym buforze odbiorczym. Trzeba dysponować odpowiednim "stosem", który wyłuska i zwróci do dalszej analizy całe ciągi znaków tak, jak zostały nadane. Można by to oczywiście zrobić w najbardziej prostacki sposób i dla każdego potencjalnego nadawcy wydzielić osobny bufor odbiorczy, jednak to już byłoby zdecydowaną przesadą. Przesadą pożerającą mnóstwo pamięci. ;)


Cytuj:
Może mało widziałem, ale dotychczas nie spotkałem się w przemyśle z transmisją tak dużej ilości danych po CAN, a tym bardziej w modbus.


Nikt nie mówi tutaj o zastosowaniach profesjonalnych. Po prostu magistrala CAN pasuje mi z kilku powodów - daje możliwość jednoczesnej pracy kilku urządzeń w trybie master (jak np. Ethernet) ale nie wymaga przy tym dodatkowej infrastruktury (jak chociażby switche). Wystarczy przeciągnąć kawałek kabla pomiędzy urządzeniami. Jednak wiem, że prawdopodobnie pojawi się konieczność przesyłania większej ilości danych, niż można zmieścić w pojedynczej ramce. Szukam więc rozwiązania, które by mi na to pozwoliło.

Nie chce mi się wierzyć, że nikt wcześniej tego nie robił. ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 12:09 
Offline
Użytkownik

Dołączył(a): 20 wrz 2013
Posty: 647
Zbananowany użytkownik

Pomógł: 101

http://en.wikipedia.org/wiki/CAN_bus#Higher_layer_implementations ??

_________________
+++++[>++++<-]>[>++++++<-]>.---------.+++.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 12:17 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 maja 2013
Posty: 174
Lokalizacja: Kraków
Pomógł: 8

Atlantis napisał(a):

No dobrze. Może nie zrozumiałem do końca tej idei, ale to chyba nie rozwiązuje problemu o którym pisałem. CAN to magistrala multimaster. W każdym momencie może się zdarzyć, że inne urządzenie zażyczy sobie nadawać do tego, które już odbiera jakąś wiadomość. Ramki się ze sobą przemieszają w jednym buforze odbiorczym. Trzeba dysponować odpowiednim "stosem", który wyłuska i zwróci do dalszej analizy całe ciągi znaków tak, jak zostały nadane. Można by to oczywiście zrobić w najbardziej prostacki sposób i dla każdego potencjalnego nadawcy wydzielić osobny bufor odbiorczy, jednak to już byłoby zdecydowaną przesadą. Przesadą pożerającą mnóstwo pamięci. ;)


Nie wiem jak to jest rozwiązane w innych prockach, ale w AT90CAN32 jest to sprzętowo zrobione w ten sposób że można mieć 15 buforów danych. I można zrobić w ten sposób, że dane
będą przychodzić do konkretnego bufora o określonym numerze ID. Dane o innym ID będą wrzucane do innego bufora bądź będą ignorowane. To chyba rozwiązuje Twój problem.



Atlantis napisał(a):
Nikt nie mówi tutaj o zastosowaniach profesjonalnych. Po prostu magistrala CAN pasuje mi z kilku powodów - daje możliwość jednoczesnej pracy kilku urządzeń w trybie master (jak np. Ethernet) ale nie wymaga przy tym dodatkowej infrastruktury (jak chociażby switche). Wystarczy przeciągnąć kawałek kabla pomiędzy urządzeniami. Jednak wiem, że prawdopodobnie pojawi się konieczność przesyłania większej ilości danych, niż można zmieścić w pojedynczej ramce. Szukam więc rozwiązania, które by mi na to pozwoliło.

Nie chce mi się wierzyć, że nikt wcześniej tego nie robił. ;)


Oczywiście, nie znaczy to że nikt tego nie robił.
Kilka lat temu była dyskusja na pl.misc.elektronika na temat przesyłania dużych ilości danych przez CAN.

_________________
Rozwój i utrzymywanie Oprogramowania



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 12:51 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

xor napisał(a):


O właśnie. To teraz rodzą się kolejne pytania:
1) Który z tych standardów jest na tyle lekko, by bez większego problemu mógł go uciągnąć ośmiobitowy MCU (zakładamy, że będzie on też musiał realizować inne zadania).
2) Czy któryś ze standardów spełniających pierwszy warunek posiada już odpowiednią bibliotekę, zgodną z AVR?


0livaw napisał(a):
Nie wiem jak to jest rozwiązane w innych prockach, ale w AT90CAN32 jest to sprzętowo zrobione w ten sposób że można mieć 15 buforów danych. I można zrobić w ten sposób, że dane
będą przychodzić do konkretnego bufora o określonym numerze ID. Dane o innym ID będą wrzucane do innego bufora bądź będą ignorowane. To chyba rozwiązuje Twój problem.


Dobrze, ale czy przypadkiem przez "bufor" nie rozumiemy tutaj przypadkiem miejsca w pamięci na jedną, przychodzącą właśnie ramkę? Bo jeśli tak, to w niczym nie pomaga. Nawet jeśli na początku miejsca jest więcej, to faktycznie na początku może się wydawać, że piętnaście urządzeń to dużo, jednak system po jakimś czasie może się rozrosnąć. :)
Poza tym wolałbym, żeby rozwiązanie było niezależne od sprzętu. Innymi słowy - jeśli w sieci zacznie pracować coś z MPC2515, chciałbym aby też mogło się komunikować z całą resztą na tych samych zasadach. Bez względu na to czy ma, czy też nie ma jakieś sprzętowe bufory.


Cytuj:
Kilka lat temu była dyskusja na pl.misc.elektronika na temat przesyłania dużych ilości danych przez CAN.


Pamiętasz może jakie były wnioski?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 13:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 maja 2013
Posty: 174
Lokalizacja: Kraków
Pomógł: 8

Atlantis napisał(a):
Dobrze, ale czy przypadkiem przez "bufor" nie rozumiemy tutaj przypadkiem miejsca w pamięci na jedną, przychodzącą właśnie ramkę? Bo jeśli tak, to w niczym nie pomaga. Nawet jeśli na początku miejsca jest więcej, to faktycznie na początku może się wydawać, że piętnaście urządzeń to dużo, jednak system po jakimś czasie może się rozrosnąć. :)
Poza tym wolałbym, żeby rozwiązanie było niezależne od sprzętu. Innymi słowy - jeśli w sieci zacznie pracować coś z MPC2515, chciałbym aby też mogło się komunikować z całą resztą na tych samych zasadach. Bez względu na to czy ma, czy też nie ma jakieś sprzętowe bufory.


Jeden bufor=jedna ramka. Ale czy nie można jednym buforem obsłużyć kilku urządzeń?
A czy możesz powiedzieć co chcesz zbudować? Bo mam wrażenie że to jest błądzenie we mgle...

Atlantis napisał(a):
Pamiętasz może jakie były wnioski?


Niestety nie pamiętam.

_________________
Rozwój i utrzymywanie Oprogramowania



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 mar 2014, o 14:33 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

0livaw napisał(a):
Jeden bufor=jedna ramka. Ale czy nie można jednym buforem obsłużyć kilku urządzeń?


Można, ale przeczytaj jeszcze raz moją pierwszą wypowiedź, bo w kółko wracasz do punktu wyjścia, pomijając wszystko co napisałem.

Mamy bufor odbiorczy, który pomieści jedną ramkę. Przesyłana wiadomość ma rozmiar większy od jednej ramki. Ramki trzeba więc na bieżąco odbierać i zapisywać w jakimś większym buforze, żeby zwalniały miejsce dla następnych danych.
No i teraz mamy problem, bo w przypadku magistrali CAN zawsze może wystąpić sytuacja, kiedy kilka urządzeń będzie nadawało wiadomość (serię ramek) do jednego odbiorcy. W takiej sytuacji albo będziemy musieli zastosować tyle osobnych buforów/tablic odbiorczych, ile mamy urządzeń (praktycznie nie do wykonania w małym MCU) albo ramki nam się przemieszają w jednej tablicy odbiorczej i w zdarzeniu uruchamianym po wykryciu otrzymania całej linii trzeba będzie jakoś wydzielić tylko te właściwe kawałki. I właśnie nie za bardzo mam pomysł, jak można by to zrealizować...


Cytuj:
A czy możesz powiedzieć co chcesz zbudować? Bo mam wrażenie że to jest błądzenie we mgle...


System automatyki domowej (sterowanie światłem, w przyszłości alarm, rolety itp.). W chwili obecnej pracuję nad wersją wykorzystującą Ethernet, w przyszłości jednak z paru względów wolałbym przerzucić się na CAN.
Tak, wiem - mógłbym przerobić to na komunikację bitową, mieszcząc całą komendę w jednej ramce. Jednak nie chcę sobie zamykać tej furtki. Jak mówiłem, istnieje spora szansa na to, że w pewnym momencie będę potrzebował funkcji przesyłania tekstu do wyświetlenia na innym urządzeniu. I co wtedy?

Zresztą w tym wypadku warstwa aplikacji nie ma nic do rzeczy. Chodzi o przesyłanie komend w postaci ciągów znaków ASCII, o rozmiarze większym niż jedna ramka CAN. To, co z tą komendą zrobi program nie ma już absolutnie nic wspólnego z zagadnieniem transmisji.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 mar 2014, o 13:24 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

Znalazłem coś takiego:
https://github.com/openxc/isotp-c

Opis standardu na Wikipedii mówi, że:

Cytuj:
It can carry up to 4095 bytes of payload per message packet.


Jednakże w opisie biblioteki na tej stronie zawarto następujące stwierdzenie:

Cytuj:
The current version supports only single frame ISO-TP messages. This is fine for OBD-II diagnostic messages, for example, but this library needs some additional work before it can support sending larger messages.


Ktoś mi może powiedzieć o co chodzi? Po co tworzyć taką bibliotekę, skoro nie potrafi ona wysyłać wiadomości dłuższych, niż jedna ramka? Przecież taką komunikację można załatwić już na starcie, przy pomocy tylko i wyłącznie tego, co oferują sprzętowe kontrolery CAN. Czyżby ktoś popełnił błąd w opisie?
Jeśli jednak przy pomocy tego można wysyłać i odbierać dłuższe wiadomości, to czy ta biblioteka ma szansę działać na (tych większych) ośmiobitowych AVR-ach (Mega644, Mega128, AT90CAN128)?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 kwi 2014, o 14:57 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

Chciałbym wrócić do tego tematu. Trochę doczytałem i bardzo obiecująco wygląda warstwa transportowa ISO 15765-2 (ISO-TP).
Opis można znaleźć TUTAJ.
Niestety w tej chwili nie czuję się jeszcze na siłach, żeby pisać swoją własną implementację w C.
Szukając jakiegoś rozwiązania natknąłem się na coś takiego: https://github.com/openxc/isotp-c

Niestety gdy już zacząłem się cieszyć, trafiłem w opisie na fragment, który ostudził mój entuzjazm:

"The current version supports only single frame ISO-TP messages. This is fine for OBD-II diagnostic messages, for example, but this library needs some additional work before it can support sending larger messages."

Wygląda na to, że wracamy do punktu wyjścia - biblioteka obsługuje ten protokół, ale najwyraźniej tylko celem zapewnienia kompatybilności przy przesyłaniu wiadomości od długości mniejszej niż jedna ramka. Jeśli dobrze rozumiem ten opis, to jak na razie nie obsługuje wiadomości przesyłanych w kawałkach.

Ktoś ma jakiś pomysł? Może istnieje jakaś biblioteka, a ja o niej nie wiem?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 kwi 2014, o 08:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 maja 2013
Posty: 174
Lokalizacja: Kraków
Pomógł: 8

Atlantis napisał(a):
Ktoś ma jakiś pomysł? Może istnieje jakaś biblioteka, a ja o niej nie wiem?


Raczej ciężko będzie ze znalezieniem darmowej biblioteki w necie. Nawet na p.m.e nie pomogli. Na Elektrodzie pytałeś?
Chyba trzeba będzie coś samemu napisać ...

_________________
Rozwój i utrzymywanie Oprogramowania



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 kwi 2014, o 08:32 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 21 cze 2012
Posty: 171
Pomógł: 5

Witam,
hmm to wydaje się być bardzo proste.
W przerwaniu od CAN RX robisz case po ID jakie będziesz odbierał. Następnie w case przepisujesz do tablicy poszczególne bajty jednocześnie inkrementując wskaźnik na tablicę. Jeśli napotkasz znak końca wiersza to kończysz przepisywanie i wystawiasz flagę odebrano. W main jeśli masz flagę to odpowiednio parsujesz dane i kasujesz flagę.
Przesyłałem tak kiedyś ciągi znaków i działało wyśmienicie.

W przerwaniu będziesz miał odbieranie znaków do znaku końca lini.

Pozdrawiam
R.L.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 kwi 2014, o 08:20 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

Lemosek napisał(a):
Witam,
W przerwaniu od CAN RX robisz case po ID jakie będziesz odbierał. Następnie w case przepisujesz do tablicy poszczególne bajty jednocześnie inkrementując wskaźnik na tablicę. Jeśli napotkasz znak końca wiersza to kończysz przepisywanie i wystawiasz flagę odebrano. W main jeśli masz flagę to odpowiednio parsujesz dane i kasujesz flagę.
Przesyłałem tak kiedyś ciągi znaków i działało wyśmienicie.


To nie ta część mnie najbardziej przeraża. Sam odbiór jest względnie łatwy do zrealizowania - wzorowałbym się tutaj na rozwiązaniu z zielonej książki, tylko tam był UART przesyłający po jednym bajcie, tutaj miałbym ramki mieszczące po kilka bajtów, które trzeba by dopisywać do tablicy.
Trzeba jednak pamiętać, że CAN jest magistralą multimaster. Zawsze istnieje możliwość, że ktoś zacznie nadawać w trakcie trwającej łączności - jakaś ramka wciśnie się pomiędzy ramki transmitowanej wiadomości. Jakoś to trzeba będzie obsłużyć, a z tym nie miałem jeszcze doświadczenia i po prostu liczyłem na to, że może ktoś już to za mnie zrobił. Wychodzi na to, że nie, więc pewnie w końcu powoli zabiorę się za pisanie jakiegoś rozwiązania. ;)

Generalnie chodzi o to, żeby oprogramować jakiś protokół komunikacyjny, np. wedle następujących zasad:
1) Nadawca pyta odbiorcy czy można rozpocząć przesyłanie wiadomości. Odbiorca odpowiada tak (jeśli jest wolny) lub nie (jeśli już trwa odbieranie jakiegoś komunikatu). W tym drugim przypadku prosi nadawcę o wstrzymanie się. Po timeoucie nadawca ponawia próbę nawiązania łączności.
2) Flaga trwającej transmisji ustawiana jest po odebraniu zapytania, na które udzielono pozytywnej odpowiedzi. Dopóki jest ustawiona, w przerwaniu RX dopisujemy kolejne bajty od konkretnego nadawcy do bufora. Flaga zostaje wyczyszczona po odebraniu znaku końca wiadomości lub upłynięciu określonego timeoutu od otrzymania ostatniej ramki.
2) Nawet w trakcie nadawania długiego komunikatu, złożonego z wielu ramek (np. ciąg ASCII) możliwe jest przesłanie niezależnego polecenia w formie jednej ramki (np. informacja o przerwaniu).

Standard ISO-TP ma to wszystko fajnie opisane. Teraz tylko jedynym problemem jest przerobienie tego na działający kod C. ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 kwi 2014, o 20:16 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 21 cze 2012
Posty: 171
Pomógł: 5

Witam,
kolego musisz chyba jeszcze doczytać o CAN.
Stosuję go na co dzień i uwierz mi będzie działało jak ci napisałem.
To właśnie, że jest multimaster powoduje, że nie obchodzi cię arbitraż magistrali, to dzieje się w kontrolerze CAN.
Jeśli wyślesz ramkę z danym ID to wszystkie urządzenia ją otrzymają. Teraz od ciebie zależy co z nią zrobisz. Nie ma czegoś takiego, że coś zginie bo inne urządzenie zacznie nadawać.

Pozdrawiam
R.L.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 kwi 2014, o 08:26 
Offline
Użytkownik

Dołączył(a): 05 gru 2013
Posty: 246
Pomógł: 0

Lemosek napisał(a):
Jeśli wyślesz ramkę z danym ID to wszystkie urządzenia ją otrzymają. Teraz od ciebie zależy co z nią zrobisz. Nie ma czegoś takiego, że coś zginie bo inne urządzenie zacznie nadawać.


Wydaje mi się, że nie do końca zrozumiałeś moją wypowiedź. Miałem na myśli nie tyle rozpłynięcie się ramki w niebycie, co jej przemieszanie się z inną wiadomością. Nie mogę zastosować prostego kolejkowania kolejno napływających "kawałków", tak jak ma to miejsce w przypadku magistrali z jednym urządzeniem master, np. RS485. Tam z góry wiadomo, że tylko jeden węzeł może w danej chwili nadawać i nic nam się nie wtrąci znienacka. Można sobie pozwolić na proste zapełnianie bufora kolejno napływającymi znakami.
W przypadku CAN trzeba jeszcze zaimplementować obsługę dodatkowych zachowań, jak rezerwowanie i zwalnianie linii na komunikację multiframe między dwoma urządzeniami. To już nie jest proste przesyłanie znaków i zapisywanie ich do bufora cyklicznego, ale miniaturowy stos. A na tym polu nie mam żadnego doświadczenia, stąd moje wątpliwości.

Przyznam, że wolałbym skorzystać z gotowego rozwiązania, jak to ma miejsce przypadku komunikacji Ethernetowej. Jeśli takiego nie ma, spróbuję coś samemu przygotować, ale pewnie pójdzie opornie. ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 21 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO