一、下载libsocketcan-0.0.9.tar.bz2,在虚拟机里解压
配置好交叉编译环境。
进入解压的目录
创建一个shell脚本mymake.sh
添加如下内容:
#!/bin/sh
./configure --host=arm-linux --prefix=/home/wxh/wxh/tools/can/targat/libsocketcan
make
make install
#--host是所用的编译环境
#--prefix为生成的libsocketcan的库的路径
将生成的share、lib和include目录下的文件拷贝到开发板的对应目录
二、编译mcp2515测试程序
配置好交叉编译环境
测试源文件如下:
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <libsocketcan.h>
#include <getopt.h>
#include <libgen.h>
#include <signal.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <pthread.h>
#include <stdint.h>
//#include <can_config.h>
#ifndef PF_CAN
#define PF_CAN 29
#endif
#ifndef AF_CAN
#define AF_CAN PF_CAN
#endif
#define EXTENDED 1
#define RTR 1
#define BUF_SIZ 255
static void do_show_bitrate(const char *name)//打印波特率信息
{
struct can_bittiming bt;
if (can_get_bittiming(name, &bt) < 0)
{
fprintf(stderr, "%s: failed to get bitrate\n", name);
exit(EXIT_FAILURE);
}
else
{
fprintf(stdout,
"%s bitrate: %u, sample-point: %0.3f\n",
name, bt.bitrate,
(float)((float)bt.sample_point*0.001));
}
}
int do_set_bitrate(char *point, char *p_bitrate, const char *name)//设置波特率
{
__u32 bitrate = 0;
__u32 sample_point = 0;
int err;
bitrate = (__u32)strtoul(p_bitrate, NULL, 0);
sample_point = (__u32)(strtod(point, NULL) * 1000);
if (sample_point)
err = can_set_bitrate_samplepoint(name, bitrate, sample_point);
else
err = can_set_bitrate(name,bitrate);
if (err < 0) {
fprintf(stderr, "failed to set bitrate of %s to %u\n",
name, bitrate);
exit(EXIT_FAILURE);
}
do_show_bitrate(name);
return 0;
}
void init_can()//can总线的初始化
{
const char* name = "can0";
char bitrate[20];
char sample_point[20];
printf("please input bitrate:\n");
fgets(bitrate,sizeof(bitrate),stdin);
bitrate[strlen(bitrate)-1]=0;
printf("please input sample_point:\n");
fgets(sample_point,sizeof(sample_point),stdin);
sample_point[strlen(sample_point)-1]=0;
if (can_do_stop(name) < 0) {
fprintf(stderr, "%s: failed to stop\n", name);
}
do_set_bitrate(sample_point,bitrate,name);
if (can_do_start(name) < 0) {
fprintf(stderr, "%s: failed to start\n", name);
}
}
void *thread_sendmessage(void* arg)//发送信息
{
int s = (int)arg;
int ret,loopcount;
char *interface = "can0";
struct ifreq ifr;
struct sockaddr_can addr;
int family = PF_CAN;
struct can_frame frame = {
.can_id = 1,
};
char send_buff[10];
strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFINDEX, &ifr)) {
perror("ioctl");
return ;
}
addr.can_family = family;
addr.can_ifindex = ifr.ifr_ifindex;
while(1)
{
printf("please input data:\n");
fgets(send_buff,sizeof(send_buff),stdin);
send_buff[strlen(send_buff)-1]=0;
int send_lenp = sprintf(frame.data,"%s",send_buff);
frame.can_dlc = send_lenp;
frame.can_id &= CAN_EFF_MASK;
frame.can_id |= CAN_EFF_FLAG;
// if (RTR)
// frame.can_id |= CAN_RTR_FLAG;
#if 1
int send_lens= sendto(s,&frame,sizeof(struct can_frame),0,(struct sockaddr*)&addr,sizeof(addr));
#else
ret = write(s, &frame, sizeof(frame));
if (ret == -1)
{
perror("write");
}
#endif
}
close(s);
}
void *thread_recvmessage(void *arg)//接收消息
{
int s = (int)arg;
struct sockaddr_can addr;
struct can_frame frame;
char buf[BUF_SIZ];
int n = 0,len;
int nbytes, i;
while (1)
{
nbytes=recvfrom(s,&frame,sizeof(struct can_frame),0,(struct sockaddr *)&addr,&len);
if (frame.can_id & CAN_EFF_FLAG)
n = snprintf(buf, BUF_SIZ, "<0x%08x> ", frame.can_id & CAN_EFF_MASK);
else
n = snprintf(buf, BUF_SIZ, "<0x%03x> ", frame.can_id & CAN_SFF_MASK);
n += snprintf(buf + n, BUF_SIZ - n, "[%d] ", frame.can_dlc);
for (i = 0; i < frame.can_dlc; i++) {
n += snprintf(buf + n, BUF_SIZ - n, "%02x ", frame.data[i]);
}
if (frame.can_id & CAN_RTR_FLAG)
n += snprintf(buf + n, BUF_SIZ - n, "remote request");
fprintf(stdout, "recvmessage:%s\n", buf);
}
}
int main(int argc, char *argv[])
{
static struct can_filter *filter = NULL;
static int filter_count = 0;
struct ifreq ifr;
int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW;
struct sockaddr_can addr;
char *interface = "can0";
uint32_t id, mask;
int s;//socket描述符
init_can();
int add_filter(u_int32_t id, u_int32_t mask)
{
filter = realloc(filter, sizeof(struct can_filter) * (filter_count + 1));
if(!filter)
return -1;
filter[filter_count].can_id = id;
filter[filter_count].can_mask = mask;
filter_count++;
printf("id: 0x%08x mask: 0x%08x\n",id,mask);
return 0;
}
if ((s = socket(family, type, proto)) < 0) {
perror("socket");
return (-1);
}
strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFINDEX, &ifr)) {
perror("ioctl");
return ;
}
addr.can_family = family;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
return ;
}
if (filter) {
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, filter,
filter_count * sizeof(struct can_filter)) != 0) {
perror("setsockopt");
exit(1);
}
}
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,thread_sendmessage,(void*)s);
pthread_create(&tid2,NULL,thread_recvmessage,(void*)s);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
}
Makefile文件如下:
cantest:can_test.o
arm-linux-gcc -o cantest can_test.o -I/home/wxh/wxh/tools/can/targat/libsocketcan/include -L/home/wxh/wxh/tools/can/targat/libsocketcan/lib -lsocketcan -lpthread
can_test.o:can_test.c can_config.h
arm-linux-gcc -c can_test.c -I/home/wxh/wxh/tools/can/targat/libsocketcan/include -L/home/wxh/wxh/tools/can/targat/libsocketcan/lib -lsocketcan -lpthread
三、运行测试程序
将生成的可执行文件拷贝到开发板后就可以运行测试了。