The code in Windows works fine.
The reader could be allerted by the event.
--------------------
I see nothing like this in Linux.
--------------------
The workaround could be to set file to blocking mode and use separate thread. Is there any chance to switch blocking mode? It seems to me that NON_BLOCKING mode is hardcoded in the library.
Is there any mutex inside PcanBASIC in Linux?
-
- Software Development
- Posts: 305
- Joined: Mon 9. Sep 2013, 12:21
Re: Is there any mutex inside PcanBASIC in Linux?
Dear Fojtik,
Can you explain what is your issue exactly?
You can find 2 C++ examples (in the PCAN-Basic linux package) which use events: "pcaneventwrite" and "pcaneventread".
Can you explain what is your issue exactly?
What code are you refering to?The code in Windows works fine.
The reader could be allerted by the event.
You can find 2 C++ examples (in the PCAN-Basic linux package) which use events: "pcaneventwrite" and "pcaneventread".
Indeed the linux API opens the CAN file descriptors in non blocking mode to have the same behaviour as in the Windows version.The workaround could be to set file to blocking mode and use separate thread. Is there any chance to switch blocking mode? It seems to me that NON_BLOCKING mode is hardcoded in the library.
Best regards,
Fabrice
Fabrice
Re: Is there any mutex inside PcanBASIC in Linux?
I has been downloaded this package: PCAN-Basic_Linux-4.3.2.tar.gzF.Vergnaud wrote:Dear Fojtik, Can you explain what is your issue exactly?
There are examples "pcanread.cpp" and "pcanwrite.cpp". They are using "PCANBasic.h" and I see here no mean how to switch into blocking mode and wake up immediatelly after message has been received.
The good workaround is to force blocking mode, but I cannot find any API call for this task.
------------
This kind of function would also satisfy me, but it is not accessible from "PCANBasic.h" and also is marked as obsolette:
DWORD LINUX_CAN_ReadFD_Timeout(HANDLE hHandle, TPCANMsgFD *pMsgBuff, int nMicroSeconds);
Also it only supports CAN FD.
I do not understand how this example works. There is something like event, but it seems to me that classical pooling is still used ror reading. So such pseudo"event" does not help.F.Vergnaud wrote:"pcaneventread"
-
- Software Development
- Posts: 305
- Joined: Mon 9. Sep 2013, 12:21
Re: Is there any mutex inside PcanBASIC in Linux?
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:
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
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
- 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
Best regards,
Fabrice
Fabrice
Re: Is there any mutex inside PcanBASIC in Linux?
Thank you very much for hint. It seems to work as expected.
There is only one flaw inside your demo (fix included in this fragment):
Without timeout the program cannot be correctly finished. 1s timeout could pool exit flag.
There could be some fix inside PCanBASIC library that force to close device handle even when select is active.
There is only one flaw inside your demo (fix included in this fragment):
Code: Select all
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int err = select(fd+1, &fds, NULL, NULL, &timeout);
if(err!=0) // Timeout ocurred -> err==0.
{
if(err!=1 || !FD_ISSET(fd, &fds))
{
fprintf(stderr, "\n%u Select(%xh) failure: %d.", GetTickCount_ms(), myObj->m_Channel, err);
uleep(1000); // Relax from error.
continue;
}
}
TPCANStatus stsResult = CAN_Read(myObj->m_Channel, &PeakCanMsg, NULL);
There could be some fix inside PCanBASIC library that force to close device handle even when select is active.