example/c/kvdiag/normal.c
#include "stdio.h"
#include "signal.h"
#include "canlib.h"
#include "kvDiag.h"
static void check(const char *name, canStatus status); /* Checks for errors */
static void intHandler(int unused); /* Handle Ctrl-C */
static void printSample(kvDiagSample *sample); /* Print diagnostics sample */
static void usage(); /* Print 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;
/* Parse command-line parameters. */
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);
}
canHandle hnd;
/* We open the channel with the EXCLUSIVE flag to not let any other
* application interfere with the diagnostics channel */
canStatus stat;
/* Attach an analyzer to an open CAN channel. */
check("kvDiagAttachAnalyzer", stat);
/* We want to run DIAG_PROGRAM_TYPE_NORMAL. It needs a JSON configuration
* specifying bus parameters. */
stat = kvDiagSetProgram(hnd, DIAG_PROGRAM_TYPE_NORMAL, CONF_500KBIT);
check("kvDiagSetProgram", stat);
/* Start the analyzer. */
stat = kvDiagStart(hnd);
check("kvDiagStart", stat);
/* Continuously read samples and print until Ctrl-C is pressed. */
signal(SIGINT, intHandler);
kvDiagSample sample;
while (1) {
/* Wait at most 100 ms for a new sample. */
stat = kvDiagReadSampleWait(hnd, &sample, 100);
if (stat == canOK) {
printSample(&sample);
}
/* Check Ctrl-C. */
if (interrupt) {
break;
}
}
/* Stop the analyzer. */
stat = kvDiagStop(hnd);
check("kvDiagStop", stat);
/* Detach the analyzer, since we're not going to restart it. */
stat = kvDiagDetachAnalyzer(hnd);
check("kvDiagDetachAnalyzer", stat);
/* Close the CAN channel. */
stat = canClose(hnd);
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 printEdges(kvDiagSample *sample)
{
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");
}
static void printSample(kvDiagSample *sample)
{
int i;
printf("CAN ID: 0x%x SEQ: %u. DLC: %u, flags: 0x%x, data:",
sample->msg.id,
sample->header.seqno,
sample->msg.dlc,
sample->msg.flag);
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");
}