 Hello, everyone. Hi, my boss is still taking a picture. I want to make I want to make a selfie with all of you. Come on, let's say. Raise your hands applause. Okay. So I'm Mark. I'm the maintainer of the Linux Khan framework and the drivers. And this is my colleague, Oleg say, and we will talk about socket can in the beginning and then Oleg say will focus on J 1939. Not that you have a little bit of information about me. I want to know something about you. Please raise your hands. Who of you has used can before? Oh, nice. Let's keep your hands up. Who has used that on the Linux mainline kernel? Oh, okay. It's not getting less. Who has heard of J 9 to 39 before? Oh, quite so many people who has used it on Linux. Some and who of use of you have used the mainline Linux kernel stack. Me and my colleague and one of my colleagues is cheating. Okay, I want to talk about first about can that you all that we all on the same level. What's what's can about can is networking hardware and then stack. It's you need just two wires for it. It's something different than either net. It's much more simpler. This is why we have different different constraints on either net. The speeds are just up to one megabit per second. Yes, per second, just one megabit. And you only have eight bytes of payload per frame. So and a frame has these eight bytes of payload and an addressing field that might be 11 or 29 bits. And based on that can ID. This is a prioritization how to access the bus. It's like Black Friday shopping. Only the strongest can ID wins the can ID was the lowest number gets a bus and all others if they should send at the same time they will automatically get away from the bus so that would be no collision. And this means all the can frames they are broadcasted so that everyone can receive them. How was the can infrastructure before we introduced it to the Linux kernel? You have the kernel. And because everyone thought they are can is so simple. We don't need it in the current we just have some library or whatever. And this is usually per vendor. Some vendor or 530 site are we bundle some library with my with my either with my can networking card and we ship it to the user. So you have the protocol and everything in your application. And some other vendor sells a different networking card and a different library. And for example, tell your IT guys when you switch your Intel Nick for AMD Nick you need to recompile your web server. Everyone says what are you crazy. And because of this we decided you're let's let's get the can stuff into the kernel that you have a unified interface for all applications. Just the usual socket open close read write that you all all know. So before it was in the kernel you have no compatibility between all those different can implementations. No tooling because everyone invented their own library and there was. Resulting of this test coverage. And then we move the protocols take into the kernel. We can make use of the in kernel infrastructure for drivers for networking. And you open a socket and this is your one and only interface between the car and your application. And some suck vendors. They wrote their own drivers and brought the main line and for others we did and other people did. And so now you can use the same application for testing on your laptop with some USB adapter or different or the same application on your sock with the internal can adapt. So this is how can looks now. You have different applications. The socket layer. The different protocols then the networking core pack it scheduling routing and the can interfaces. This is how the flow of packages in this. It's might look complicated in the end but as a application developer you just interface with the socket layer and with the driver developer. We just at the bottom. So it is all quite nice and shiny. And with all this we have a lot of infrastructure now. Cannot yields for basic interacting with the canvas and good examples to start with. We have can tests. We have wire shark plugins and so on and so on. Yeah but coming back to the limitation of the canvas packets are only the can frames are only 0 to 8 bytes and yeah this is just single tiny spoon of data and if you want to have make a firmware update in your device or whatever where the firmware is several megabytes big several tens of megabytes it's quite complicated. And for the can the can ID is not in the lower levels not standardized. What to do with it is just an ID and what you do with it with the sender or receiver or that defines what the content of the packet is it's up to you. So this is where J1939 comes into play. This all gives teeny tiny can packets and addressing meaning and leverages the small slow bus with a tiny packet to do something something bigger. And this is where my colleague will take over because he has cleaned up and implemented a lot of ideas and brought it into mainline. So we already get some idea about challenges of can it is slow. It provides we can transfer really tiny bytes of data and usually we have lots of choice what we can do but well it is it provides us huge power to do really different designs but how we work with this power depends on us and sometimes we provide interfaces which are not compatible with each other. So here is the place where J1939 comes into play is it's providing or well it's providing a number of recommendations what you can do with all of this and well everyone is free to apply these recommendations but if you do your device will just work with another device. For example we get recommendations for physical layer and the main part of this specification is a number of different defined predefined PGNs. PGNs are parameter group numbers and with this number you can already know how you can process all of data which are in the payload independent and the way how you get it. This PGN is located in the can ID, the can ID is 29 bit, the data is 64 bit and you get in can ID source address and you can even get a destination address inside of PGN. It depends on the PGN level so until some PGN number you are able to use a destination address and after this it's some kind of generic groups like this ID for example for engine, status, rotation temperature and so on it's everything encoded and predefined inside of PGN and well we have three bits of preo and you can use it as you wish. As well we get here transport protocol and based on this we get even extended transport protocol defined by isobus. With transport protocol we can more or less reliably send and receive data. It is not common and common because usually you just fire and forget and in this case we have a unshaking request to send, request to send, clear to send and end of message and then we have a acknowledgement which is done after complete transfer was made so between different MTUs you are able to see if this data was actually transferred completely or not and if not then you are still able to somehow recover it. With transport protocol you can send message of 1792 bytes and with extended transport protocol you can send a message of 112 megabyte and this was a main challenging part of implementation in the kernel because we need to provide abstraction there for MTU maximum transfer unit of 112 megabyte. Just a comparison of why we actually do not use some existing protocols theoretically we will use IP with TCP or UDP headers but well let's see IP version 4 we have 20 bytes of header it is even not fit to one can package it is a lot and with TCP we have extra 20 bytes of header with UDP we are close enough we can put complete UDP header in one can package but what can we do else with this? So we need it somehow and here's where comes to use of this protocol and how can this be used in the Linux. Currently this protocol is spread somehow and there are different implementation in user space and different operation systems so it closely the same situation like it was with socket scan back in 2013 or so yeah so yeah 2008. What kind of challenges we have with this protocol? Well usually on the Caspan we work with like probably about 2,000 packages per second it's not really huge amount of data for normal high power system. These packages are tiny really small so with SKBS we have a huge overhead for each package. The specification provides relatively relaxed timing requirements so usually we will not go to time out if you are running from user space with this implementation but for example on some low power system with I don't know old version of ARM with 400 smear hairs for example iMix 28 it will be problematic. There are user space implementations and you can spot a different variants in the wildness. The kind of J90, 39 demon running in user space and routing all the data to different applications. There is one library used by different applications or all in one application which is just doing everything or even you're probably familiar with this. Some product is made by different developers or different companies at different time or status of development so you get just different stacks and same product. In first case well it's possible to do this but you'll get really long round trip times so your can message will go to process by kernel then it will be copied to user space and processed by J90, 39 stack for demon then it will be somehow on some way I don't know pipes, unix, domain sockets, TCP or whatever transfer to the application. There's a huge amount of time and not needless overhead in this case. If you use a library it will be easier for update or page something so your applications will be updated at the same time but you'll get copy all the same data for each application so for example if you run 10 application in user space you'll get all this 2000 packets per second for each application. It is needless overhead as well. All in one well it's possible to do this but you'll get other kind of challenges, security, availability and so on. Is it really good to manage a huge project all in one? I don't think so and I think this part is we don't really need to explain this if you get different stacks different kind of implementation on same system. It's just nightmare to manage this kind of project. So we have kernel stack for J9039 and at least theoretically it should cover three or four variants of this protocol, original SIA J9039. Isobus for this we was needed extended transport protocol. Probably it should work on NMA 2000. It is for marine applications and mil-can is for military applications. We was testing mostly only first variant and then we did the second variant and then we did the third variant. We were testing mostly only first variant but I don't think it will be a big challenge to extend or fix existing protocol to run with all other variants. So we have now the same well-known socket implementation from user space point of view. If you already worked with different kind of socket you will be able to apply your knowledge with this protocol as well. Kernel will give you all power you need to work with this stack and take some tasks for example for others claiming and then for transport protocols. So if you are starting to use transport protocol with J9039 kernel will gather all needed packages and assemble one huge data package and transfer it in one time to user space. For others claiming you should do your own others claiming in user space but kernel will cache these claims and so you don't need to resent new others claims for each application and this will save you some time on the bus as well. If you want to try to play with a kernel stack you can already use some examples in can-you-chills for example JACD is for the demon for J9039 others claiming. It is really straight forward simple demon but it's ready for use and JCAD was used only for transport and extended transport protocol testing. It is similar kind like net cat so you just get JCAD on both sides and both units and cut data from one unit send it over can with transport protocol and gather it on other side so you can just put it like a file. For kernel in kernel we have a documentation network J9039 files so you can read as much as possible from this. There are some examples, some motivation explanation if you are missing some information in this file please contact us or just send pages. Here is one example how you can implement a simple transfer in user space. You will need to provide a structure, SOC, other with all needed information. You can use a name if you are already familiar with others claiming on J9039 then you know what name is if you are not. The name is with can ID we have only one byte for others and in some cases it is not enough to identify what device it is. And name used as 64 bit ID so you can really pretty exact identify what device it is, what manufacturer and so on. So at first stage we claim this address, this 8 bit address by sending a 64 bit name to the bus and other applications then able to reuse this name to communicate with it so you can use address directly or name. It is up to you. And you can use Pagain as well. In this case in kernel implementation we use source Pagain differently as destination Pagain, destination Pagain is used to compile a message which will be sent to the bus and the source Pagain is used as an input filter so you can set it or not if you will set this Pagain on your source address then you will get messages only for this pgn. As soon as you prepare your addresses for source and destination then it is just enough to open socket bind to it and wish you can connect. If you do not use connect then you won't be able to use send or receive. In these cases you will need to use send message or receive message. In this example I provided here connect so we are able to use send. Here is an example just proof of concept that it is working. On the right side is a riot board with iMix 6 solo and here I am starting jcat receiver with address 90 0x90 and parameter minus r means that it is in receiver mode and all that I will be redirected to TMP RX file. So I started here each top to show CPU load and the left side similar system it is riot board as well with same CPU and here I am starting similar jcat application but in send minus e means this input file which we use to transfer data can zero it is the interface which should be used to send data so you can use multiple interfaces on your system 0x80 is a source address and 0x90 is a destination address. Here you can see status update it was sent by the kernel over error queue so you are able to use this you should not use it. In some cases it is really useful because with this huge M2 you just give the kernel huge amount of data and it starts on processing and well if you need to know somehow in user space what is going on you can request it and prove that all the data was correctly transferred I provided here checksum on both sides so it looks okay now. If you are already familiar with J9339 maybe you will spot here bug which is this code this Friday. Can anyone see it? Okay. It should be different. This size this is a end of message acknowledgment message and it should say I received so much bytes or so much packages and well in this case it was wrongly implemented and thanks to open source community this bug was spotted and reported. It is just one example how it usually works. Main challenge with huge M2 was solved. One challenge is at least now is how to explore the others claiming cache should use some kind of similar procedure like with ARP cache currently it is not really decided. I prefer to not mainline not really not really not really implementations so you can have enough time to decide what is good and then provide proper UIP for this. And well we need some kind of test automation. It is I was playing with small com so maybe you will go this way. I don't know if you already have some experience with this tech or with testing for J9339 you are welcome and I really would like to hear some suggestions and ideas. And well it is already accepted for mainline. With kernel 5.4 you will be able to use it. Thank you. Do you have any questions? So when you have these 112 megabyte huge packets do you preallocate buffers on the kernel level when you receive them? So do you have this massive chunk of memory on your little embedded SOC which is just wasted and ready for receiving these packets? Yeah. The implementation end protocol was designed so that not all systems are able to receive this amount of data. So we kindly ask first that we are trying to send a huge amount of data. Can you accept this? And other side can say I can accept only this amount of data or I can say I don't want this. And for the sending part we don't allocate this 112 megabytes inside the kernel again and don't copy it on block to the kernel but we just use a socket memory and allocate from there like how much is it 128k or so. Then we copy data to it, push it into the stack and then the next allocation either sleeps because you have a blocking socket and then it starts again if the driver has sent some data and frees some socket buffer or if you are in a non-blocking mode the sender process will return to the user space and say I just have sent like one megabyte and it's up to you to send the rest. And you have to provide the same or the remaining bytes of data into the kernel with another send or send to or whatever system call and then the kernel picks up from there and completes or tries to complete until it blocks again or goes back into user space or a signal comes. And for the receiving side it's yeah as Olex explained if so much memory is available it will be allocated. We have no we see if in chunks and provide to user space in chunks we currently receive the complete 112 megabytes at a time and then provide it to the user space. For the sending side it was not for the receiving side it wasn't that easy to do it in chunks so we skip that any more questions? Yeah. Have you got any drive how many drivers are currently in the kernel and are people starting to look at actually implementing device drivers for these against your stack now? This J1939 is based on the normal socket can as May 9 since 2008 right yes thank you. Since May 9 since 2008 and there are many drivers inside the kernel now and the normal socket can in raw mode without this J1939 is available and it's used everywhere I think and this stack is used on top of these existing drivers. One side note this stack is designed in a way that the send packages and the receive packages are needed to be in the right order. If the send and receive packets get mixed up the stack gets confused so maybe your driver that's already in the kernel needs some tweaking. Another question? Yes hello yeah first I would like to thank both Mark and Olexi to put some more things into the can network layer because we really have two things one is can network layer which is in Linux net can and the other thing is really which is under Linux drivers net can so the drivers are really for SOCs and USB whatever you have so at least this increases the pressure for me to also bring my ISOTP mainline which is just hanging around on my GitHub but one question from my side what about J1939 and can fd is there also something something which is going on to bring this also to can fd because it has not only 8 bytes it has 64 bytes in the data of the can frame. I think the problem with the SAE that is the organization who does the standardization all their standards are closed or you have to pay money or something like this but I have seen now that the next next can protocol like the can excel is being implemented now the people from SAE are looking for can fd and J1939 I think it's in the making and I think there is a draft but you probably can only download it if you're a member of the SAE you cannot even buy it as far as I know. Marek, so how do you handle moving this big buffers between user space and the kernel? I know that the graphic stacks uses DMA buffs to efficiently shuffle big buffers between user space and the kernel does the network stack have something similar or do you just like copy to user copy from user? For the sending path we use just the normal stuff from the networking stack I think you can use zero copy this is all abstracted by the networking stack it makes a handling from user space a little bit more different more difficult because you say send and then send returns but you are not allowed to discard the buffer because it's still in use and if it's the kernel is done with it then you get some message from the kernel that the buffer is done and you can discard it the question was is there a library that does this it's inside the kernel it's called zero copy look into documentation net and then look for zero copy use regex and then you will find something there are examples in the kernel send file was the question if you think about it do we have to implement a callback for this I think we have to implement a callback for this we should put it on our to-do list yes the first stage it was not really important we had to provide at the first stage some basic UAPI which has no questions to say the well-established read write and receive stuff and all the optimization is on top another question I think no one then thank you again thank you