Recent

Author Topic: CAN-BUS SocketCAN  (Read 71632 times)

rampinia

  • Newbie
  • Posts: 2
CAN-BUS SocketCAN
« on: January 28, 2018, 10:20:35 am »
Hello to all

does anyone did programming socket in the class PF_CAN for accessing CAN-BUS in Linux?
On the wiki side I have seen there are not current constant declaration for such network protocoll.

If the pfsocket and others call are just wrapper for standard BSD socket call I think it is enaugh to declare the constant just porting from the standard linux header.

Any info?

Thanks
« Last Edit: March 25, 2021, 09:04:36 am by mattias »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11352
  • FPC developer.
Re: CAN-BUS SockectCAN
« Reply #1 on: January 28, 2018, 10:43:14 am »
Yes, the sockets unit are just wrappers. Best is if somebody finds the constants, tests it, and then submits a patch.

rampinia

  • Newbie
  • Posts: 2
Re: CAN-BUS SockectCAN
« Reply #2 on: January 28, 2018, 06:30:27 pm »
Yes

got PF_CAN = 29 and CAN_RAW = 1 from sys/if.h

already run some tests with PF_CAN = 29 and CAN_RAW = 1 and it works.

I'm working a minimal porting from C header.

RM

  • Newbie
  • Posts: 1
Re: CAN-BUS SockectCAN
« Reply #3 on: March 11, 2019, 08:50:21 am »
Hello at all, i am new here...

I try to establish a CAN connection on the raspberry pi (stretch), using free pascal.
I successfully created a raw socket with PF_CAN=29 and CAN_RAW=1.
And now i have to bind the socket to the hardware address, but i don't know how?

Code: Pascal  [Select][+][-]
  1. class procedure TSysBus.OpenSocket;
  2. var
  3.   s:Tsocket;
  4.   sa:TSockAddr;
  5. begin
  6.      s:=fpsocket(29, SOCK_RAW, 1);
  7.      sa.sa_family:=29;
  8.      sa.sa_data[0]:=???;
  9.      fpbind(s,@sa,SizeOf(sa));
  10.      FpClose(s);
  11. end;
  12.  

Can somebody give me an example, how i have to go on?
Thanks

jcdammeyer

  • Full Member
  • ***
  • Posts: 205
  • Embedded System Developer
    • Automation Artisans Inc.
Re: CAN-BUS SockectCAN
« Reply #4 on: August 21, 2020, 05:00:22 am »
Anyone been able to create the equivalent of a simple the socketCAN utilities  candump using Lazarus
Code: Text  [Select][+][-]
  1. debian@ebb:~$ sudo /sbin/ip link set can1 up type can bitrate 250000
  2. debian@ebb:~$ candump can1
  3.   can1  721   [1]  05
  4.   can1  1A1   [8]  20 00 FF 0F A8 FD A8 FD
  5.  

No one answered RM and rampinia didn't post any other solutions.

Code: Pascal  [Select][+][-]
  1. procedure TSocketForm.Button1Click(Sender: TObject);
  2. var
  3.     i : integer;
  4. begin
  5.   // open socket
  6.   socket_result := fpsocket(PF_CAN, SOCK_RAW, CAN_RAW);
  7.   if (socket_result < 0) then begin
  8.         // perror("socket");
  9.     Edit1.text := 'Error #' + IntToStr(socket_result) + ' creating socket';
  10.   end
  11.   else begin
  12.     SAddr.sin_family := PF_CAN;
  13.     if fpconnect(socket_result, @SAddr, 0) = -1 then begin
  14.       Edit1.text := 'Socket can''t connect: ' + strerror(socketerror);
  15.     end;
  16.   end;
  17. end;
  18.  

The error is 'Operation not supported on Endpoint'

The C language candump doesn't use fpconnect() and the 'connect()' is deprecated and doesn't work either.  So although this is the document for fpconnect it uses deprecated functions rather than fpconnect().

https://www.freepascal.org/docs-html/current/rtl/sockets/fpconnect.html

Plus it's more targeted at internet protocol sockets.

Ideas?


trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: CAN-BUS SockectCAN
« Reply #5 on: August 21, 2020, 05:17:22 am »
What about this. The Windows/Linux SDK for Delphi is free.

jcdammeyer

  • Full Member
  • ***
  • Posts: 205
  • Embedded System Developer
    • Automation Artisans Inc.
Re: CAN-BUS SockectCAN
« Reply #6 on: August 23, 2020, 09:55:24 am »
What about this. The Windows/Linux SDK for Delphi is free.
Unfortunately from what I can see it doesn't address socketcan.

What I've found out so far is that socketcan and the utilities like candump work with the USB based CANUSB from Lawicel along with the internal BeagleBone Black CAN device and on a Pi, an SPI based MCP2515.

Further research shows that as simple as including 'can' in python programs brings in support for either the BBB or Pi. 

This is what I want to see for Lazarus.  I'd like to be able to plug in any device that has socketCAN support and have the application compile on that platform, or cross compile for that platform and just plain work.

What I've discovered is that this doesn't work for Lazarus yet.   So I need to find out where the sockets source code lives for the Pi and the Beagle and figure out why the fpconnect() returns an error.  Clearly it's broken or not properly documented.

Laksen

  • Hero Member
  • *****
  • Posts: 724
    • J-Software
Re: CAN-BUS SockectCAN
« Reply #7 on: August 23, 2020, 11:10:19 am »
Why are you calling connect and not bind?

jcdammeyer

  • Full Member
  • ***
  • Posts: 205
  • Embedded System Developer
    • Automation Artisans Inc.
Re: CAN-BUS SockectCAN
« Reply #8 on: October 22, 2020, 06:10:48 am »
I think I have some time to dive back into this project. 
Why are you calling connect and not bind?
Even if I call bind (or fpbind) the issue is that the sockets code seems to be oriented towards ip and port numbers. 
Referencing this document
http://www.linuxhowtos.org/C_C++/socket.htm
I believe the socketCAN has to address the unix domain via the Linux File system. 
Recall my example from a previous post.
Code: Pascal  [Select][+][-]
  1.    
  2.     debian@ebb:~$ sudo /sbin/ip link set can1 up type can bitrate 250000
  3.     debian@ebb:~$ candump can1
  4.       can1  721   [1]  05
  5.       can1  1A1   [8]  20 00 FF 0F A8 FD A8 FD
  6.  
The can1 is the device which in the above example is a USB based CAN dongle.  On a Pi I can just as easily specify the SPI based MCP2515 CAN device in place of the USB device. 

For example from this tutorial
https://www.raspberrypi.org/forums/viewtopic.php?t=141052
Code: Pascal  [Select][+][-]
  1. pi@piv2:~ $ ls /sys/bus/spi/devices/spi0.0/net/
  2. can0
  3.  
  4. pi@piv2:~ $ sudo ip link set can0 up type can bitrate 125000
  5.  
  6. pi@piv2:~ $ sudo ifconfig
  7. can0   Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
  8.           UP RUNNING NOARP  MTU:16  Metric:1
  9.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  10.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  11.           collisions:0 txqueuelen:10
  12.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
  13.  

So from the OS perspective the fact that one device is USB based and can be plugged into a WIN-PC MAC or Linux system while the other one is SPI based on the Pi the access via Linux is the same.

And the C Program candump.c creates identical output regardless of the hardware type.  (BTW, it's the same with the embedded inside the processor CAN device in a BeagleBone Black).

Code: Pascal  [Select][+][-]
  1. pi@piv2:~ $ candump can0
  2.   can0  001   [8]  11 22 33 44 55 66 77 88
  3.   can0  00003456   [8]  EF FE DD AD CB 67 98 AA
  4.  

Now in the C world, candump.c or cansend.c can be used as a template for a customized program to do whatever...  One might cut and paste parts into their application.    That's because the sockets library in C handles the parameters PF_CAN and SOCK_RAW, CAN_RAW.

The FPC sockets does not.  And yes I can define those but tunnel down into sockets.pp and and the system's ...sockh.inc we don't have a PF_CAN.  And without a PF_CAN and AF_CAN in the socket()  the connection aborts because it doesn't know what to do with it.

In order to cut and paste more of the code I'll have to continue this in another message from the Pi3 so I can post the Lazarus program I've used to discover this but I don't think the FPC code will matter at this point.

Search for candump.c and we find in
https://github.com/linux-can/can-utils/blob/master/candump.c

Code: Text  [Select][+][-]
  1. s[i] = socket(PF_CAN, SOCK_RAW, CAN_RAW);

Later we bind to the socket
Code: C  [Select][+][-]
  1. if (bind(s[i], (struct sockaddr *)&addr, sizeof(addr)) < 0) {
  2.                         perror("bind");
  3.                         return 1;
  4.                 }
  5.  

Eventually after all the CAN_FD and filter handling we end up
Code: C  [Select][+][-]
  1. nbytes = recvmsg(s[i], &msg, 0);

So in general I get the feeling that to add socketCAN support to FPC will require a fairly extensive modification of the base sockets library.  Is there any interest in this?  Who's allowed to change it. 

The project I started in Lazarus works fine with the USB based CAN dongle by treating it as a serial port which generates strings of characters representing the messages.  But I can't access the CAN devices built into the BeagleBone nor the Pi which is a cakewalk with Python or C.  And I'd like to be able to demonstrate CAN bus access from a USB dongle or the embedded hardware. 

What's the next step?

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: CAN-BUS SockectCAN
« Reply #9 on: October 22, 2020, 09:41:43 am »
So in general I get the feeling that to add socketCAN support to FPC will require a fairly extensive modification of the base sockets library.
PF_CAN is just a number. In linux sources you can find it defined as AF_CAN, which is defined as 29. So why don't you try that first?

You could also take a look at https://github.com/linux-can/socketcand if you wish to access CAN via CAN-ETH gateway daemon. You can install https://github.com/dschanoeh/Kayak as a handy GUI application that can access SocketCAN (and serial slcan through it) using socketcand.

Instead of using real slcan device as you do, maybe it would be easier if you use vcan instead and simulate CAN traffic for testing purposes. Once you get everything working you can then switch to a real device. If you wish I can give you several simple scripts to bring up VCAN environment, generate CAN traffic, and use SocketCAN directly or through socketcand and Kayak.

EDIT: I see now that you are looking at sources of candump. It will be much easier if you use simpler example from here:
https://www.beyondlogic.org/example-c-socketcan-code/
« Last Edit: October 22, 2020, 09:59:07 am by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

MarkMLl

  • Hero Member
  • *****
  • Posts: 6647
Re: CAN-BUS SockectCAN
« Reply #10 on: October 22, 2020, 09:44:51 am »
I believe the socketCAN has to address the unix domain via the Linux File system. 

Presumably you mean unix domain *socket* here. If so I agree that it's normally accessed via the filesystem, but otherwise the API is fairly similar to an inet datagram socket.


Code: [Select]
      if fpSelect(maxHandle + 1, @readSet, nil, nil, nil) >= 0 then begin

(* A message received on the inet domain socket must have a recognisable sender *)
(* since it might be needed for authentication purposes. A unix domain socket   *)
(* can be assumed to be protected by local permissions and capabilities.        *)

        if (UnixDomainSocket() >= 0) and (fpFD_ISSET(UnixDomainSocket(), readSet) = 1) then
          dispatchMessage(UnixDomainSocket(), false);
        if (InetDomainSocket() >= 0) and (fpFD_ISSET(InetDomainSocket(), readSet) = 1) then
          dispatchMessage(InetDomainSocket(), true)
      end

...

begin // dispatchMessage(), invoked as above, 2nd param is hasFrom
  FillByte(recvBuffer, SizeOf(recvBuffer), 0);
  if hasFrom then begin                 (* Inet domain socket                   *)
    FillByte(sa, SizeOf(sa), 0);
    saLength := SizeOf(sa);
    messageLength := fpRecvFrom(socket, @recvBuffer, SizeOf(recvBuffer), 0, @sa, @saLength)
  end else begin                        (* Unix domain socket                   *)
    saLength := -1;
    messageLength := fpRecv(socket, @recvBuffer, SizeOf(recvBuffer), 0)
  end;

(* There is no provision here for concatenated or fragmented messages, which we *)
(* of course shouldn't see since it's a datagram socket. Elsewhere, we try to   *)
(* work out the MTU by looking at padded backbone messages.                     *)

...

(* The result of this may be subsequently retrieved using UnixDomainSocket().
  If a .pid file indicates that an existing socket was created by an instance
  of this program that no longer exists then delete it. Create a fresh Unix
  Domain socket and save the handle, on failure save an error code. Both success
  and failure are silent.
*)
procedure CreateUnixDomainSocket(socketName: string);

var
  oldPid: longInt= -1;
  pidName: string;
  pidFile: text;
  uid: TUid;
  gid: TGid;

begin
  if socketName[1] = '~' then begin
    Delete(socketName, 1, 1);
    socketName := UserHome() + socketName
  end;
  pidName := socketName + '.pid';
  if FileExists(pidName) then
    try
      Write(StdErr, 'Opening old PID file... ');
      Assign(pidFile, pidName);
      Reset(pidFile);
      try
        Read(pidFile, oldPid);
        WriteLn(StdErr, 'OK, ' + IntToStr(oldPid))
      finally
        Close(pidFile)
      end
    except
      WriteLn(StdErr, 'failed');
      oldPid := -1
    end;

(* If we have managed to read a process ID file then check whether the relevant *)
(* process (an older instance of this program) still exists. If it does then we *)
(* shouldn't be trying to run this program, if it does not and a unix domain    *)
(* socket exists then try to delete it.                                         *)

  if (oldPid >= 0) and FileExists('/proc/' + IntToStr(oldPid)) then begin
    WriteLn(StdErr, 'WatchP0x already running, terminating.');
    Halt(9)
  end;
  if oldPid >= 0 then begin
    WriteLn(StdErr, 'Process ', oldPid, ' is not running');
    try
      if FileExists(socketName) then begin
        Write(StdErr, 'Deleting old unix domain socket ', socketName, '... ');
        DeleteFile(socketName);
        if not FileExists(socketName) then
          WriteLn(StdErr, 'OK')
        else
          WriteLn(StdErr, 'ineffective (critical error)')
      end else
        WriteLn(StdErr, 'No old socket')
    except
      WriteLn(StdErr, 'failed');
      unixDomainSocketHandle := -Abs(ErrNo) (* Probably ESysEACCESS             *)
    end
  end;

(* Delete old PID file since it might be owned by a different user.             *)

  if FileExists(pidName) then begin
    Write(StdErr, 'Deleting old PID file... ');
    try
        DeleteFile(pidName);
        if not FileExists(pidName) then
          WriteLn(StdErr, 'OK')
        else
          WriteLn(StdErr, 'ineffective (critical error)')
    except
      WriteLn(StdErr, 'failed');
      unixDomainSocketHandle := -Abs(ErrNo) (* Probably ESysEACCESS             *)
    end
  end;

(* Create a new PID file.                                                       *)

  try
    Write(StdErr, 'Creating new PID file... ');
    Assign(pidFile, pidName);
    Rewrite(pidFile);
    try
      WriteLn(pidFile, IntToStr(GetProcessID()));
      WriteLn(StdErr, 'OK, ', GetProcessID())
    finally
      Close(pidFile)
    end
  except
    WriteLn(StdErr, 'failed (critical error)');
    unixDomainSocketHandle := -Abs(ErrNo) (* Probably ESysEACCESS               *)
  end;

(* Create the socket. Note that there is no suitable fpBind() for this.         *)

  Write(StdErr, 'Creating new unix domain socket... ');
  unixDomainSocketHandle := fpSocket(AF_UNIX, SOCK_DGRAM, 0);
  if Bind(unixDomainSocketHandle, socketName) then
    WriteLn(StdErr, 'OK')
  else begin
    WriteLn(StdErr, 'failed (continuing)');
    unixDomainSocketHandle := -Abs(ErrNo) (* Probably ESysEACCESS               *)
  end;

(* Change socket owner and group to be the same as the executable, on the       *)
(* assumption that this is the user that will be executing all programs.        *)

// TODO : Bad assumption if setuid.

  Write(StdErr, 'Changing socket''s ownership... ');
  getOwner(ParamStr(0), uid, gid);
  if fpChown(socketName, uid, gid) = 0 then
    WriteLn(StdErr, 'OK')
  else begin
    WriteLn(StdErr, 'failed (continuing)');
//    unixDomainSocketHandle := -Abs(ErrNo) (* Probably ESysEACCESS             *)
  end;

(* Set the socket to be writable by its owner (i.e. any cooperating program)    *)
(* and readable by its group (this program). I don't think very much of doing   *)
(* this but the computer on which this is running can be assumed to be          *)
(* physically secure leaving the major risk being that somebody unauthorised    *)
(* logs into it and runs one of this suite of programs.                         *)

  Write(StdErr, 'Relaxing socket''s read/write permissions... ');
  if fpChMod(socketName, &766) = 0 then
    WriteLn(StdErr, 'OK')
  else begin
    WriteLn(StdErr, 'failed (continuing), might need CAP_DAC_OVERRIDE,CAP_NET_BIND_SERVICE,CAP_NET_RAW=p+e');
    unixDomainSocketHandle := -Abs(ErrNo) (* Probably ESysEACCESS               *)
  end

(* Since we're about to reliquish admin capabilities we won't be able to delete *)
(* the socket at program termination.                                           *)

end { CreateUnixDomainSocket } ;


(* The result of this may be subsequently retrieved using InetDomainSocket().
  Assume that any existing socket was deleted when its owner terminated. Create
  a fresh Inet Domain socket and save the handle, on failure save an error code.
  Both success and failure are silent.
*)
procedure CreateInetDomainSocket(port: integer);

var
  sockAddr: TSockAddr;

begin
  Write(StdErr, 'Creating new Internet domain socket (UDP, port ', port, ')... ');
  inetDomainSocketHandle := fpSocket(PF_INET, SOCK_DGRAM, 0);
  try
    sockAddr.sin_family:= AF_INET;
    sockAddr.sin_port:= hToNS(port);
    sockAddr.sin_addr.s_addr:= 0;
    FillChar(sockAddr.sin_zero[0], SIZEOF(sockAddr.sin_zero), #0);
    if fpBind(inetDomainSocketHandle, @sockAddr, SIZEOF(sockAddr)) = 0 then
      WriteLn(StdErr, 'OK')
    else begin
      WriteLn(StdErr, 'failed, might need CAP_DAC_OVERRIDE,CAP_NET_BIND_SERVICE,CAP_NET_RAW=p+e');
      inetDomainSocketHandle := -Abs(ErrNo)
    end
  except
    WriteLn(StdErr, 'failed, might need CAP_DAC_OVERRIDE,CAP_NET_BIND_SERVICE,CAP_NET_RAW=p+e');
    inetDomainSocketHandle := -Abs(ErrNo)
  end

(* Assume that this will be deleted automatically at program termination.       *)

end { CreateInetDomainSocket } ;

Quote
Recall my example from a previous post.

Code: Pascal  [Select][+][-]
  1.    
  2.     debian@ebb:~$ sudo /sbin/ip link set can1 up type can bitrate 250000
  3.     debian@ebb:~$ candump can1
  4.       can1  721   [1]  05
  5.       can1  1A1   [8]  20 00 FF 0F A8 FD A8 FD
  6.  

...

So in general I get the feeling that to add socketCAN support to FPC will require a fairly extensive modification of the base sockets library.  Is there any interest in this?  Who's allowed to change it. 

Noting that you seem to have demonstrated that the "plug-in" nature of the Linux network stack functionality is working properly... are you saying that this is purely an FPC issue rather than a kernel one? At that point I'd expect that a patch via Mantis would be appropriate, particularly since this appears to move FPC and possibly Lazarus into an area that it's not previously supported.

MarkMLl
« Last Edit: October 22, 2020, 09:51:42 am by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

jcdammeyer

  • Full Member
  • ***
  • Posts: 205
  • Embedded System Developer
    • Automation Artisans Inc.
Re: CAN-BUS SockectCAN
« Reply #11 on: October 22, 2020, 10:07:36 am »

Noting that you seem to have demonstrated that the "plug-in" nature of the Linux network stack functionality is working properly... are you saying that this is purely an FPC issue rather than a kernel one? At that point I'd expect that a patch via Mantis would be appropriate, particularly since this appears to move FPC and possibly Lazarus into an area that it's not previously supported.

MarkMLl


Yes for both the BeagleBone and Pi and as I understand pretty well all Linux systems the socketCAN capability works well.  As the attached screen shot generated by the return result from the socket call with PF_CAN as the parameter shows.  PF_CAN doesn't exist so of course it fails.  The PF_CAN with a value of 29 doesn't exist in the definitions for socket.pp or whatever code is ultimately executed.  And the PF can is required so the system knows where to go for the data during a read.

Code: Pascal  [Select][+][-]
  1. const
  2.   PF_CAN = 29;
  3.   CAN_RAW = 1;
  4.  

Trouble is, GitHub and the associated read me files are so convoluted that I have no idea where to even start much less what to compile (if at all) to be able to duplicate the operation of the C programs.    I could make the changes but I don't know where to start.

Here's the example.  I realize bind should probably be used but it doesn't make it past the socket call.
Code: Pascal  [Select][+][-]
  1. unit socketunit;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Sockets, errors;
  9.  
  10. const
  11.   PF_CAN = 29;
  12.   CAN_RAW = 1;
  13.  
  14. type
  15.  
  16.   { TSocketForm }
  17.  
  18.   TSocketForm = class(TForm)
  19.     Button1: TButton;
  20.     Edit1: TEdit;
  21.     procedure Button1Click(Sender: TObject);
  22.   private
  23.  
  24.   public
  25.     socket_result : LongInt;
  26.     SAddr : TInetSockAddr;
  27.     Slen : TSockLen;
  28.     sin, sout : text;
  29.  
  30.   end;
  31.  
  32. var
  33.   SocketForm: TSocketForm;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. { TSocketForm }
  40.  
  41. procedure TSocketForm.Button1Click(Sender: TObject);
  42. var
  43.     i : integer;
  44. begin
  45.   // open socket
  46.   socket_result := fpsocket(PF_CAN, SOCK_RAW, CAN_RAW);
  47.   if (socket_result < 0) then begin
  48.         // perror("socket");
  49.     Edit1.text := 'Error #' + IntToStr(socket_result) + ' creating socket';
  50.   end
  51.   else begin
  52.     SAddr.sin_family := PF_CAN;
  53.     SAddr.xpad := 'can0';
  54.     if fpconnect(socket_result, @SAddr, 0) = -1 then begin
  55.       Edit1.text := 'Socket can''t connect: ' + strerror(socketerror);
  56.     end;
  57.   end;
  58. end;
  59.  
  60. end.
  61.  
« Last Edit: October 22, 2020, 10:10:38 am by jcdammeyer »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6647
Re: CAN-BUS SockectCAN
« Reply #12 on: October 22, 2020, 10:45:46 am »
At the very least I suggest getting a bug report in  suggesting that FPC's definition of PF_INET (and possibly AF_INET?) should be accompanied by one for PF_CAN. However I think that you'd need to make sure that you could provide (links to) the appropriate numeric values for different OSes, since I don't think the numeric values can be relied upon to be constant... you're basically telling the OS how to populate an internal table.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: CAN-BUS SockectCAN
« Reply #13 on: October 22, 2020, 11:15:23 am »
Here's the example.  I realize bind should probably be used but it doesn't make it past the socket call.
Because you are trying to use "SAddr : TInetSockAddr;" (C sockaddr) with SocketCAN, while you need to use C sockaddr_can. CAN C headers have not yet been translated to FPC. You will at least need sockaddr_can, ifreq and can_frame structures. You can find ifreq structure in \fpcsrc\packages\libc\src\nifh.inc, but the rest only in /usr/src/linux-source-5.8/include/uapi/linux/can.h and /usr/src/linux-source-5.8/include/uapi/linux/can/ (raw.h, bcm.h, error.h ...) waiting for translation.

Btw.1 You do not need CAN_FD for slcan devices since none of them implements faster CAN_FD yet (although CAN_FD is backwards compatible with slow CAN).
Btw.2 Did you read my previous message? I still think that socketcand path would be easier for you...
« Last Edit: October 22, 2020, 11:18:01 am by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

tetrastes

  • Sr. Member
  • ****
  • Posts: 469
Re: CAN-BUS SockectCAN
« Reply #14 on: October 22, 2020, 12:39:40 pm »
Code: Pascal  [Select][+][-]
  1.     if fpconnect(socket_result, @SAddr, 0) = -1 then begin
  2.  

Why the third parameter of fpconnect is zero?

 

TinyPortal © 2005-2018