@CHIP-RTOS C Library V2.06 - CAN API
CAN_Send
Queue a CAN message for transmission. int CAN_Send ( unsigned int port_idx, unsigned int channel,
const CAN_MSG far *msg ); Parameters
port_idx
- CAN port specifier:
CAN0_PORT = 0, or CAN1_PORT = 1
channel
- Transmit register specifier:
CAN_TX1 = 0
CAN_TX2 = 1
CAN_TX3 = 2
or when operating in
CAN_TX_PRIORITY_QUEUES
mode:
CAN_TX_NORMAL = 0
CAN_TX_HIGH = 1
(2 works same as CAN_TX_HIGH here)
msg
- Pointer to a
CAN_MSG
data structure holding contents of CAN message to be
transmitted, set by caller.
Return Value
- Error code -
CAN_EC_SUCCESS = 0: Success, message has been
transferred into specified transmit queue.
CAN_EC_INVALID_PARAMS = -1: port_idx,
filter_idx invalid
or NULL msg pointer.
CAN_EC_PORT_NOT_OPENED = -3: Port has not been
opened.
CAN_EC_NO_BUF_SPACE = -5: Transmit queue for this
output channel is full, message not accepted.
Comments
- Three different modes of operation are available for the CAN
transmission, selected at the
CAN_Open_Port API call:
- Default mode
This mode uses three transmit software FIFO queues, where each FIFO
feeds a specific hardware transmit register. The size of
each FIFO is configurable.
- CAN_TX_PRIORITY_QUEUES Mode
This mode is selected by setting the CAN_TX_PRIORITY_QUEUES
bit in the CAN_CONFIG
structure's Mode word.
In this mode two transmit FIFO's are used, one with normal
priority and one with high priority. The size of the
normal priority queue is specified by the
Tx_Q_Size[CAN_TX_NORMAL] value in the
CAN_PORT_INIT
structure at the CAN_Open_Port call.
The high priority queue size is specified here with the
Tx_Q_Size[CAN_TX_HIGH] value.
- CAN_TXQ1_DRIVES_ALL Mode
This mode is selected by setting the CAN_TXQ1_DRIVES_ALL
bit in the CAN_CONFIG
structure's Mode word.
In this mode, a single queue feeds more than one of the
hardware transmit registers. If a queue size of zero
is specified for channels CAN_TX2 and
CAN_TX3, then the respective hardware transmit
registers will be fed from the common FIFO. If both
the Tx_Q_Size[CAN_TX2] and Tx_Q_Size[CAN_TX3]
values in the
CAN_PORT_INIT
structure are zero when CAN_Open_Port
is called, then the single FIFO whose size was specified by
Tx_Q_Size[CAN_TX1] drives all three hardware
transmit channels.
Comments General to All Operation Modes
The CAN_Send() function either places the provided
CAN message directly into the hardware register when there is no
message currently pending output already in this register, or into
the software ring buffer queue.
When no more space is available in the output queue, an error code
CAN_EC_NO_BUF_SPACE is returned and no operation is
performed.
The driver feeds the output queues into the hardware transmit
registers in an interrupt driven fashion. The hardware
prioritizes the three transmit registers based on "first recessive
bit" logic, similar to that used for normal CAN bus arbitration.
However in this case, the "arbitration" is performed internally prior
to presentation of the outgoing CAN message on the bus.
This priorization mechanism can lead to transmission which is not done
in FIFO order for the operational modes which drive more than one
hardware transmit register from a single FIFO.
Inside this API the interrupts are masked for a short period and then
re-enabled. This function is reentrant.
Comments on Default Mode
The CAN driver provides three queues for outgoing CAN messages.
Each queue is fed into one of the three hardware transmit registers
provided by the CAN device.
The output queues can be loaded with this API prior to
enabling the respective hardware transmit register. In this
case no output from this channel will occur until the channel
is enabled with the appropriate channel enable command to the
CAN_Control() function.
Comments on CAN_TX_PRIORITY_QUEUES Mode
The CAN_TX_PRIORITY_QUEUES
option bit in the
CAN_CONFIG
Mode word selects this mode. CAN messages from the
CAN_TX_NORMAL queue
will only be loaded into the CAN hardware transmit registers
when the CAN_TX_HIGH queue is empty. The
CAN messages in the CAN_TX_HIGH queue are higher
priority and will be loaded before those in the
CAN_TX_NORMAL queue.
When using this CAN_Send() API, the channel
parameter is used to specify either the normal (CAN_TX_NORMAL)
or high (CAN_TX_HIGH) priority queues.
Note that when this API is called with channel set to
CAN_TX_HIGH, any CAN messages from the
CAN_TX_NORMAL queue which have already been
loaded into the hardware registers will remain there.
Consequently, it can happen that pending CAN
messages from the CAN_TX_NORMAL queue that have
already been loaded into one of the three hardware transmit
registers may
be transmitted after calling this API with a
CAN_TX_HIGH message and before this
higher priority message is loaded into the transmit
registers by the CAN driver. The new high priority
message will only be loaded when one of the three
transmit registers becomes available (empty).
Once loaded into the hardware register, the CAN message
recessive bit prioritization logic is used by hardware to select among
the three transmit registers. This too may lead to
messages from the normal priority queue being
transmitted ahead of a high priority CAN message, if the high
priority queue's
message does not have a high priority CAN message ID (low number).
For applications where this behavior is not tolerable, you might consider
disabling all but one of the transmit registers. However, this
may lead to performance problems so should be avoided when possible.
The queues will drain through what ever transmit registers
have been enabled.
Comments on CAN_TXQ1_DRIVES_ALL Mode
This mode is selected by setting the CAN_TXQ1_DRIVES_ALL
option bit in the
CAN_CONFIG
Mode word. (The CAN_TX_PRIORITY_QUEUES
bit must be zero.) In this mode the hardware transmit registers
CAN_TX2 and/or CAN_TX3 can be driven
from the CAN_TX1 FIFO by specifying zero
sizes for
the CAN_TX2 and/or CAN_TX3 software
FIFO's.
Example #1:
CAN_PORT_INIT init ;
init.Config.Mode = CAN_TXQ1_DRIVES_ALL ;
init.Tx_Q_Size[CAN_TX1] = 20 ;
init.Tx_Q_Size[CAN_TX2] = 5 ;
init.Tx_Q_Size[CAN_TX3] = 0 ;
These settings would cause TX1 and TX3 hardware transmit
registers to both be driven from the 20 message
CAN_TX1 FIFO. The TX2 hardware transmit
register is connected to its private 5 message queue.
Example #2:
CAN_PORT_INIT init ;
init.Config.Mode = CAN_TXQ1_DRIVES_ALL ;
init.Tx_Q_Size[CAN_TX1] = 20 ;
init.Tx_Q_Size[CAN_TX2] = 0 ;
init.Tx_Q_Size[CAN_TX3] = 0 ;
These settings would cause all three hardware
transmit registers to be filled from the 20 message
CAN_TX1 FIFO.
When the CAN_TXQ1_DRIVES_ALL option is used
to drive more than one hardware transmit register from the first
software transmit FIFO, the CAN transmissions may not necessarily
come out in FIFO order. This is due to the CAN bus
arbitration based on CAN label performed within the CAN port
device's set of transmit registers. A typical scenerio
would be that the CAN driver software
takes three CAN messages from the send FIFO and places these into
the three hardware transmit registers. Then the hardware transmit
arbitration logic selects the CAN message among these three
with the lowest CAN ID for transmission.
When the CAN_TXQ1_DRIVES_ALL option is used to
drive CAN_TX2 and CAN_TX3 transmit
registers, calling this CAN_Send() API with the
channel argument set to either
CAN_TX2 or CAN_TX3 performs nearly
the same operation as CAN_TX1. In the case
where the provided CAN message is placed in the single send FIFO,
the functionality is identical. When the FIFO and specified
transmit register are empty, there is a slight difference.
In this case the channel argument specifies
which hardware transmit registers is loaded.
See Also
RTOS API
- This library function uses a
dynamic
link to reach the service
offered by RTOS software
interrupt.
Supported since or modified in @CHIP-RTOS version-
SC12 | SC13 | SC11 | SC1x3 |
-
n/a | n/a | n/a | V1.07 |
Supported by @CHIP-RTOS C Library since version
This API List
List of C Libraries
@CHIP-RTOS Main Index
End of document
|