devctl()

Perform CAN_DEVCTL_* commands

Synopsis

#include <errno.h>
#include <hw/libcan.h>
#include <sys/can_dcmd.h>
#include <sys/iomsg.h>

int devctl( CANDEV *cdev,
            io_devctl_t *msg );

Arguments

cdev

A pointer to the structure corresponding to the device that should perform the command.

msg

A structure containing the command to be performed and any associated arguments.

Description

The devctl() function inspects msg->i.dcmd to determine how to handle the requested command. It then either performs the command and returns data if appropriate or lets libcan handle it, where one of the following occurs:

  • Returns EOK to indicate that the command was completed successfully and doesn't sent back any data.
  • Writes content into the buffer defined by _IO_OUTPUT_PAYLOAD(msg), returns the number of bytes to indicate that command was completed successfully, and passes the data back to the client.
  • Returns a value less than 0 and sets errno to ENOTSUP to allow libcan to handle the command. The libcan resource manager then returns CAN frame data if available, blocks until the frame is available, or transmits the CAN frame.
  • Returns a value less than 0 and sets errno to a value other than ENOSTUP to specify an error.

The libcan library only implements default handling for the following commands:

  • CAN_DEVCTL_READ_CANMSG_EXT
  • CAN_DEVCTL_RX_FRAME_RAW_NOBLOCK
  • CAN_DEVCTL_RX_FRAME_RAW_BLOCK; then, one of the following occurs:
    • Returns the next message from the cdev->msg_queue, if available.
    • Returns EGAIN if using non-blocking IO, the command is CAN_DEVCTL_RX_FRAME_RAW_NOBLOCK, or too many clients are already blocked.
    • Blocks and waits for the message to become available.
  • CAN_DEVCTL_WRITE_CANMSG_EXT
  • CAN_DEVCTL_TX_FRAME_RAW
    • Inserts a message to be transmitted to cdev->msg_queue and calls the transmit() callback.

For all other commands, the default implementation returns ENOTTY.

Returns

  • 0 on success without any response data.
  • >0 number of bytes in the successful reply.
  • <0 on error, with errno set.

Errors

ENOTSUP

Indicates that the command is not implemented and libcan should handle it using either the default function or by passing through the error.

Other error values to be passed to the resource manager.

Example

int my_devctl(CANDEV *cdev, io_devctl_t *msg)
{
  my_device_t *mydev = get_my_device(cdev);
  CAN_DCMD_DATA * can_dcmd_data = _IO_INPUT_PAYLOAD(msg);
  switch(msg->i.dcmd) {
    case CAN_DEVCTL_GET_MID:
      can_dcmd_data->mid = dev->mid & (mydev->extended ? 0x1FFFFFFF : 0x7FF);
      return sizeof(can_dcmd_data->mid);
    case CAN_DEVCTL_SET_MID:
      dev->mid = can_dcmd_data->mid & (mydev->extended ? 0x1FFFFFFF : 0x7FF);
      return 0;
    ...
    }
    errno = ENOTSUP;
    return -1;
}
Page updated: