nuttx/Documentation/components/socketcan.rst

67 lines
2.6 KiB
ReStructuredText
Raw Normal View History

========================
SocketCAN Device Drivers
========================
- **``include/nuttx/net/netdev.h``**. All structures and APIs
needed to work with drivers are provided in this header file.
The structure struct net_driver_s defines the interface and is
passed to the network via netdev_register().
- **``include/nuttx/can.h``**. CAN & CAN FD frame data
structures.
- **``int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype)'``**.
Each driver registers itself by calling netdev_register().
- **``Include/nuttx/net/can.h``**. contains lookup tables for CAN
dlc to CAN FD len sizes named
.. code-block:: c
extern const uint8_t can_dlc_to_len[16];
extern const uint8_t len_to_can_dlc[65];
- **Initialization sequence is as follows**.
#. up_netinitialize(void) is called on startup of NuttX in this
function you call your own init function to initialize your
CAN driver
#. In your own init function you create the net_driver_s
structure set required init values and register the required
callbacks for SocketCAN
#. Then you ensure that the CAN interface is in down mode
(usually done by calling the d_ifdown function)
#. Register the net_driver_s using netdev_register
- **Receive sequence is as follows**.
#. Device generates interrupt
#. Process this interrupt in your interrupt handler
#. When a new CAN frame has been received you process this
frame
#. When the CAN frame is a normal CAN frame you allocate the
can_frame struct, when it's a CAN FD frame you allocate a
canfd_frame struct (note you can of course preallocate and
just use the pointer).
#. Copy the frame from the driver to the struct you've
allocated in the previous step.
#. Point the net_driver_s d_buf pointer to the allocated
can_frame
#. Call the ``can_input(FAR struct net_driver_s *dev)``
function ``include/nuttx/net/can.h``
- **Transmit sequence is as follows**.
#. Socket layer executes d_txavail callback
#. An example of the txavail function can be found in
``arch/arm/src/s32k1xx/s32k1xx_flexcan.c``
#. An example of the txpoll function can be found in
``arch/arm/src/s32k1xx/s32k1xx_flexcan.c``
#. In your ``transmit(struct driver_s *priv)`` function you
check the length of ``net_driver_s.d_len`` whether it
matches the size of a ``struct can_frame`` or
``struct canfd_frame`` then you cast the content of the
``net_driver_s.d_buf`` pointer to the correct CAN frame
struct