CAN Schnittstelle für FreeBSD

serie300

Well-Known Member
Hallo

habe ich im "Heute gelernt" Thread richtig gelesen, daß mit Socket CAN eine komplette Highlevel CAN Schnittstelle für CAN 2.0 und CAN FD in FreeBSD integriert werden soll, die unter sich Treiber für spezifische Adapter hat und auf die Eigenschaften von CAN abgestimmt ist?

Serie300
 
So hab ich @das.chaos auch verstanden. Ich kenn mich mit CAN etwas aus unter Linux und Windows. Wie es mit FreeBSD hier aussieht und was die Zukunft unter FreeBSD anbelangt kann ich nicht beantworten.
 
Okay, ... ist noch nicht fertig, aber ich befinde mich auf der Zielgeraden.

Anmerkung: das soll jetzt kein Egodram sein, d. h. ich mache das _nicht_ um mich zu profilieren, sondern weil ich derzeit etwas Zeit fuer sowas habe [oder etwas Langeweile] und NetBSD 8.0 mir eine Steilvorlage dafuer bot [danke!!!1!] bzw. mich CAN interessiert und mir etwas versuche ueber CAN beizubringen.

Die Software befindet sich noch im Entwicklungsstadium und bin dabei die Code-base "aufzuraeumen" [u. a. bei Inclusion-directives bzw. Header-files, da ich erstmal "drauflosportierte" und jetzt mit Korrekturen [da sind noch einge syntaktische und semantische Fluechtigkeitsfehler drinne] und Fine-tuning beschaeftige.

Wobei ich schon anfing, mich auf if_slcan(4) [als "geforktes" slip(4)] einzuschieszen, dann muss ich noch if_cansubr(4) etwas ueberarbeiten und vielleicht den netisr(4) Handler fuer NETISR_CAN nach raw_can.c verschieben, etc. pp..

Wenn die Software in einem benutzbaren Stadium ist [was diese definitiv noch _nicht_ ist], dann kann ich dazu mehr schreiben und dann auch wegen Bugfixes gesteinigt werden [aber bitte jetzt noch nicht]. :)

Wurde ein "fehlerfreies" Stadium erreicht, dann wird das auch in vnet(4) integriert, aber bis dahin ist es noch ein steiniger Weg.

Was ich mich aber frage, ob ich das lizensrechtlich richtig mache, da ich mich als Anfeanger [bzw. Amateur] betrachte und keinen Bock auf Stress habe?

Edit: ich habe es noch _nicht_ kompiliert, weil ich mich noch in der "Strategischen" Phase [siehe Definition in "Computer Networks" von Tannenbaum] befinde und mich mit MAC / LLC bzgl. ISO 11898-1 einarbeite.

Was mir aber Kopfschmerzen verursacht, ist die Implementierung von can_ctlinput(9) [und einiger anderer Komponenten] in AF_CAN Communication domain(9) von der Implementierung in NetBSD 8.0, da ich noch dabei bin herauszufinden, in welcher Teilschicht [entweder Protocol-layer oder Socket-layer, siehe usrreqs von CANPROTO_RAW] das zugeordnet wird, da auf mich das noch wie eine "Baustelle" wirkt?
 
Zuletzt bearbeitet von einem Moderator:
Hallo Chaos,

beim Netzwerk / Socket Anteil kann ich dir leider nicht viel helfen, aber evtl. bei CAN selber (mehr die Controller Ebene). Wenn du Code mit BSD oder GNU Lizenz wiederverwendest sollte es lizenzmäßig keine Probleme geben. M.W werden Lizenzen verlangt, wenn du einen CAN Controller baust - aber der ist ja auf den einschlägigen MCUs drauf. Hast du mit CAN gearbeitet oder kommst du mehr aus der UNIX Netzwerk Ecke?

Serie300
 
Eher UNIX Netzwerk Ecke.

Ich vermute ganz scharf, dass die Firmware von einem CAN Controller [oder Adapter???] schon Media Access Control sowie ein Interface fuer Link Layer Control integriert????

Der Socket-anteil ist easy [aehnlich wie socket(2)s ueber AF_ATM, so als hinkender "Vergleich"], weil bei AF_CAN der Protocol Control Block ein [simples] Mapping von einem Interface ueber ifnet(9) KPI und einem socket(9) implementiert, wo bspw. Sockets [eher Prozesse] ueber dem Index von Interface [bzw. Adapter] verbunden mit einem Filter bzgl. CAN-ID addressiert werden [was deutlich "angenehmer" als das Arbeiten mit einem Char-device ist].

${my_proto}_ctl{in,out}put(9) sind Dienstelemente bzw. Funktionen, die verwendet werden, um den Zestand der FSM eines Protokolles innerhalb den Teilschichten von Protocol-layer und Socket-layer von OS in einer communication domain(9) zu veraendern oder die FSM zu konfigurieren.

${my_proto}_ctlinput(9) eines beliebigen Protokolles erbringt Dienst von einer Schicht N an Schicht N+1, wobei bspw. ${my_proto}_ctloutput(9) von "oben" bspw. per {get,set}sockopt(2) Syscall ueber Socket-layer nach "unten" inerhalb einer communication domain(9) des Network-stacks "sendet", bei ganz grober sowie oberflaechlicher Betrachtung bzw. etc.pp., aber das wuerde jetzt erheblich off-topic werden.
 
Zuletzt bearbeitet von einem Moderator:
Hier ist eine (uralte) Erklärung von CAN, die ich aber ganz gut finde. CAN Bus Erklärung.
Auf PC Seite würde ich erstmal versuchen Adapter einzubinden, die über die "serielle" Schnitzstelle betrieben werden (früher RS-232, heute USB-CDOM Port oder CDC). Das CAN Protokoll ist dann in ein serielles für die "RS232" eingekapselt. CAN FD (längere Datenfelder als bei 2.0) fände ich am Anfang als nice-to-have. Also nur CAN Telegramm am Socket bereitstellen bzw. vom Socket auf den Adapter schieben
Serie300
 
Hier ist eine (uralte) Erklärung von CAN, die ich aber ganz gut finde. CAN Bus Erklärung.

Danke. Schoen, MAC wird vom Controller realisiert.

Auf PC Seite würde ich erstmal versuchen Adapter einzubinden, die über die "serielle" Schnitzstelle betrieben werden (früher RS-232, heute USB-CDOM Port oder CDC). Das CAN Protokoll ist dann in ein serielles für die "RS232" eingekapselt.

ist schon in Arbeit, siehe das in "Was habe ich heute Gelernt" erwaehnte USB-Device.

CAN FD (längere Datenfelder als bei 2.0) fände ich am Anfang als nice-to-have. Also nur CAN Telegramm am Socket bereitstellen bzw. vom Socket auf den Adapter schieben
Serie300

Das Telegram wird schon vollstaendig per Raw-Socket bereitgestellt.
 
@serie300 , @schorsch_76 Ack, da laesst sich schon mit "simplen" UART etwas machen bzw. einfach CAN Frames nach dem Muster
Code:
<type> <id> <dlc> <data>*
seriell per Null-modem-Cable, zwecks Experimentieren mit existierendem High-level Interface und ifnet(9), "verarbeiten". Spannendes Thema! :) [Wass'n Glueck, dasz ich mehrere PC mit seriellen Schnittstellen da habe.]
 
Zuletzt bearbeitet von einem Moderator:
Ich finde halt an CAN das Tolle, daß das ganze Zusammenstellen, Dekodieren und Fehlerhandling des seriellen Stroms vom Controller gemacht wird und du einfach nur eine CAN Nachricht in der MCU abholst.Die CAN einheit benachrichtigt dich, wen eine Nachricht komplett da ist und zum Schreiben sagst du dem Controller "Schreiben". Der schaut dann selber, wie er die Nachricht auf einen (teilweise belegten) Bus bringt. Und du hast automatisch Telegrammpriorisierung auf dem Bus.
 
Ich freue mich schon, wenn das USB Device da ist. Zwecks Debugging von High-level Interface und dem Entwickeln von if_slc(4) [fuer LLC] beschraenke ich mich noch auf Hooking, siehe bspw. uplcom(4).
 
.Die CAN einheit benachrichtigt dich, wen eine Nachricht komplett da ist und zum Schreiben sagst du dem Controller "Schreiben".

Jain, bin noch nicht [aber bald] fertig mit einem generischem Interface, was per ttyhook(9) [testweise] Zugriff per Interface-layer auf bspw. einem USB-CAN-Adapter implementiert [derzeit wird aber mit uplcom(4) experimentiert, da ich noch Kohle dafuer zusammenkratzen muss und ich gluecklicherweise ein USB-X-over-cable sowie 0-modem-cable da habe].

Dann werde ich mich wieder dem High-level-interface widmen und wenn es klappt, dann if_slc(4) fuer NetBSD "rueckportieren".

Was man nicht so alles tut, nur um die Installation einer GNU/Linux Distribution zu vermeiden. </ironic> :D
 
Der Prototyp fuer ein serielles Low-level Interface if_slc(4) wurde jetzt hinreichend implementiert sowie der Loopback wurde jetzt [hinreichend] ueberarbeitet.
 
Zuletzt bearbeitet von einem Moderator:
Hallo Chaos,

mal für Blöde wie mich, die CAN hauptsächlich aus der MCU Pogrammierung kennen. Dort wird das Handling zwischen Applikation und Treiber teilweise so abgewickelt, daß man beim Aufruf der Lesefunktion aus der Applikation den Zeiger auf die CAN Struktur (Queue Handling macht der treiber) bekommt und dann die Nachricht verbuchselt. Beim Schreiben gibt man einen Zeiger auf die zusammengestellte CAN Struktur und gibt diesen an den Treiber, der die Nachricht dann geeignet in die Queue einbaut.
Wie schaut das bei dir aus?

Serie300
 
Hi,

Ack.

mal für Blöde wie mich

Du hast definitiv mehr Ahnung bzw. Hintergrundwissen von CAN [sowie Elektronik] als ich.

Wie schaut das bei dir aus?

if_slc(4) ist als Prototyp fuer eine [geplante] Portierung der Business-logic von Linux-slcan als TTY Device Class zu verstehen.

Die Komplexitaet von Code-base ist auf dem ersten Blick erschlagend - mir geht es um das Weiterentwickeln einer weitestgehend generischen Implementierung, womit "man mit FreeBSD etwas machen kann".

Der I/O-Path ist eigendlich recht einfach: wie ich von dir lernte, integrieren [anscheinend handelsuebliche] CAN-Devices schon Error- / Media-access- / Link-layer-control , siehe u. a. hier oder dort.

Wobei hier der CAN Frame per Software-interrupt bzw. in can_input(9) eine FIFO-Queue kommt.

Es ist so aehnlich wie bei dem von dir beschriebenen Szenario, nur es ist auf die "Realitaet" von FreeBSD "umgebogen", was leider dann nicht wirklich KISS ist [spannendes Thema].

Der BSD Networkstack kennt, bei grober Betrachtung, drei Schichten:
Code:
a) Interface-layer <=> OSI-L2 [mit logischen Teilschichten MAC / LLC, etc. ]

b) Protocol-layer <=> OSI-L3 [das ganze Kasperletheater mit CAN-ID Filtering und PCBs, etc. ]

c) Socket-layer <=> OSI-L4 [teilweise auch OSI-L5, wobei sich das auch auf andere Komponenten von OS "verteilt"]
Das I/O Subsystem BSD Kernels wird "ergaenzend" bzw. "grob" in die Teilschichtem "Top-half" sowie "Bottom-half" unterteilt [siehe u. a. hier bzw. Kap. 2.2], etc. ...

... derzeit wird Code-base bzgl. Protocol- / Socket-layer ueberarbeitet, da jetzt _endlich_ mehrere Stationen [testweise] per tty(4) vernetzbar waeren [auch wenn das auf dem ersten Blick etwas schwachsinning ist, da keine oder noch nicht Error-control, wenn jetzt kein Device mit CAN Controller noch nicht da ist], nur um den Raw-socket in einen hinreichend "benutzbaren" Zustand zu "versetzem", damit das "Hackvalue" hat [und austesten will, was so alles mit FreeBSD machbar waere].
 
Zuletzt bearbeitet von einem Moderator:
@das.chaos : Ich hab den usbtin Zuhause und Can Feldbus Hardware von Wago.
Um deinen Treiber zu testen, würde ich mal wie folgt vorgehen:
  • 11.2 FreeBSD VM installieren
  • Das Github Repo von dir klonen nach /usr/src
  • Das System aus den Quellen neu bauen
  • USB Interface durchreichen und dein Modul laden.
Passt das so?

Unter Linux hab ich eine bestehende CAN Open Implementierung die auf Socket CAN basiert. Das würde ich dann probieren es unter FreeBSD zum laufen zu bekommen.
 
Supi.

So aehnlich ist das der Plan, aber ich bin noch mit dem Ueberarbeiten von can.c [bspw. ioctl(2)s sowie integration von Funktionen aus canconfig(8) fuer AF_CAN in ifconfig(8)] und raw_can.c [Fehlerkorrekturen, etc.] beschaeftigt, siehe Commit-history..

Ich muss noch in sys/conf/{files, options} anlegen [eher Patches], bin gerade dabei mir zwei Kisten mit 11.2 aufzusetzen.

Ich gebe dann bescheid, wenn Code-base "verwendbar" ist. :)
 
Syntaktische und semantische Fehler wurden im Quelltext beseitigt [gemeint sind jetzt die groben und offensichtlichen Schnitzer], d. h. ich werde nachher mit Software-testing beginnen und das alles debuggeen.

Mal schauen, wie spaektakulaer damit FreeBSD 11.2 crashed. :D

Da gibt es einige Sachen in Code-base, die mir Kopfschmerzen verursachen, aber das Stadium der produktiven Verwendbarkeit rueckt stetig [aber in kleinen Schritten] naeher.
 
Sieht auf dem ersten Blick gut aus..
image.jpeg
 
Testweise uart(4) hooked, zwecks Testing von Interface-/Protocol-layer der can(4) communication domain, ..
image.jpeg
 
Hallo Chaos

die Netzwerk CAN Layer kann jetzt also über cuaa0 auf den adapter zugreifen Und hinten am Socket kommen die Telegramme an ? Man könnte also zu Testzwecken mit einer pipe verbinden und sic einen virtuellen Adapter anstatt cuaa + phys. adapter einbauen? Entschuldigung wenn ich blöde frag, aber ich mache mehr Erfahrung auf MCUs als PC Ebene

Sere300
 
die Netzwerk CAN Layer kann jetzt also über cuaa0 auf den adapter zugreifen

Jain, ... das ist ein tty(4) Hook, damit Unit-tests fuer die Komponenten der Interface-layer sowie der Protocol-layer, die das High-level interface integriert. realisiert [Debugging, etc.] werden.

Ist diese Phase abgeschlossen, wird if_slc(4) in eine tty(4) Device-driver Class ueberfuehrt, die das implementiert.

Man könnte also zu Testzwecken mit einer pipe verbinden und sic einen virtuellen Adapter anstatt cuaa + phys. adapter einbauen?

Guter Hinweis - das ist definitiv moeglich, indem die Komponente vom Char-device mit I/O-Subr. erweitert werden wuerde [was fuer Software-tests fuer das High-level interface hinreichend ist].

Es wurden zwei Stationen per 0-modem-cable verbunden, um das I/O-Verhalten von in if_slc(4) integriertem tty(4) Hooks interface zu testen, weil es interessant ist mit tty(4) sowie termios(4) zu "experimentieren" und ich den Tx-/Rx-Path im Kernel nicht "unterbrechen" moechte, wie bspw. das beim Zusammenwirken von tun(4) mit ppp(8) zu beobachten ist].

Selbstverstaendlich beschaeftigie ich mich schon mit dieser Thematik.
 
Zuletzt bearbeitet von einem Moderator:
CAN Frame wurde zwischen zwei Stationen gesendet, die mit uart(4) physisch vernetzt sind.

image.jpeg


Es folgen weitere Tests, ..
 
Das Senden von CAN Frames via Socket-layer wurde jetzt hinreichend getestet, ...
image.jpeg
.. d. h. ich werde jetzt anfangen einen Gerätetreiber für "echte" Hardware [PCI-Adapter mit Phillips SJA1000 Controller] implementieren sowie can_nh_input(9) überarbeiten, weil die Implementierung nicht wirklich generisch ist [auch wenn es so aussieht]:
  1. die innere Schleife wird als rcan_input(9) externalisiert werden, da protosw{} table.
  2. die äußere Schleife wird per can_filter{}-to-ifaddr(9) mapping "weg-optimiert" werden, da nicht nur CAN Frames auf Basis von can_filter{}-to-PCB mapping gefiltert werden.
  3. "Korrekturen bzgl. [gs]etsockopt(2), etc.
if_slc(4) wird "danach" in eine tty(4) device-driver class im Tahmen von allgemeinen Fehlerkorrekturen umgewandelt werden, weil TDD.
 
Zuletzt bearbeitet von einem Moderator:
Zurück
Oben