dotnet核心中的SocketCAN

时间:2018-07-23 06:57:36

标签: linux .net-core can-bus

我正在为Linux上的设备编写软件,该软件应与CAN接口配合使用。理想情况下,我想使用该接口而不连接c ++的第三方库。有可能吗?

2 个答案:

答案 0 :(得分:0)

您需要查看Linux中的SocketCAN库。 您还可以使用candump和cansend帮助您进行开发,并查看candump.ccansend.c源文件以获取启发。

我看到有一个dotnet标签,如果您想在dotnet中使用CAN,我建议您编写一个小型C库来处理CAN内容。然后将其封送给dotnet,一旦您可以访问dotnet,就可以将其包装在类中并创建所需的任何抽象。

答案 1 :(得分:0)

我使用本机函数解决了此问题。在这里示例绑定套接字,可以使用本机函数write(或aio_write)读写消息并进行读取。以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));