CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

How to determine if there are nodes on CAN bus?!

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
stoyanoff



Joined: 20 Jul 2011
Posts: 375

View user's profile Send private message

How to determine if there are nodes on CAN bus?!
PostPosted: Wed Aug 05, 2015 10:29 am     Reply with quote

Greetings! I have a CAN bus line created with MCP2515 and SN65HVD230D. If there are no nodes on the line and I try to send a lot of data, my CAN bus blocks. It seems I fouled the buffer. How can I avoid this?!
Thanks!
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Wed Aug 05, 2015 2:11 pm     Reply with quote

You need to start by testing modbus_rx.error after each read/write.
stoyanoff



Joined: 20 Jul 2011
Posts: 375

View user's profile Send private message

PostPosted: Wed Aug 05, 2015 11:25 pm     Reply with quote

You mean to read the MCP2515 error register?!
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Thu Aug 06, 2015 1:22 am     Reply with quote

Yes. Sorry to say Modbus was doing some work on this at the same time...

Problem is that if a packet is sent, and not acknowledged, the driver will automatically send an error frame and re-send. 'Last_error_register' will contain 'ACK error' (010). After 127 retries the bus will go to the error state. If this happens on a master, you have the indication that there is 'nobody home'.....
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Aug 06, 2015 2:51 am     Reply with quote

Ttelmah wrote:
You need to start by testing &%*%_rx.error after each read/write.


Note: the CAN calls are non-blocking (see below), and messages to be sent are buffered. That means the error will not be set immediately after a write call returns. Best to check it BEFORE trying to send the next message.

Actually write calls will block if the buffers are full, and not return until the new message has been buffered, i.e. an earlier message has successfully been sent. By default there are three buffers, one being sent and two waiting to go out. A node on its own will block on the third write call.

In some situations, you can't actually prevent blocking. The trouble is that the error register is only set after many retries and the transmitter ghas gone to the bus passive or bus off states. That's way too late, you may well already have tried to buffer more messages and become blocked. I've tried several times to get round this, but not really succeeded, mainly through lacking a really effective way of resetting the CAN hardware. You can send out an "Is anyone there?" message, and wait to see if any node acknowledges it, i.e. that after the time the retries would have took, there is no bus error.

If there is a bus error, the flags don't reset themselves immediately the error condition clears. The flags are based on counts - its standard CAN behaviour - and just as they count on, they count off. So to clear a bus passive of bus off indication, you have to sucessfully send many messages.

You also cannot, at least not in CAN itself, tell if a particular node has received a message sent for it. There is no mechanism built into CAN itself that allows addressing, and no means of providing a ponit to point link; all messages are acknowledged by all nodes. There are ways of adding addressing at a higher layer, but its built into the base protocol.
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Thu Aug 06, 2015 3:05 am     Reply with quote

If you read the reply you will see I 'cross answered'.

Yes 127 counts to error, and then 256 to bus off. In error, it'll only accept error packets.
As you say, he should check before sending, then he needs to set his own flag, and if it has reached one of the error states, put up an alert.
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Thu Aug 06, 2015 6:48 am     Reply with quote

RF_Developer wrote:
You also cannot, at least not in CAN itself, tell if a particular node has received a message sent for it. There is no mechanism built into CAN itself that allows addressing, and no means of providing a ponit to point link; all messages are acknowledged by all nodes. There are ways of adding addressing at a higher layer, but its built into the base protocol.


There is a method of doing 'addressed' packets but it must really be done only in the extended addressing mode. Break the 29 bits of the address into bitfields representing sender, recipient, message purpose, message "ID", etc. Of course, as you have said, all nodes will ACK a message even if it's not intended for them but with this sort of mechanism if you have a logging device, at least you can tell who sent what.

The other thing about CAN errors that has to be stated is that a CAN error count of x does NOT necessarily mean that there were actually x errors on the bus. A node simply asserts an open bit time slot in the error packet if it detects an error. So the count increases, effectively, by bits being set, not incremented. Seven bits being set can = error count of 127, or stated another way 7 errors = error count of 127. Our flagship product has a provision for technicians to actually see the CAN error count and it's the worst feature of that damn product because they keep obsessing over the actual number. The parts I've been able to redesign have done away with the count provision and now simply flash an LED if no replies/ACKs are detected. The LEDs now directly correlate to a single cable, which can be quickly found and replaced if they run into trouble. ...Instead of phoning me to wax poetic about how the system is doing funny stuff at an error count of x but yesterday when it was y, and y > x, it didn't.
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Thu Aug 06, 2015 7:11 am     Reply with quote

But (of course), in normal circumstances a master should never see an ACK error. Hence for what he wants (to know a bus is empty or disconnected), the actual 'details' don't terribly matter. Repeated ACK errors -> nothing replying....
stoyanoff



Joined: 20 Jul 2011
Posts: 375

View user's profile Send private message

PostPosted: Mon Sep 14, 2015 6:51 am     Reply with quote

Hi, again! I have another problem with CAN bus! I have to transmit variable length data between nodes. I have buffer with 1500 bytes. So I make an algorithm which separates the buffer to parts of 8 bytes and sends them with 300us delay. The problem is sometimes after sending a few 8 byte parts there are only 2 or 3 bytes left. When I try to send them the can_put() function returns 1, but the receiver never receive them.
If the buffer has only 3 bytes everything is OK. BUT for example if I have 51 bytes in the buffer, the transmitter sends 6x8 bytes and the last 3, but the last 3 are never received by the receiver? If I try to send 54 or more bytes everything is OK. The problem appears only when I have 1, 2 or 3 bytes left to send.
Can you tell me what I'm missing?!
Thanks!
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Sep 14, 2015 9:16 am     Reply with quote

CAN is not great for sending large data sets like this. Really, its intended for situations where each message is self-contained.

There are two main things to think about, both related to the buffering in the CAN hardware. First, there's the rate of sending. Generally, at, say, 125kbps, a CAN message takes around a millisecond to send. So, when you send multiple messages in quick succession, the transmit buffers will fill up. For you, 300us may sound like a long time, but for CAN it's not a lot, and the hardware will still be sending the first message when you try and buffer the second, and so on.

The other problem is that in CAN there's not concept of message ordering, and there's no built-in mechanism for ensuring one message arrives before or after any other message. The way the CAN hardware transmission process works means that buffered messages won't necessarily be sent in the order you buffered them. That means that three messages, 1, 2 & 3, can arrive in the order, 1, 3, 2. That's not a fault, its the way CAN is intended to work.

You can get round this by limiting the number of buffers the driver uses for transmission. You can limit it to just one, but that can lead to considerable blocking in high traffic situations. A better alternative is to limit it to two, simply not using the third buffer. I won't explain how or why that works, but it does.

Another thing to do is to include a sequence number as part of the ID or in the data. Also, of course, you'll have to include the number of bytes in the packet. Again its possible to do this in the ID, but you'd probably find it easier with 29 bit extended IDs. That way, the receiving process would be able to work out what order to reassemble the packets,, and be able to deal with any short packet at the end. I've done this, and it works reasonably well.
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Mon Sep 14, 2015 9:39 am     Reply with quote

RF_Developer had good suggestions and points.

I've had to come up with methods for transferring large text files (error logs) via CAN. An originator generates an error log (ASCII text file) and saves it to an SD card. When safe to do so, it alerts a recipient to the presence of this log file, which then starts an automated transfer/download of the log from originator to a single recipient, where all error logs are aggregated on an SD card for transfer to a technician's PC. This was my approach:

Originator of the error log only sends one packet at a time and doesn't send the next packet until the first is ACKed by the recipient. Reason: this avoids the packet-out-of-order issue and also negates the need for a packet number count as part of the transfer. Your originator sends a "expect transfer" message which the originator ACKs. Originator then knows that the data that will then follow starts at offset/byte number 0. This approach also doesn't dominate/overload the CAN bus and it also ensures that the originator doesn't go too fast for the recipient to handle the incoming data.

As long as there are bytes to transfer, originator sends packets. Any packet with a payload less than 8 bytes signals the end of the transfer. For example if you have 16 bytes total to transfer, they would be sent via two full payload 8 byte messages followed by a zero payload length message to signal to the recipient that the transfer has now ceased. If you had 15 bytes to transfer, that would only require two messages: a length 8 followed by a length 7 message. The length 7 message, since it is less than the possible 8 byte payload of a CAN message signifies the end of the transfer.

The recipient just has to keep a running tally of transfers. Data from the CAN message gets stored at location [(8 * transfer_number) + can data offset]. If the CAN message length was < 8, that's the end of the transfer.

The ACK can be a zero length message or it can be a full echo of the packet. A zero length message is more efficient in terms of bus usage.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group