Is there any mutex inside PcanBASIC in Linux?

This forum covers PCAN-Linux and Linux development issues concerning our products
Post Reply
Fojtik
Posts: 30
Joined: Thu 8. Feb 2018, 13:06

Is there any mutex inside PcanBASIC in Linux?

Post by Fojtik » Thu 17. Oct 2019, 18:48

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.

F.Vergnaud
Software Development
Software Development
Posts: 305
Joined: Mon 9. Sep 2013, 12:21

Re: Is there any mutex inside PcanBASIC in Linux?

Post by F.Vergnaud » Fri 18. Oct 2019, 09:38

Dear Fojtik,

Can you explain what is your issue exactly?
The code in Windows works fine.
The reader could be allerted by the event.
What code are you refering to?
You can find 2 C++ examples (in the PCAN-Basic linux package) which use events: "pcaneventwrite" and "pcaneventread".
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.
Indeed the linux API opens the CAN file descriptors in non blocking mode to have the same behaviour as in the Windows version.
Best regards,
Fabrice

Fojtik
Posts: 30
Joined: Thu 8. Feb 2018, 13:06

Re: Is there any mutex inside PcanBASIC in Linux?

Post by Fojtik » Fri 18. Oct 2019, 10:52

F.Vergnaud wrote:Dear Fojtik, Can you explain what is your issue exactly?
I has been downloaded this package: PCAN-Basic_Linux-4.3.2.tar.gz

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.

F.Vergnaud wrote:"pcaneventread"
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
Software Development
Software Development
Posts: 305
Joined: Mon 9. Sep 2013, 12:21

Re: Is there any mutex inside PcanBASIC in Linux?

Post by F.Vergnaud » Fri 18. Oct 2019, 11:44

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
Best regards,
Fabrice

Fojtik
Posts: 30
Joined: Thu 8. Feb 2018, 13:06

Re: Is there any mutex inside PcanBASIC in Linux?

Post by Fojtik » Mon 21. Oct 2019, 18:11

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):

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);
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.

Post Reply