As far as i know,the demo code “demo_2_motors” of blmc_drivers is a demo to control motor track the slide pos using PD.
If i hold the motor to make it can’t spin when “demo_2_motors” running, soon i will receive an error which error code=2( 2 means can recv timeout).
Is this normal or abnormal?
I also try another demo “demo_sine_position_1_motor”,got same error again,here is the test video:
hold the motor the can timeout error occur
There is another situation i observed when i try debugging “udriver_firmware” ,the computer use “demo_sine_position_1_motor” to send CAN messages.
I add a breakpoint at the line of setCanStatusMsg function:
status.bit.error_code = CAN_ERROR_CAN_RECV_TIMEOUT;//this line is where the breakpoint added
It quickly receive a CAN receive time error soon after the motor start to spin.
I have no time to hold the motor,because it fail too quickly.
The CCS doesn’t jump to the code line i add breakpoint to,seems it is not that line to set the CAN timeout flag.
I search the whole project,there is no other place to set timeout flag if using can communication.
Now i have installed PREEMPT_RT kernel,the CAN timeout error still occurs using “demo_sine_position_1_motor” for test.
I have set the timeout params using below code:
auto board = std::make_shared<blmc_drivers::CanBusMotorBoard>(can_bus,1000,1000);
But the problem still hanppens.
Does anybody can give me advices?
I have spent 3 days to find out why so easy timeout.
Finally i found that the CanBus::send_frame()function calls “sendto” API to send the can frame,
the “sendto” API blocks when sending will cause the timeout problem.
Does anybody meet the same problems?
I never used breakpoints in CCS, so unfortunately I don’t know why it is not triggered (I think this is indeed the correct line).
Just to make sure: After installing the PREEMPT_RT kernel, it is important to do a clean rebuild (i.e. delete the old “install” and “build” directories first) with the PREEMPT_RT kernel running. Did you do this? This is needed because real-time threads are only used by our software if the rt-kernel is detected at build-time.
I am so sure the PREEMPT_RT kernel is running and the project is rebuild.
I modified the source code of blmc_driver:
- using non-blocking mode to send can data.
- if data is not sent completely, keep trying for some thimes.
- drop the can frame if not successful sent after certain try.
- report a send fail.
This is what i often do when i develop game server.
After those modification,the can timeout error reduces ,but still happens sometimes,i will keep test to find a best way to fix that.
Can communication is a little different from network communication .
In normal network communication, if i detect a sent fail,it ok to close the connection and do reconnection.
But in CAN communication ,i don’t know what will happen if not the whole CAN frame is sent.
I know little about TI Board F28069M, it seems the CAN data is automatically received and put in to mailboxs.
Hm, this sounds like it is not a timing problem but rather some frames are not transmitted correctly. Maybe some problem with the cables?
You could try to monitor the CAN bus with candump
(from the can-utils
package) to check if there are any errors. E.g. to show all frames and errors of can0:
candump -e can0
I’m also not a real expert regarding CAN. If I recall correctly, the process of sending works like this:
The sender writes the frame to the bus. At the end, there is an acknowledge bit, which is not set by the sender but by the receiver. So if the receiver read the frame successfully, it sets the acknowledge bit, which is then detected by the sender.
I think if the frame is not acknowledged, the sender may try to send it again. However, I’m not sure if this is a standard behaviour or if it might depend on the CAN controller that is used.