From 2fb9910b017649c2c64295cb948d56e7403e367d Mon Sep 17 00:00:00 2001 From: Matias N Date: Fri, 14 Aug 2020 17:31:06 -0300 Subject: [PATCH] backport SocketCAN documentation to new docs (PR #1533) --- Documentation/components/index.rst | 1 + Documentation/components/socketcan.rst | 66 ++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 Documentation/components/socketcan.rst diff --git a/Documentation/components/index.rst b/Documentation/components/index.rst index aa3463480e..b2ba8e6ab1 100644 --- a/Documentation/components/index.rst +++ b/Documentation/components/index.rst @@ -10,6 +10,7 @@ OS Components nsh/index.rst power.rst + socketcan.rst syslog.rst binfmt.rst drivers/index.rst diff --git a/Documentation/components/socketcan.rst b/Documentation/components/socketcan.rst new file mode 100644 index 0000000000..f8323a2512 --- /dev/null +++ b/Documentation/components/socketcan.rst @@ -0,0 +1,66 @@ +======================== +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 +