|
@@ -0,0 +1,235 @@
|
|
|
+/**
|
|
|
+ ******************************************************************************
|
|
|
+ * @file : test_1.cpp
|
|
|
+ * @author : wangyingjie
|
|
|
+ * @brief : None
|
|
|
+ * @attention : None
|
|
|
+ * @date : 2025/6/20
|
|
|
+ ******************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+#ifdef WIN32 // for windows
|
|
|
+#include <windows.h>
|
|
|
+#include <process.h>
|
|
|
+#include <stdio.h>
|
|
|
+#include <time.h>
|
|
|
+#include "controlcan.h"
|
|
|
+#pragma comment(lib, "controlcan.lib")
|
|
|
+#define msleep(ms) Sleep(ms)
|
|
|
+typedef HANDLE pthread_t;
|
|
|
+#else // for linux
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <string.h>
|
|
|
+#include <strings.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <sys/types.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+#include <fcntl.h>
|
|
|
+#include <pthread.h>
|
|
|
+#include "controlcan.h"
|
|
|
+#define msleep(ms) usleep((ms) * 1000)
|
|
|
+#define min(a, b) (((a) < (b)) ? (a) : (b))
|
|
|
+#endif
|
|
|
+
|
|
|
+#define MAX_CHANNELS 4
|
|
|
+#define CHECK_POINT 200
|
|
|
+#define RX_WAIT_TIME 100
|
|
|
+#define RX_BUFF_SIZE 1000
|
|
|
+
|
|
|
+unsigned gDevType = 0; // 设备类型号
|
|
|
+unsigned gDevIdx = 0; // 设备索引,第一个设备是0,第二个相同信号设备是1
|
|
|
+unsigned gChMask = 0; // 通道掩码,CAN0 = 1,CAN1=2,CAN0+CAN1=3
|
|
|
+unsigned gBaud = 0; // 波特率
|
|
|
+unsigned gTxType = 0; // 发送类型,正常发送=0,单次发送=1,自发自收=2,单次自发自收=3
|
|
|
+unsigned gTxSleep = 0; // 发送帧间隔
|
|
|
+unsigned gTxFrames = 0; // 每次发送帧数
|
|
|
+unsigned gTxCount = 0; // 发送次数
|
|
|
+
|
|
|
+// 将字符串表示的十六进制数转换为无符号整数
|
|
|
+unsigned s2n(const char *s)
|
|
|
+{
|
|
|
+ unsigned l = strlen(s);
|
|
|
+ unsigned v = 0;
|
|
|
+ unsigned h = (l > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
|
|
|
+ unsigned char c;
|
|
|
+ unsigned char t;
|
|
|
+ if (!h)
|
|
|
+ return atoi(s);
|
|
|
+ if (l > 10)
|
|
|
+ return 0;
|
|
|
+ for (s += 2; c = *s; s++)
|
|
|
+ {
|
|
|
+ if (c >= 'A' && c <= 'F')
|
|
|
+ c += 32;
|
|
|
+ if (c >= '0' && c <= '9')
|
|
|
+ t = c - '0';
|
|
|
+ else if (c >= 'a' && c <= 'f')
|
|
|
+ t = c - 'a' + 10;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+ v = (v << 4) | t;
|
|
|
+ }
|
|
|
+ return v;
|
|
|
+}
|
|
|
+
|
|
|
+typedef struct
|
|
|
+{
|
|
|
+ unsigned channel; // channel index, 0~3 通道索引
|
|
|
+ unsigned stop; // stop RX-thread 停止接受线程标志
|
|
|
+ unsigned total; // total received 接收到的总数据量
|
|
|
+ unsigned error; // error(s) detected 错误数量
|
|
|
+} RX_CTX;
|
|
|
+
|
|
|
+#ifdef WIN32
|
|
|
+unsigned __stdcall rx_thread(void *data)
|
|
|
+#else
|
|
|
+void *rx_thread(void *data)
|
|
|
+#endif
|
|
|
+{
|
|
|
+ RX_CTX *ctx = (RX_CTX *)data;
|
|
|
+ ctx->total = 0; // reset counter 重置计数器
|
|
|
+
|
|
|
+ VCI_CAN_OBJ can[RX_BUFF_SIZE]; // buffer
|
|
|
+ int cnt; // current received
|
|
|
+ int i;
|
|
|
+
|
|
|
+ unsigned check_point = 0;
|
|
|
+ while (!ctx->stop) // 在不停止的情况下
|
|
|
+ {
|
|
|
+ cnt = VCI_Receive(gDevType, gDevIdx, ctx->channel, can, RX_BUFF_SIZE, RX_WAIT_TIME); // 接受函数,返回读取到的帧数
|
|
|
+ if (!cnt)
|
|
|
+ continue;
|
|
|
+ for (i = 0; i < cnt; i++)
|
|
|
+ {
|
|
|
+ printf("ID: 0X%X ", can[i].ID);
|
|
|
+ printf("TimeStamp: %d ", can[i].TimeStamp);
|
|
|
+ printf("Data: ");
|
|
|
+ for (int j = 0; j < can[i].DataLen; j++)
|
|
|
+ {
|
|
|
+ printf("%02X ", can[i].Data[j]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ printf("CAN%d RX thread terminated\n", ctx->channel);
|
|
|
+
|
|
|
+#ifdef WIN32
|
|
|
+ _endthreadex(0);
|
|
|
+ return 0;
|
|
|
+#else
|
|
|
+ pthread_exit(0);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+int test()
|
|
|
+{
|
|
|
+ // ----- init & start -------------------------------------------------
|
|
|
+
|
|
|
+ // 板卡初始化结构体
|
|
|
+ VCI_INIT_CONFIG config;
|
|
|
+ config.AccCode = 0; // 验收码
|
|
|
+ config.AccMask = 0xffffffff; // 屏蔽码
|
|
|
+ config.Filter = 1; // 滤波方式,1表示单滤波,0表示双滤波
|
|
|
+ config.Mode = 0; // 0表示正常模式,1表示只听模式
|
|
|
+ config.Timing0 = gBaud & 0xff; // 波特率定时器0
|
|
|
+ config.Timing1 = gBaud >> 8; // 波特率定时器1
|
|
|
+
|
|
|
+ int i, j;
|
|
|
+ for (i = 0; i < MAX_CHANNELS; i++)
|
|
|
+ {
|
|
|
+ if ((gChMask & (1 << i)) == 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ // 初始化CAN通道 设备类型号,设备索引号,第几路CAN,初始化参数结构(VCI_INIT_CONFIG结构体变量)
|
|
|
+ if (!VCI_InitCAN(gDevType, gDevIdx, i, &config))
|
|
|
+ {
|
|
|
+ printf("VCI_InitCAN(%d) failed\n", i);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ printf("VCI_InitCAN(%d) succeeded\n", i);
|
|
|
+
|
|
|
+ // 启动CAN通道 设备类型号,设备索引号,第几路CAN
|
|
|
+ if (!VCI_StartCAN(gDevType, gDevIdx, i))
|
|
|
+ {
|
|
|
+ printf("VCI_StartCAN(%d) failed\n", i);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ printf("VCI_StartCAN(%d) succeeded\n", i);
|
|
|
+ }
|
|
|
+
|
|
|
+ VCI_CAN_OBJ can;
|
|
|
+
|
|
|
+ // 创建接收线程
|
|
|
+ RX_CTX rx_ctx[MAX_CHANNELS];
|
|
|
+ pthread_t rx_threads[MAX_CHANNELS];
|
|
|
+ for (i = 0; i < MAX_CHANNELS; i++)
|
|
|
+ {
|
|
|
+ if ((gChMask & (1 << i)) == 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ rx_ctx[i].channel = i;
|
|
|
+ rx_ctx[i].stop = 0;
|
|
|
+ rx_ctx[i].total = 0;
|
|
|
+ rx_ctx[i].error = 0;
|
|
|
+#ifdef WIN32
|
|
|
+ rx_threads[i] = (HANDLE)_beginthreadex(NULL, 0, rx_thread, &rx_ctx[i], 0, NULL);
|
|
|
+#else
|
|
|
+ pthread_create(&rx_threads[i], NULL, rx_thread, &rx_ctx[i]); // 创建一个新的线程
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ // 停止接收
|
|
|
+ printf("<ENTER> to terminate RX-threads...\n");
|
|
|
+ getchar();
|
|
|
+ for (i = 0; i < MAX_CHANNELS; i++)
|
|
|
+ {
|
|
|
+ if ((gChMask & (1 << i)) == 0)
|
|
|
+ continue;
|
|
|
+ rx_ctx[i].stop = 1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int main(int argc, char *argv[])
|
|
|
+{
|
|
|
+ // if (argc < 5)
|
|
|
+ // {
|
|
|
+ // printf("test [DevType] [DevIdx] [ChMask] [Baud]\n"
|
|
|
+ // " example: test 3 0 1 0x1c00 \n"
|
|
|
+ // " | | | |\n"
|
|
|
+ // " | | | |0x1400-1M, 0x1c00-500K, 0x1C01-250K ....\n"
|
|
|
+ // " | | |\n"
|
|
|
+ // " | | |bit0-CAN1, bit1-CAN2, bit2-CAN3, bit3-CAN4, 3=CAN1+CAN2, 7=CAN1+CAN2+CAN3\n"
|
|
|
+ // " | |\n"
|
|
|
+ // " | |Card0\n"
|
|
|
+ // " |\n"
|
|
|
+ // " |3-usbcan-i, 4-usbcan-ii ....\n");
|
|
|
+ // return 0;
|
|
|
+ // }
|
|
|
+ // gDevType = s2n(argv[1]);
|
|
|
+ // gDevIdx = s2n(argv[2]);
|
|
|
+ // gChMask = s2n(argv[3]);
|
|
|
+ // gBaud = s2n(argv[4]);
|
|
|
+
|
|
|
+ gDevType = s2n("3");
|
|
|
+ gDevIdx = s2n("0");
|
|
|
+ gChMask = s2n("1");
|
|
|
+ gBaud = s2n("0x1c00");
|
|
|
+ printf("DevType=%d, DevIdx=%d, ChMask=0x%x, Baud=0x%04x\n", gDevType, gDevIdx, gChMask, gBaud);
|
|
|
+
|
|
|
+ // 打开设备 设备类型号,设备索引号,0
|
|
|
+ if (!VCI_OpenDevice(gDevType, gDevIdx, 0))
|
|
|
+ {
|
|
|
+ printf("VCI_OpenDevice failed\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ printf("VCI_OpenDevice succeeded\n");
|
|
|
+
|
|
|
+ test();
|
|
|
+
|
|
|
+ // 关闭设备 设备类型号,设备索引号
|
|
|
+ VCI_CloseDevice(gDevType, gDevIdx);
|
|
|
+ printf("VCI_CloseDevice\n");
|
|
|
+ return 0;
|
|
|
+}
|