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 vianetdev_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 callingnetdev_register().Include/nuttx/net/can.h. contains lookup tables for CAN dlc to CAN FD len sizes namedextern const uint8_t g_can_dlc_to_len[16]; extern const uint8_t g_len_to_can_dlc[65];Initialization sequence is as follows.
xxx_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)functioninclude/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 ofnet_driver_s.d_lenwhether it matches the size of astruct can_frameorstruct canfd_framethen you cast the content of thenet_driver_s.d_bufpointer to the correct CAN frame struct