Once again the API is using non-blocking mechanisms by default to behave as the Windows version.
If you are developping a linux-only application, you can choose to use directly libpcanfd and open the file descriptor without the non-blocking flag (PCAN-Basic linux is built on top of that library).
Nevertheless, I would recommend to use PCAN-Basic API with PCAN_RECEIVE_EVENT parameter: it allows you to retrieve the File Descriptor of the initialized channel, then use the select function on it. Select will block until an event occurs on the file descriptor (much like WaitForSingleObject on Windows), it is quite different than a polling method.
As on Windows, after an event notification you have to read the messages from the channel.
Here is the "pcaneventread" code with more comments:
Code: Select all
// retrieves the File Descriptor
int fd;
Status = CAN_GetValue(pcan_device, PCAN_RECEIVE_EVENT, &fd, sizeof fd);
fd_set fds;
// initializes an fd_set with that File Descriptor, it will be used to get "read" notifications
FD_ZERO(&fds);
FD_SET(fd, &fds);
// the example uses a forever loop because it only reads messages
while (1) {
// blocks on read descriptor:
// - fds is used to request "read" event,
// - 3rd and 4th parameters are respectively "write" and "exceptional" events,
// - last argument defines no timeout.
int err = select(fd+1, &fds, NULL, NULL, NULL);
// check the return status to see what caused the exit of the function
if (err != 1 || !FD_ISSET(fd, &fds)) {
printf("select(%xh) failure: %d\n", pcan_device, err);
break;
}
// select exited because of a read notification: fetch the message
TPCANMsg Message;
Status = CAN_Read(pcan_device, &Message, NULL);
...
// once we've read all the available messages, loop again to wait for new messages
You can find more information on select on its man page:
- int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
-
http://man7.org/linux/man-pages/man2/select.2.html