使用 CMAKE 和 arm 工具链交叉编译 CAN 项目,但在查找 AF_CAN PF_CAN 时遇到问题
Cross-compiling a CAN project using CMAKE and an arm toolchain, but having issues finding AF_CAN PF_CAN
我正在使用 CMAKE 对嵌入式 arm 设备进行交叉编译,并且在定义 PF_CAN 和 AF_CAN 时遇到了一些问题。我被建议使用
sys/socket.h
但它不包含定义并且不能真正判断它是否间接指向它。
这是我现在的程序(超级简单)
/* A simple SocketCAN example */
#include <cstdlib>
#include <stdio.h>
#include <cstring>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <assert.h>
#include <errno.h>
#include <iostream>
#include <sys/socket.h> // i tried linux/socket.h and get some other errors, so I am confused.
#include <pthread.h>
#include <net/if.h>
#include <string.h>
#include <net/if.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int soc;
int read_can_port;
int open_port(const char *port)
{
ifreq ifr;
sockaddr_can addr;
/* open socket */
soc = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if(soc < 0)
{
return (-1);
}
addr.can_family = AF_CAN;
strcpy(ifr.ifr_name, port);
if (ioctl(soc, SIOCGIFINDEX, &ifr) < 0)
{
return (-1);
}
addr.can_ifindex = ifr.ifr_ifindex;
fcntl(soc, F_SETFL, O_NONBLOCK);
if (bind(soc, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
return (-1);
}
return 0;
}
int send_port(struct can_frame *frame)
{
int retval;
retval = write(soc, frame, sizeof(struct can_frame));
if (retval != sizeof(struct can_frame))
{
return (-1);
}
else
{
return (0);
}
}
/* this is just an example, run in a thread */
void read_port()
{
struct can_frame frame_rd;
int recvbytes = 0;
read_can_port = 1;
while(read_can_port)
{
struct timeval timeout = {1, 0};
fd_set readSet;
FD_ZERO(&readSet);
FD_SET(soc, &readSet);
if (select((soc + 1), &readSet, NULL, NULL, &timeout) >= 0)
{
if (!read_can_port)
{
break;
}
if (FD_ISSET(soc, &readSet))
{
recvbytes = read(soc, &frame_rd, sizeof(struct can_frame));
if(recvbytes)
{
printf("dlc = %d, data = %s\n",
frame_rd.can_dlc,frame_rd.data);
}
}
}
}
}
int close_port()
{
close(soc);
return 0;
}
int main(void)
{
std::cout << "Hello World! " << std::endl;
open_port("can0”");
read_port();
return 0;
}
这是我 运行 make:
时的输出
HelloWorld.cpp:45: 错误: 'PF_CAN' 未在此范围内声明
HelloWorld.cpp:45: 错误: 'PF_CAN' 未在此范围内声明
解决方案是添加
#ifndef AF_CAN
#define AF_CAN 29
#endif
这使得项目可以无错误地构建。此外,运行 实际目标设备上的项目和它通常 运行。
我刚刚 运行 遇到了同样的问题,不得不在我的代码中添加以下内容:
#ifndef PF_CAN
#define PF_CAN 29
#endif
#ifndef AF_CAN
#define AF_CAN PF_CAN
#endif
这些值是通常在 bits/socket.h.
中定义的标准控制器局域网协议族和地址族值
我弄明白了为什么我需要这样做,并且认为它需要在其他人 运行 遇到问题时分享,因为这将是一个类似的原因。
在我的例子中,这是因为 /opt/freescale/usr/local/gcc-4.3.50-eglibc-2.8.50/powerpc-linux-gnu/powerpc-linux-gnu/libc/usr/include/linux/socket.h 定义了这些值,但它们不再由于以下封装它们的编译宏而暴露:
#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
代码中的后续注释 "This mess will go away with glibc" 暗示库的大部分内容预计会随着 glibc 更新而改变;不幸的是,工具链没有在其他任何地方提供这些定义,因此需要在我的代码中定义它们。
即。如果您使用的是较旧的工具链并且在 bits/socket.h 中找不到这些值,可能是时候更新您的工具链了,或者您需要定义这些价值观你自己就像我必须的那样。
我正在使用 CMAKE 对嵌入式 arm 设备进行交叉编译,并且在定义 PF_CAN 和 AF_CAN 时遇到了一些问题。我被建议使用
sys/socket.h
但它不包含定义并且不能真正判断它是否间接指向它。
这是我现在的程序(超级简单)
/* A simple SocketCAN example */
#include <cstdlib>
#include <stdio.h>
#include <cstring>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <assert.h>
#include <errno.h>
#include <iostream>
#include <sys/socket.h> // i tried linux/socket.h and get some other errors, so I am confused.
#include <pthread.h>
#include <net/if.h>
#include <string.h>
#include <net/if.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int soc;
int read_can_port;
int open_port(const char *port)
{
ifreq ifr;
sockaddr_can addr;
/* open socket */
soc = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if(soc < 0)
{
return (-1);
}
addr.can_family = AF_CAN;
strcpy(ifr.ifr_name, port);
if (ioctl(soc, SIOCGIFINDEX, &ifr) < 0)
{
return (-1);
}
addr.can_ifindex = ifr.ifr_ifindex;
fcntl(soc, F_SETFL, O_NONBLOCK);
if (bind(soc, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
return (-1);
}
return 0;
}
int send_port(struct can_frame *frame)
{
int retval;
retval = write(soc, frame, sizeof(struct can_frame));
if (retval != sizeof(struct can_frame))
{
return (-1);
}
else
{
return (0);
}
}
/* this is just an example, run in a thread */
void read_port()
{
struct can_frame frame_rd;
int recvbytes = 0;
read_can_port = 1;
while(read_can_port)
{
struct timeval timeout = {1, 0};
fd_set readSet;
FD_ZERO(&readSet);
FD_SET(soc, &readSet);
if (select((soc + 1), &readSet, NULL, NULL, &timeout) >= 0)
{
if (!read_can_port)
{
break;
}
if (FD_ISSET(soc, &readSet))
{
recvbytes = read(soc, &frame_rd, sizeof(struct can_frame));
if(recvbytes)
{
printf("dlc = %d, data = %s\n",
frame_rd.can_dlc,frame_rd.data);
}
}
}
}
}
int close_port()
{
close(soc);
return 0;
}
int main(void)
{
std::cout << "Hello World! " << std::endl;
open_port("can0”");
read_port();
return 0;
}
这是我 运行 make:
时的输出HelloWorld.cpp:45: 错误: 'PF_CAN' 未在此范围内声明 HelloWorld.cpp:45: 错误: 'PF_CAN' 未在此范围内声明
解决方案是添加
#ifndef AF_CAN
#define AF_CAN 29
#endif
这使得项目可以无错误地构建。此外,运行 实际目标设备上的项目和它通常 运行。
我刚刚 运行 遇到了同样的问题,不得不在我的代码中添加以下内容:
#ifndef PF_CAN
#define PF_CAN 29
#endif
#ifndef AF_CAN
#define AF_CAN PF_CAN
#endif
这些值是通常在 bits/socket.h.
中定义的标准控制器局域网协议族和地址族值我弄明白了为什么我需要这样做,并且认为它需要在其他人 运行 遇到问题时分享,因为这将是一个类似的原因。
在我的例子中,这是因为 /opt/freescale/usr/local/gcc-4.3.50-eglibc-2.8.50/powerpc-linux-gnu/powerpc-linux-gnu/libc/usr/include/linux/socket.h 定义了这些值,但它们不再由于以下封装它们的编译宏而暴露:
#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
代码中的后续注释 "This mess will go away with glibc" 暗示库的大部分内容预计会随着 glibc 更新而改变;不幸的是,工具链没有在其他任何地方提供这些定义,因此需要在我的代码中定义它们。
即。如果您使用的是较旧的工具链并且在 bits/socket.h 中找不到这些值,可能是时候更新您的工具链了,或者您需要定义这些价值观你自己就像我必须的那样。