Hello
You must start a script who intialize the CAN.
You can do that at startup or include this script into your application.
In your project create a folder “script” , inside create a file “can_init.sh”
copy/paste this code into “can_init.sh”
#!/bin/sh
export PATH=$PATH:/sbin
ifconfig can0 down
echo 2 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio2/direction
echo 1 > /sys/class/gpio/gpio2/value
echo 13 > /sys/class/gpio/export &&
echo out > /sys/class/gpio/gpio13/direction &&
echo 1 > /sys/class/gpio/gpio13/value &&
modprobe can &&
sleep 1 &&
modprobe can-dev &&
sleep 1 &&
modprobe can-raw &&
sleep 1 &&
modprobe mcp251x &&
sleep 1
CAN=ifconfig | cut -c -4 | sed 's/^\s\+//' | sort | uniq | grep can0
if [ -z “$CAN” ]; then
ip link set can0 type can bitrate 500000 triple-sampling on &&
sleep 1 &&
ifconfig can0 up
fi
In your app create this function :
#include <net/if.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define INTERFACE_NAME_SIZE 15
#define SOCKET_ERROR 1
#define SOCK_IOCTL_ERROR 2
#define SOCK_BINDING_ERROR 3
#define SOCK_WRITING_ERROR 4
#define SOCK_READING_ERROR 5
#define WRONG_DLC 6
#define WRONG_ID 7
int bitrate;
int sdw; // socket descriptor write
int sdr; // socket descriptor read
int nbytesReceive;
bool canwrite;
char name[INTERFACE_NAME_SIZE];
struct can_frame frameRead;
struct can_frame frameWrite;
int can_connect(const char *interface)
{
struct sockaddr_can addr;
struct ifreq ifr;
int sock_buf_size;
sock_buf_size = 1000;
// Run the can-init.sh before advertising the service to ensure that the CAN device is
// available before we allow it to be used.
char line[256];
FILE* fp = popen("can_init.sh 2>&1", "r");
LE_ASSERT(fp != NULL);
while (fgets(line, sizeof(line), fp) != NULL)
{
LE_INFO("can_init.sh output: %s", line);
}
int canInitResult = pclose(fp);
LE_FATAL_IF(!WIFEXITED(canInitResult), "Could not run can_init.sh");
const int canInitExitCode = WEXITSTATUS(canInitResult);
LE_FATAL_IF(canInitExitCode != 0, "can_init.sh failed with exit code %d", canInitExitCode);
// if interface string is long we will cut it
if(strlen(interface)>INTERFACE_NAME_SIZE)
{
memcpy(name,interface,INTERFACE_NAME_SIZE);
name[INTERFACE_NAME_SIZE-1]='\0';
}
else
{
strcpy(name,interface);
}
// SOCKET FOR READING
if ((sdr = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
return SOCKET_ERROR;
}
addr.can_family = PF_CAN;
strcpy(ifr.ifr_name, name);
if (ioctl(sdr, SIOCGIFINDEX, &ifr) < 0)
{
return SOCK_IOCTL_ERROR;
}
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(sdr, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
return SOCK_BINDING_ERROR;
}
// Filter
struct can_filter rfilter[7]; int i = 0;
rfilter[i].can_id = CHG_TX_STS;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = CHG_TX_ACT;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_CHRGR_CTL;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_SOC_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_BATTP_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_BATP_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_BATU_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
setsockopt(sdr, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
// SET SOCKET BUFFER SIZE
setsockopt(sdr, SOL_CAN_RAW, SO_RCVBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
// SOCKET FOR WRITING
if ((sdw = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
return SOCKET_ERROR;
}
addr.can_family = PF_CAN;
strcpy(ifr.ifr_name, name);
if (ioctl(sdw, SIOCGIFINDEX, &ifr) < 0)
{
return SOCK_IOCTL_ERROR;
}
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(sdw, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
return SOCK_BINDING_ERROR;
}
// SET SOCKET BUFFER SIZE
setsockopt(sdw, SOL_CAN_RAW, SO_SNDBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
//READ SOCKET NON-BLOCKING
int flags;
if (-1 == (flags = fcntl(sdr, F_GETFL, 0))) flags = 0;
fcntl(sdr, F_SETFL, flags | O_NONBLOCK);
return 0;
}
int can_disconnect(void)
{
close(sdw);
close(sdr);
return 0;
}
int can_send(void)
{
int nbytesWrite;
// USE SEND STANDARD FRAME
frameWrite.can_id = 0x600;
frameWrite.can_id &= CAN_SFF_MASK;
frameWrite.can_dlc = 8;
strcpy((char *)frameWrite.data, "MangoH ");
if ((nbytesWrite = write(sdw, &frameWrite, sizeof(frameWrite))) != sizeof(frameWrite))
{
canwrite = false;
LE_INFO ("Writing error");
return SOCK_WRITING_ERROR;
}
canwrite = true;
return 0;
}
int can_receive(void)
{
nbytesReceive = 1;
while (nbytesReceive != 0)
{
if ((nbytesReceive = read(sdr, &frameRead, sizeof(frameRead))) != sizeof(frameRead))
{
return SOCK_READING_ERROR;
}
/else
LE_INFO(“Receive message %X %X %X %X %X %X %X %X %X”, frameRead.can_id, frameRead.data[0], frameRead.data[1], frameRead.data[2], frameRead.data[3]
, frameRead.data[4], frameRead.data[5], frameRead.data[6], frameRead.data[7]);/
}
return 0;
}
You just now to call it in your main :
COMPONENT_INIT
{
can_connect(“can0”);
can_send();
can_receive();
}