dotnet 核心中的 SocketCAN
SocketCAN in dotnet core
我正在为 Linux 上的设备编写软件,它应该可以与 CAN 接口一起使用。理想情况下,我希望在不连接来自 c ++ 的第三方库的情况下使用该接口。可能吗?
您需要查看 SocketCAN 库,它是 Linux 的一部分。
您还可以使用 candump 和 cansend 来帮助您开发,也可以查看 candump.c and cansend.c 源文件以获取灵感。
我看到有一个 dotnet 标签,如果你想在 dotnet 中使用 CAN,我建议你写一个小的 C 库来处理 CAN 的东西。然后将其编组到 dotnet,一旦您可以访问 dotnet,您就可以将内容包装在 类 中并创建您需要的任何抽象。
我使用本机函数解决了这个问题。这里示例绑定套接字,可以使用本地函数 write( or aio_write) 和 read 读写消息。 CanPublisher in UDSim 例如
const int Siocgifindex = 0x8933;
private const int PfCan = 29;
private const int SockRaw = 3;
private const int CanRaw = 1;
private const int CanMtu = 16;
[DllImport("libc", SetLastError = true)]
private static extern int socket(int domain, int type, int protocol);
[DllImport("libc", SetLastError = true)]
private static extern int ioctl(int fd, int request, ref Ifreq mtu);
[DllImport("libc", SetLastError = true)]
private static extern int bind(int fd, ref SockaddrCan addr, int addrlen);
[StructLayout(LayoutKind.Sequential)]
struct SockaddrCan
{
public ushort can_family;
public int can_ifindex;
public uint rx_id;
public uint tx_id;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct Ifreq
{
public Ifreq(string ifr_name)
{
this.ifr_name = ifr_name;
this.ifr_ifindex = 0; // ifru_ivalue
this.ifru_mtu = 0;
}
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string ifr_name;
public int ifr_ifindex;
public uint ifru_mtu;
}
var addr = new SockaddrCan();
var s = socket(PfCan, SockRaw, CanRaw);
var ifr = new Ifreq("vcan0");
var ret = ioctl(s, Siocgifindex, ref ifr);
addr.can_ifindex = ifr.ifr_ifindex;
addr.can_family = PfCan;
ret = bind(s, ref addr, Marshal.SizeOf(addr));
我已经为 SocketCAN 编写了一个名为 SocketCAN# (SocketCANSharp) 的 .NET 托管包装器库:https://github.com/derek-will/SocketCANSharp
SocketCAN# 允许在 Linux.
上的 .NET 应用程序中使用原始 CAN、ISO-TP、广播管理器和 J1939 套接字
一些示例代码:
IEnumerable<CanNetworkInterface> collection = CanNetworkInterface.GetAllInterfaces(true);
var iface = collection.FirstOrDefault(i => i.Name.Equals("vcan0"));
using (var rawCanSocket = new RawCanSocket())
{
rawCanSocket.Bind(iface);
int bytesWritten = rawCanSocket.Write(
new CanFrame(0x123, new byte[] { 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }));
}
库下面使用 P/Invoke 调用本机 libc 函数并在托管代码和非托管代码之间来回编组各种类型。
我正在为 Linux 上的设备编写软件,它应该可以与 CAN 接口一起使用。理想情况下,我希望在不连接来自 c ++ 的第三方库的情况下使用该接口。可能吗?
您需要查看 SocketCAN 库,它是 Linux 的一部分。 您还可以使用 candump 和 cansend 来帮助您开发,也可以查看 candump.c and cansend.c 源文件以获取灵感。
我看到有一个 dotnet 标签,如果你想在 dotnet 中使用 CAN,我建议你写一个小的 C 库来处理 CAN 的东西。然后将其编组到 dotnet,一旦您可以访问 dotnet,您就可以将内容包装在 类 中并创建您需要的任何抽象。
我使用本机函数解决了这个问题。这里示例绑定套接字,可以使用本地函数 write( or aio_write) 和 read 读写消息。 CanPublisher in UDSim 例如
const int Siocgifindex = 0x8933;
private const int PfCan = 29;
private const int SockRaw = 3;
private const int CanRaw = 1;
private const int CanMtu = 16;
[DllImport("libc", SetLastError = true)]
private static extern int socket(int domain, int type, int protocol);
[DllImport("libc", SetLastError = true)]
private static extern int ioctl(int fd, int request, ref Ifreq mtu);
[DllImport("libc", SetLastError = true)]
private static extern int bind(int fd, ref SockaddrCan addr, int addrlen);
[StructLayout(LayoutKind.Sequential)]
struct SockaddrCan
{
public ushort can_family;
public int can_ifindex;
public uint rx_id;
public uint tx_id;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct Ifreq
{
public Ifreq(string ifr_name)
{
this.ifr_name = ifr_name;
this.ifr_ifindex = 0; // ifru_ivalue
this.ifru_mtu = 0;
}
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string ifr_name;
public int ifr_ifindex;
public uint ifru_mtu;
}
var addr = new SockaddrCan();
var s = socket(PfCan, SockRaw, CanRaw);
var ifr = new Ifreq("vcan0");
var ret = ioctl(s, Siocgifindex, ref ifr);
addr.can_ifindex = ifr.ifr_ifindex;
addr.can_family = PfCan;
ret = bind(s, ref addr, Marshal.SizeOf(addr));
我已经为 SocketCAN 编写了一个名为 SocketCAN# (SocketCANSharp) 的 .NET 托管包装器库:https://github.com/derek-will/SocketCANSharp
SocketCAN# 允许在 Linux.
上的 .NET 应用程序中使用原始 CAN、ISO-TP、广播管理器和 J1939 套接字一些示例代码:
IEnumerable<CanNetworkInterface> collection = CanNetworkInterface.GetAllInterfaces(true);
var iface = collection.FirstOrDefault(i => i.Name.Equals("vcan0"));
using (var rawCanSocket = new RawCanSocket())
{
rawCanSocket.Bind(iface);
int bytesWritten = rawCanSocket.Write(
new CanFrame(0x123, new byte[] { 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }));
}
库下面使用 P/Invoke 调用本机 libc 函数并在托管代码和非托管代码之间来回编组各种类型。