Hotwheel Technology has developed a rk3588s motherboard youyeetoo R1, which provides 40pin expansion pins, including 1 can pin. The pin distribution is shown in the figure below:
If you want to use shell commands in the Android system, you need to enter the Android command line window through ADB. For the tutorial on using ADB, please refer to the chapter adb debugging . After opening the Android system command line through adb,
adb root
adb shell
ifconfig can0 down
ip link set can0 up type can bitrate 100000
ip -details link show can0
ifconfig can0 up
The permission management of the Android system is very strict. Using c++ or java to operate files or resources in the Android root file system requires corresponding permissions. The ndk program written here is written based on the system app as a template. For system app, please refer to the chapter Creating system app.
#include <jni.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#define can_up "ifconfig can0 up"//Open CAN0
#define can_down "ifconfig can0 down"//Close CAN0
static void setCan0Bitrate(int nBitRate)
{
char anCanCommand[128] = {0,};
printf("- can0 down \n");
system(can_down);
printf("- can0 config bitrate %d\n", nBitRate);
sprintf(&anCanCommand[0], "ip link set can0 type can bitrate %d", nBitRate);
system(anCanCommand);
printf("- can0 up \n");
system(can_up);//Close the CAN device, set the baud rate, and reopen the CAN device
}
int can0Init(int nBitRate)
{
int nCanFd;
struct sockaddr_can addr;
struct ifreq ifr;
setCan0Bitrate(nBitRate); //Configure can0 baud rate
nCanFd = socket(PF_CAN, SOCK_RAW, CAN_RAW);//Create a socket
printf("- can0 socket \n");
strcpy(ifr.ifr_name, "can0" );
ioctl(nCanFd, SIOCGIFINDEX, &ifr); //Specify can0 device
printf("- can0 ioctl \n");
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind(nCanFd, (struct sockaddr *)&addr, sizeof(addr));//Bind the socket to can0
printf("- can0 binded \n");
return nCanFd;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_youyeetoo_r1_1i2cdemo_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
int nCanFd, nbytes;
struct can_frame frame[2] = {{0}};
nCanFd = can0Init(1000000); //Create can instantiation object
frame[0].can_id = 0x666;
frame[0].can_dlc = 8;
frame[0].data[0] = 0x40;
frame[0].data[1] = 0x20;
frame[0].data[2] = 0x10;
frame[0].data[3] = 0x00;
frame[0].data[4] = 0x03;
frame[0].data[5] = 0x04;
frame[0].data[6] = 0x05;
frame[0].data[7] = 0x06;
for(int i=0;i<10;i++)
{
printf("- for enter: %d \n", i);
frame[0].data[7]++;
printf("send frames: 0x40 0x20 0x10 0x00 0x03 0x04 0x05 0x06 \n");
nbytes = write(nCanFd, &frame[0], sizeof(frame[0])); //Send frame[0]
if(nbytes != sizeof(frame[0]))
{
printf("Send Error frame[0]\n!");
}
nbytes = read(nCanFd, &frame[1], sizeof(frame[1]));//The message received on the bus is saved in frame[1]
printf("the nbytes:%d\n", nbytes);
printf("length:%d \n", sizeof(frame[1]));
printf("ID=0x%X DLC=%d\n", frame[1].can_id, frame[1].can_dlc);
printf("data0=0x%02x\n",frame[1].data[0]);
printf("data1=0x%02x\n",frame[1].data[1]);
printf("data2=0x%02x\n",frame[1].data[2]);
printf("data3=0x%02x\n",frame[1].data[3]);
printf("data4=0x%02x\n",frame[1].data[4]);
printf("data5=0x%02x\n",frame[1].data[5]);
printf("data6=0x%02x\n",frame[1].data[6]);
printf("data7=0x%02x\n",frame[1].data[7]);
sleep(1);
}
close(nCanFd);
return env->NewStringUTF(show_buf);
}