将SJA1000注册到RTDM实时驱动模型中 --WT

要将一个具体的can 控制器注册到xenomai 中的RTDM实时驱动模型中,一般分为两个部分:第一,将具体的CAN控制器注册到RTCAN模块中。第二,将注册的具体的RTCAN设备注册到 RTDM之中。

1、 SJA1000设备注册到RTCAN 中

adv_pci_init_one->rtcan_adv_pci_add_chan->rtcan_sja1000_register()->rtcan_dev_register()

在上一篇文章" Advantech PCI card 驱动注册 --W T "中介绍到注册完PCI设备后 ,若需要使用xenomai下实时系统,则应向xenomai的子系统RTDM 实时驱动模型注册一个RTDM设备,在这里选用SJA1000:
rtcan_pci_adv.c
adv_pci_init_one()启用 PCI 设备,请求适当的配置空间的"BAR"区域

static int adv_pci_init_one(struct pci_dev *pdev,
			    const struct pci_device_id *ent)
{
   
	int ret, channel;
	unsigned int nb_ports = 0;
	unsigned int bar = 0;
	unsigned int bar_flag = 0;
	unsigned int offset = 0;
	unsigned int ix;

	struct rtcan_device *master_dev = NULL;

	dev_info(&pdev->dev, "RTCAN Registering card");

	ret = pci_enable_device(pdev);
	if (ret)
		goto failure;

	dev_info(&pdev->dev, "RTCAN detected Advantech PCI card at slot RTCAN在插槽中检测到Advantech PCI卡  #%i\n",
		 PCI_SLOT(pdev->devfn));

	ret = pci_request_regions(pdev, RTCAN_DRV_NAME);
	if (ret)
		goto failure_device;

	switch (pdev->device) {
   
	case 0xc001:
	case 0xc002:
	case 0xc004:
	case 0xc101:
	case 0xc102:
	case 0xc104:
		nb_ports = pdev->device & 0x7;
		offset = 0x100;
		bar = 0;
		break;
	case 0x1680:
	case 0x2052:
		nb_ports = 2;
		bar = 2;
		bar_flag = 1;
		break;
	case 0x1681:
		nb_ports = 1;
		bar = 2;
		bar_flag = 1;
		break;
	default:
		goto failure_regions;
	}

	if (nb_ports > 1)
		channel = CHANNEL_MASTER;
	else
		channel = CHANNEL_SINGLE;

	RTCAN_DBG("%s: Initializing device %04x:%04x:%04x\n",
		   RTCAN_DRV_NAME,
		   pdev->vendor,
		   pdev->device,
		   pdev->subsystem_device);

	ret = rtcan_adv_pci_add_chan(pdev, channel, bar, offset, &master_dev);
	if (ret)
		goto failure_iounmap;

	/* register slave channel, if any */

	for (ix = 1; ix < nb_ports; ix++) {
   
		ret = rtcan_adv_pci_add_chan(pdev,
					     CHANNEL_SLAVE,
					     bar + (bar_flag ? ix : 0),
					     offset * ix,
					     &master_dev);
		if (ret)
			goto failure_iounmap;
	}

	pci_set_drvdata(pdev, master_dev);

	return 0;

failure_iounmap:
	if (master_dev)
		rtcan_adv_pci_del_chan(pdev, master_dev);

failure_regions:
	pci_release_regions(pdev);

failure_device:
	pci_disable_device(pdev);

failure:
	return ret;
}

其中
语句ret = rtcan_adv_pci_add_chan(pdev, channel, bar, offset, &master_dev);
添加设备:rtcan_adv_pci_add_chan()在这个函数中完成了rtcan设备初始化。

static int rtcan_adv_pci_add_chan(struct pci_dev *pdev,
				  int channel,
				  unsigned int bar,
				  unsigned int offset,
				  struct rtcan_device **master_dev)
{
   
	struct rtcan_device *dev;
	struct rtcan_sja1000 *chip;
	struct rtcan_adv_pci *board;
	void __iomem *base_addr;
	int ret;

	dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000),
			      sizeof(struct rtcan_adv_pci));
	if (dev == NULL)
		return -ENOMEM;

	chip = (struct rtcan_sja1000 *)dev->priv;
	board = (struct rtcan_adv_pci *)dev->board_priv;

	if (channel == CHANNEL_SLAVE) {
   
		struct rtcan_adv_pci *master_board =
			(struct rtcan_adv_pci *)(*master_dev)->board_priv;
		master_board->slave_dev =
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值