我正在为Linux上的设备编写软件,该软件应与CAN接口配合使用。理想情况下,我想使用该接口而不连接c ++的第三方库。有可能吗?
答案 0 :(得分:0)
您需要查看Linux中的SocketCAN库。 您还可以使用candump和cansend帮助您进行开发,并查看candump.c和cansend.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));