The CANtegrity API can be used to obtain detailed information about the traffic on a CAN bus. To use the CANtegrity API, a device that supports it is needed, such as the Kvaser USBcan Pro 2xHS v2.
If a device supports CANtegrity, it will have the canCHANNEL_CAP_CANTEGRITY flag set in its channel capabilities. To check whether the flag is set or not, use the canGetChannelData API call with the canCHANNELDATA_CHANNEL_CAP item as follows.
uint32_t capabilities;
if (capabilities & canCHANNEL_CAP_CANTEGRITY) {
}
Setting up an analyzer
To use the API, both the "canlib.h" and "kvDiag.h" header files need to be included in the program.
First, a CAN channel must be opened on the CANtegrity device to obtain a canHandle.
Then, attach an analyzer to the open channel.
Decide which analyzer program to run. Currently there are two analyzer programs, DIAG_PROGRAM_TYPE_NORMAL and DIAG_PROGRAM_TYPE_AUTOBAUD. The former samples CAN frames from the bus and gives detailed information about the timing characteristics, while the latter can be used to find out the bitrate of a running CAN bus.
Choosing an analyzer program is done through the kvDiagSetProgram API call, which requires a JSON configuration as an argument. For DIAG_PROGRAM_TYPE_AUTOBAUD, no configuration is needed so pass an empty JSON string, "{}". DIAG_PROGRAM_TYPE_NORMAL needs bus parameters in the configuration, the details of which can be found in the kvDiagSetProgram reference.
Now, the analyzer program can be started by calling kvDiagStart.
There are different functions available for interacting with a running analyzer program. kvDiagReadSample and kvDiagReadSampleWait are used with DIAG_PROGRAM_TYPE_NORMAL , kvDiagCalculateBitrate and kvDiagResetBitrateCalculation are used with DIAG_PROGRAM_TYPE_AUTOBAUD, and kvDiagCalculateClockOffset and kvDiagResetClockOffsetCalculation can be used with both analyzer programs. For details on their usage, see the API reference.
When finished, call kvDiagStop, kvDiagDetachAnalyzer and canClose in that order to stop the CANtegrity device.
Below, two complete sample programs are provided showcasing how the CANtegrity API is used.
Samples
Example: Continuously read samples from the CAN bus using DIAG_PROGRAM_TYPE_NORMAL and print some information about the samples.
#include "stdio.h"
#include "signal.h"
static void check(
const char *name,
canStatus status);
static void intHandler(int unused);
static void usage();
static int interrupt = 0;
static const char *CONF_500KBIT = "{"
"\"tseg1\" : 59,"
"\"tseg2\" : 20,"
"\"sjw\" : 16,"
"\"brp\" : 2"
"}";
int main(int argc, char *argv[])
{
int channel = -1;
for (int i=1; i<argc; i++) {
if (sscanf(argv[i], "-ch=%d", &channel) == 1);
else {
usage();
exit(1);
}
}
if (channel == -1) {
usage();
exit(1);
}
check("kvDiagAttachAnalyzer", stat);
check("kvDiagSetProgram", stat);
check("kvDiagStart", stat);
signal(SIGINT, intHandler);
while (1) {
if (stat == canOK) {
printSample(&sample);
}
if (interrupt) {
break;
}
}
check("kvDiagStop", stat);
check("kvDiagDetachAnalyzer", stat);
check("canClose", stat);
return 0;
}
static void check(
const char *name,
canStatus status)
{
if (status != canOK) {
printf("%s returned %d\n", name, status);
exit(1);
}
}
static void intHandler(int unused)
{
interrupt = 1;
}
{
uint64_t time = sample->
sample.startTime;
int value = sample->
sample.startValue;
int i = 0;
printf("Start \t End \t Length (microseconds) \t Value\n");
printf("-----------------------------------------------\n");
do {
printf("%6llu \t %6llu \t %2.2f \t\t %u\n",
time,
time + sample->
sample.edgeTimes[i],
(1.0 * sample->
sample.edgeTimes[i]) / (1.0 * sample->
sample.sampleFreq),
value);
time += sample->
sample.edgeTimes[i];
value = !value;
i++;
} while (i < sample->sample.edgeCount);
printf("-----------------------------------------------\n\n");
}
{
printf("CAN ID: 0x%x SEQ: %u. DLC: %u, flags: 0x%x, data:",
if (sample->
msg.dlc > 0) {
for (
int i=0; i < sample->
msg.dlc; i++) {
printf(
" %02X", (
unsigned char)sample->
msg.data[i]);
}
}
printf("\n\n");
printEdges(sample);
}
static void usage()
{
printf(
"Usage: 'normal_example -ch=n', "
"where 'n' is a CANlib channel with analyzer capability.\n\n"
"Note: This program requires a working CAN bus with traffic to function properly.\n");
}
Example: Continuously measure bitrate of a CAN bus using DIAG_PROGRAM_TYPE_AUTOBAUD .
#include "stdio.h"
#include "signal.h"
static void check(
const char *name,
canStatus status);
static void intHandler(int unused);
static void usage();
static int interrupt = 0;
int main(int argc, char *argv[])
{
int channel = -1;
for (int i=1; i<argc; i++) {
if (sscanf(argv[i], "-ch=%d", &channel) == 1);
else {
usage();
exit(1);
}
}
if (channel == -1) {
usage();
exit(1);
}
check("kvDiagAttachAnalyzer", stat);
check("kvDiagSetProgram", stat);
check("kvDiagStart", stat);
signal(SIGINT, intHandler);
while (1) {
Sleep(100);
if (stat == canOK) {
printf("Estimated CAN bitrate to %.0f KBit/s with quality %d %%.\n",
}
check("kvDiagResetBitrateCalculation", stat);
if (interrupt) {
break;
}
}
check("kvDiagStop", stat);
check("kvDiagDetachAnalyzer", stat);
check("canClose", stat);
return 0;
}
static void check(
const char *name,
canStatus status)
{
if (status != canOK) {
printf("%s returned %d\n", name, status);
exit(1);
}
}
static void intHandler(int unused)
{
interrupt = 1;
}
static void usage()
{
printf(
"Usage: 'autobaud_example -ch=n', "
"where 'n' is a CANlib channel with analyzer capability.\n\n"
"Note: This program requires a working CAN bus with traffic to function properly.\n");
}