There are a few code examples for C in the pcanbasic api package.
ReadEvent, WriteEvent. But I'm missing the ReadWriteEvent example.
I patched the examples together. The added code is not tested. But I have tested a similar code earlier with none working result.
The question is,, Is this the correct approach?
If not,, What is the correct approach?
The Idea is to send a message every 100mS and else receive messages.
Or should I run one thread with ReadEvent and one thread with WriteEvent?
I'm using Ubuntu 20.04.1 LTS 64 Bit
PeakBasic API 4.4.0
Peak-linux-driver-8.10.2
PcanDevice IPEH-004064
Regards
Terje.
Here is the code..
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <asm/types.h>
#include <unistd.h>
#define PCAN_DEVICE PCAN_USBBUS1
#include "PCANBasic.h"
static int SendInterrupt=0; //Set to 1 by an timer every 100mS.
static struct sigaction oldact;
static void signal_handler(int s)
{
printf("Interrupted by SIG%u!\n", s);
}
static int setup_sig_handler(int signum, void (*f)(int))
{
struct sigaction act;
memset(&act, 0, sizeof act);
act.sa_handler = f;
// note: siagaction() is thread -safe
return sigaction(signum, &act, &oldact);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary> Main entry-point for this application. </summary>
///
/// <remarks> </remarks>
///
/// <param name="argc"> The argc. </param>
/// <param name="argv"> [in,out] If non-null, the argv. </param>
///
/// <returns> . </returns>
////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
TPCANStatus Status;
unsigned int rx_count = 0;
unsigned int tx_count = 0;
unsigned int pcan_device = PCAN_DEVICE;
// be INTRuptible by user
setup_sig_handler(SIGINT, signal_handler);
Status = CAN_Initialize(pcan_device, PCAN_BAUD_500K, 0, 0, 0);
printf("CAN_Initialize(%xh): Status=0x%x\n", pcan_device, (int)Status);
if (Status)
goto lbl_exit;
int fd;
Status = CAN_GetValue(pcan_device, PCAN_RECEIVE_EVENT, &fd, sizeof fd);
printf("CAN_GetValue(%xh): Status=0x%x\n", pcan_device, (int)Status);
if (Status)
goto lbl_close;
fd_set fdsIn;
fd_set fdsOut;
FD_ZERO(&fdsIn);
FD_SET(fd, &fdsIn);
FD_ZERO(&fdsOut);
FD_SET(fd, &fdsOut);
TPCANMsg MessageRx,MessageTx;
MessageTx.ID = 0x77;
MessageTx.LEN = 8;
MessageTx.MSGTYPE = PCAN_MESSAGE_STANDARD;
memset(MessageTx.DATA, '\0', sizeof(MessageTx.DATA));
// forever loop
while (1) {
// blocks on read descriptor
int err = select(fd+1, &fdsIn, &fdsOut, NULL, NULL);
if (err != 1 || !FD_ISSET(fd, &fdsIn)) {
printf("select(%xh) failure: %d\n", pcan_device, err);
break;
}
if(SendInterrupt == 1)
{
SendInterrupt = 0; // Clear timer flag.
Status = CAN_Write(pcan_device, &MessageTx);
if (Status != PCAN_ERROR_OK) {
printf("CAN_Write(%xh) failure 0x%x\n", pcan_device, (int) Status);
break;
}
// increment data bytes
for (int i = 0; i < 8; i++)
if (++MessageTx.DATA[i])
break;
tx_count++;
printf(" - S ID:%4x LEN:%1x DATA:%02x %02x %02x %02x %02x %02x %02x %02x\n",
(int) MessageTx.ID, (int) MessageTx.LEN, (int) MessageTx.DATA[0],
(int) MessageTx.DATA[1], (int) MessageTx.DATA[2],
(int) MessageTx.DATA[3], (int) MessageTx.DATA[4],
(int) MessageTx.DATA[5], (int) MessageTx.DATA[6],
(int) MessageTx.DATA[7]);
}
Status = CAN_Read(pcan_device, &MessageRx, NULL);
if (Status == PCAN_ERROR_QRCVEMPTY) {
printf("CAN_Read(%xh) Abnormal PCAN_ERROR_QRCVEMPTY status. Wating 1s before looping (^C to stop)...\n", pcan_device);
if (usleep(1000000))
break;
continue;
}
if (Status != PCAN_ERROR_OK) {
printf("CAN_Read(%xh) failure 0x%x\n", pcan_device, (int) Status);
break;
}
rx_count++;
printf(" - R ID:%4x LEN:%1x DATA:%02x %02x %02x %02x %02x %02x %02x %02x\n",
(int) MessageRx.ID, (int) MessageRx.LEN, (int) MessageRx.DATA[0],
(int) MessageRx.DATA[1], (int) MessageRx.DATA[2],
(int) MessageRx.DATA[3], (int) MessageRx.DATA[4],
(int) MessageRx.DATA[5], (int) MessageRx.DATA[6],
(int) MessageRx.DATA[7]);
}
printf("pcaneventread(%xh): received %u message(s)\n", pcan_device, rx_count);
printf("pcaneventwrite(%xh): sent %u message(s)\n", pcan_device, tx_count);
lbl_close:
CAN_Uninitialize(pcan_device);
lbl_exit:
return 0;
}