cwalter-at / freemodbus

BSD licensed MODBUS RTU/ASCII and TCP slave
720 stars 379 forks source link

demo/LINUXTCP application using 100% CPU during idle time as well #18

Open samminen opened 4 years ago

samminen commented 4 years ago

Hi, When i test demo/LINUXTCP app, I see service using 100% CPU all the time. Any resolution ?

pvyleta commented 4 years ago

The demo application is really simple, an it is possible that this is a correct behavior of the demo application, as there is infinite while loop calling eMBPoll, see https://github.com/cwalter-at/freemodbus/blob/master/demo/LINUXTCP/demo.c#L185. I have checked the code only briefly however.

Can you please check, if you are able to read the registers of the demo application? Can you try to debug with the debugger to see if the application is not stuck in some infinite loop?

samminen commented 4 years ago

thank you for the quick reply. Using demo/LINUXTCP application, I am able to read/write holding registers and also able to read input registers. Now the problem is with CPU spike to 100% when i perform read/write registers operation.

I did check infinite while loop and I get rid of 2 while loops in main() function using pthread_join(). But I am not sure how to eliminate infinite do { } while () for eMBPoll().

I tried below code but it is crashing when I try to dMBPoll() in a child thread.

  1. without loop, how can we do periodic polling ?
  2. is there a way we can remove eMBPoll() dependency while reading/writing registers ?

Kindly help me to resolve this issue.


Files attached for reference.

modbusslave.zip

pvyleta commented 4 years ago

Hello, I am pretty sure you cannot remove the eMBPoll() periodic call, but you can definitely play around with putting it in a separate thread, and blocking it until new data arrives. This would require you to play a bit with xMBPortTCPPool, see https://github.com/cwalter-at/freemodbus/blob/master/demo/LINUXTCP/port/porttcp.c#L180 Unfortunately I am not familiar with the Linux port and I cannot really advise you on how to do that. You would have to understand the calls to select() and possibly alter some of its parameters, or maybe rewrite the function completely.

However, I am curious as how you obtained the 100% processor use. Are you performing some cyclic reading of the register? Or you perform ony one read and after that there is 100% use forever, even without any subsequent read/write opperations? Or does the app take 100% processor even before you start the slave?

samminen commented 4 years ago

Thank you for the update.

When I perform one time read/write operation either holding registers or Input registers ( no cyclic read/write) , it spike CPU usage to 100% and stay for around ~60 sec and come back to 0% usage.

It spike only when read/write operation happen.

pvyleta commented 4 years ago

In this case it very well could be the designed behavior, but as I am not familiar with the Linux demo, I cannot say. Feel free to investigate and suggest a PR in case you figure something out.