admin 管理员组文章数量: 1086019
xilinx
查看设备结构体:
struct xvip_composite_device {struct v4l2_device v4l2_dev;struct media_device media_dev;struct device *dev;struct v4l2_async_notifier notifier;struct list_head entities;unsigned int num_subdevs;struct list_head dmas;u32 v4l2_caps;
};
由上面可知xvipp为一个v4l2设备,同时将其加入media框架中,notifier为v4l2同步子设备的通知器,即子设备被注册后,通知消息将会添加到该结构体中。同时定一个entites链表,用来保存整个pipeline通路上的实体。同时定义一个DMA通道的链表。
下面看一下probe函数:
static int xvip_composite_probe(struct platform_device *pdev)
{struct xvip_composite_device *xdev;int ret;xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);if (!xdev)return -ENOMEM;xdev->dev = &pdev->dev;INIT_LIST_HEAD(&xdev->entities);INIT_LIST_HEAD(&xdev->dmas);ret = xvip_composite_v4l2_init(xdev);if (ret < 0)return ret;ret = xvip_graph_init(xdev);if (ret < 0)goto error;platform_set_drvdata(pdev, xdev);dev_info(xdev->dev, "device registered\n");return 0;error:xvip_composite_v4l2_cleanup(xdev);return ret;
}
xvip_composite_v4l2_init函数中将media设备和v4l2设备进行了注册。
xvip_graph_init函数中,初始化DMA通道,即上一篇博客中的xilinx_dma设备。接着解析praph并抽取子设备设备树节点的列表,填充entites字段。然后注册子设备通知器v4l2_async_notifier_register,在该函数中,假设子设备匹配较晚,则在链表中获取不到已有的子设备注册,此时将通知消息加入notifier_list链表中,待子设备驱动端获取;若已有子设备注册,则会执行v4l2_async_test_notify函数:
static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,struct v4l2_subdev *sd,struct v4l2_async_subdev *asd)
{int ret;if (notifier->bound) {ret = notifier->bound(notifier, sd, asd);if (ret < 0)return ret;}ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);if (ret < 0) {if (notifier->unbind)notifier->unbind(notifier, sd, asd);return ret;}/* Remove from the waiting list */list_del(&asd->list);sd->asd = asd;sd->notifier = notifier;/* Move from the global subdevice list to notifier's done */list_move(&sd->async_list, ¬ifier->done);if (list_empty(¬ifier->waiting) && notifier->complete)return notifier->complete(notifier);return 0;
这里回调bound和执行v4l2_device_register_subdev把子设备注册到v4l2核心层。
在我们的项目中子设备(python1300_core、rxif)的注册都晚于xvip设备,在子设备中,通过v4l2_async_register_subdev进行注册:
int v4l2_async_register_subdev(struct v4l2_subdev *sd)
{struct v4l2_async_notifier *notifier;mutex_lock(&list_lock);INIT_LIST_HEAD(&sd->async_list);list_for_each_entry(notifier, ¬ifier_list, list) {struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, sd);if (asd) {int ret = v4l2_async_test_notify(notifier, sd, asd);mutex_unlock(&list_lock);return ret;}}/* None matched, wait for hot-plugging */list_add(&sd->async_list, &subdev_list);mutex_unlock(&list_lock);return 0;
}
这里操作与上面v4l2_async_notifier_register互补关系;不管谁先谁后注册,最后都将实现v4l2_async_test_notify函数操作。
xilinx定义xvip_composite_device这个虚拟物体的目的就是方便对设备的统一的管理,作为这个驱动的v4l2设备管理着python_core和rxif两个子设备。而在应用层操作需要关心的是xilinx-dma.c中的dma通道设备,因为其被注册为video_device设备。
本文标签: xilinx
版权声明:本文标题:xilinx 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1688226502a194425.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论