⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcan_fops_rt.c

📁 linux下的CAN BUS驱动代码。适合在arm平台使用。
💻 C
📖 第 1 页 / 共 2 页
字号:
    // push a new transmission trough ioctl() only if interrupt triggered push was stalled    mb();    if (atomic_read(&dev->DataSendReady))    {      atomic_set(&dev->DataSendReady, 0);      mb();      rtdm_lock_get_irqsave(&ctx->sja_lock, lockctx);      err = dev->device_write(dev,ctx);      rtdm_lock_put_irqrestore(&ctx->sja_lock, lockctx);      if (err)        atomic_set(&dev->DataSendReady, 1);    }    else    {      // DPRINTK(KERN_DEBUG "%s: pushed %d items into Fifo\n", DEVICE_NAME, dev->writeFifo.nStored);    }  }  fail:  return err;}//----------------------------------------------------------------------------// is called at user ioctl() with cmd = PCAN_GET_EXT_STATUS int pcan_ioctl_extended_status_rt(rtdm_user_info_t *user_info, struct pcanctx_rt *ctx, TPEXTENDEDSTATUS *status){  int err = 0;  struct pcandev *dev;  TPEXTENDEDSTATUS local;  DPRINTK(KERN_DEBUG "%s: pcan_ioctl_rt(PCAN_GET_EXT_STATUS)\n", DEVICE_NAME);  dev = ctx->dev;  local = pcan_ioctl_extended_status_common(dev);  if (copy_to_user_rt(user_info, status, &local, sizeof(local)))  {    err = -EFAULT;    goto fail;  }  dev->wCANStatus = 0;  dev->nLastError = 0;  fail:  return err;}//----------------------------------------------------------------------------// is called at user ioctl() with cmd = PCAN_GET_STATUSint pcan_ioctl_status_rt(rtdm_user_info_t *user_info, struct pcanctx_rt *ctx, TPSTATUS *status){  int err = 0;  struct pcandev *dev;  TPSTATUS local;  DPRINTK(KERN_DEBUG "%s: pcan_ioctl_rt(PCAN_GET_STATUS)\n", DEVICE_NAME);  dev = ctx->dev;  local = pcan_ioctl_status_common(dev);  if (copy_to_user_rt(user_info, status, &local, sizeof(local)))  {    err = -EFAULT;    goto fail;  }  dev->wCANStatus = 0;  dev->nLastError = 0;  fail:  return err;}//----------------------------------------------------------------------------// is called at user ioctl() with cmd = PCAN_DIAG int pcan_ioctl_diag_rt(rtdm_user_info_t *user_info, struct pcanctx_rt *ctx, TPDIAG *diag){  int err = 0;  struct pcandev *dev;  TPDIAG local;  DPRINTK(KERN_DEBUG "%s: pcan_ioctl_rt(PCAN_DIAG)\n", DEVICE_NAME);  dev = ctx->dev;  local = pcan_ioctl_diag_common(dev);  if (copy_to_user_rt(user_info, diag, &local, sizeof(local)))    err = -EFAULT;  return err;}//----------------------------------------------------------------------------// is called at user ioctl() with cmd = PCAN_INITint pcan_ioctl_init_rt(rtdm_user_info_t *user_info, struct pcanctx_rt *ctx, TPCANInit *Init){  int err = 0;  TPCANInit local;  struct pcandev *dev;  rtdm_lockctx_t lockctx;  DPRINTK(KERN_DEBUG "%s: pcan_ioctl_rt(PCAN_INIT)\n", DEVICE_NAME);  dev = ctx->dev;  if (copy_from_user_rt(user_info, &local, Init, sizeof(local)))  {    err = -EFAULT;    goto fail;  }  // flush fifo contents  rtdm_lock_get_irqsave(&ctx->out_lock, lockctx);  err = pcan_fifo_reset(&dev->writeFifo);  rtdm_lock_put_irqrestore(&ctx->out_lock, lockctx);  if (err)    goto fail;  rtdm_lock_get_irqsave(&ctx->in_lock, lockctx);  err = pcan_fifo_reset(&dev->readFifo);  rtdm_lock_put_irqrestore(&ctx->in_lock, lockctx);  if (err)    goto fail;  wait_until_fifo_empty(dev, MAX_WAIT_UNTIL_CLOSE, ctx);  // release the device  dev->device_release(dev);  // init again  err = dev->device_open(dev, local.wBTR0BTR1, local.ucCANMsgType, local.ucListenOnly);  if (!err)  {    dev->wBTR0BTR1    = local.wBTR0BTR1;    dev->ucCANMsgType = local.ucCANMsgType;    dev->ucListenOnly = local.ucListenOnly;  }  fail:  return err;}//----------------------------------------------------------------------------// get BTR0BTR1 init valuesint pcan_ioctl_BTR0BTR1_rt(rtdm_user_info_t *user_info, struct pcanctx_rt *ctx, TPBTR0BTR1 *BTR0BTR1){  int err = 0;  TPBTR0BTR1 local;  DPRINTK(KERN_DEBUG "%s: pcan_ioctl_rt(PCAN_BTR0BTR1)\n", DEVICE_NAME);  if (copy_from_user_rt(user_info, &local, BTR0BTR1, sizeof(local)))  {    err = -EFAULT;    goto fail;  }  // this does not influence hardware settings, only BTR0BTR1 values are calculated  local.wBTR0BTR1 = sja1000_bitrate(local.dwBitRate);  if (!local.wBTR0BTR1)  {    err = -EFAULT;    goto fail;  }  if (copy_to_user_rt(user_info, BTR0BTR1, &local, sizeof(*BTR0BTR1)))    err = -EFAULT;  fail:  return err;}//----------------------------------------------------------------------------// add a message filter_element into the filter chain or delete all filter_elementsint pcan_ioctl_msg_filter_rt(rtdm_user_info_t *user_info, struct pcanctx_rt *ctx, TPMSGFILTER *filter){  TPMSGFILTER local_filter;  struct pcandev *dev;  DPRINTK(KERN_DEBUG "%s: pcan_ioctl_rt(PCAN_MSG_FILTER)\n", DEVICE_NAME);  dev = ctx->dev;  // filter == NULL -> delete the filter_elements in the chain  if (!filter)  {    pcan_delete_filter_all(dev->filter);    return 0;  }  if (copy_from_user_rt(user_info, &local_filter, filter, sizeof(local_filter)))    return -EFAULT;  return pcan_add_filter(dev->filter, local_filter.FromID, local_filter.ToID, local_filter.MSGTYPE);}//----------------------------------------------------------------------------// is called at user ioctl() callint pcan_ioctl_rt(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, IOCTL_REQUEST_TYPE request, void *arg){  int err;  struct pcanctx_rt *ctx;  struct pcandev *dev;  ctx = (struct pcanctx_rt *)context->dev_private;  dev = ctx->dev;  // if the device is plugged out  if (!dev->ucPhysicallyInstalled)    return -ENODEV;  switch(request)  {    case PCAN_READ_MSG:      err = pcan_ioctl_read_rt(user_info, ctx, (TPCANRdMsg *)arg); // support blocking and nonblocking IO      break;    case PCAN_WRITE_MSG:      err = pcan_ioctl_write_rt(user_info, ctx, (TPCANMsg *)arg);  // support blocking and nonblocking IO      break;    case PCAN_GET_EXT_STATUS:      err = pcan_ioctl_extended_status_rt(user_info, ctx, (TPEXTENDEDSTATUS *)arg);     break;    case PCAN_GET_STATUS:      err = pcan_ioctl_status_rt(user_info, ctx, (TPSTATUS *)arg);      break;    case PCAN_DIAG:      err = pcan_ioctl_diag_rt(user_info, ctx, (TPDIAG *)arg);      break;    case PCAN_INIT:       err = pcan_ioctl_init_rt(user_info, ctx, (TPCANInit *)arg);      break;    case PCAN_BTR0BTR1:      err = pcan_ioctl_BTR0BTR1_rt(user_info, ctx, (TPBTR0BTR1 *)arg);      break;    case PCAN_MSG_FILTER:      err = pcan_ioctl_msg_filter_rt(user_info, ctx, (TPMSGFILTER *)arg);      break;    default:      DPRINTK(KERN_DEBUG "%s: pcan_ioctl_rt(%d)\n", DEVICE_NAME, request);      err = -ENOTTY;      break;  }  DPRINTK(KERN_DEBUG "%s: pcan_ioctl()_rt = %d\n", DEVICE_NAME, err);  return err;}//****************************************************************************// GLOBALS//----------------------------------------------------------------------------// this structure is used in init_module(void)struct rtdm_device pcandev_rt ={  struct_version:     RTDM_DEVICE_STRUCT_VER,  device_flags:       RTDM_NAMED_DEVICE,  context_size:       sizeof(struct pcanctx_rt),  device_name:        "",  open_rt:            NULL,  open_nrt:           pcan_open_rt,  ops: {    close_rt:         NULL,    close_nrt:        pcan_close_rt,    ioctl_rt:         pcan_ioctl_rt,    ioctl_nrt:        pcan_ioctl_rt,    read_rt:          NULL,    read_nrt:         NULL,    write_rt:         NULL,    write_nrt:        NULL,    recvmsg_rt:       NULL,    recvmsg_nrt:      NULL,    sendmsg_rt:       NULL,    sendmsg_nrt:      NULL,  },  device_class:       RTDM_CLASS_CAN,  driver_name:        "pcan_driver",  provider_name:      "PEAK System-Technik GmbH",  proc_name:          pcandev_rt.device_name,};// end of file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -