当前位置:文档之家› 第8章CAN总线驱动器

第8章CAN总线驱动器

总线型运动控制系统

总线型运动控制系统 传统运动控制系统中常以脉冲和模拟量作为控制信号,并将控制信号发送到电机驱动器中,再由电机驱动器驱动电机运行。得益于总线技术的发展,运动控制器厂家将总线技术应用运动控制器中。上位机通过总线将运动参数传送至电机驱动器,再由电机驱动器驱动电机运行。常见的总线技术有ProfiNet,ProfiBus,EhertCA T,RTEX,CCLINK等等。 总线型运动控制系统相对传统的运动控制系统有诸多优点。 1.接线简化。 在传统运动控制系统中,上位机与电机驱动器通过大量的数字量或者模拟量IO连接,以发送控制信号和接受反馈信号。这样会使接线数量增加,接线出错的几率比较大,线材成本上升,布线时间长而复杂。在总线型运动控制系统中,上位机的总线通讯接口可以通过线性拓扑方式连接多个支持总线通讯的电机驱动器。 2.拥有故障自诊断特性。 传统型运动控制系统中的上位机与电机控制器的信息交换是通过有限的IO进行的。能获取的信息是极有限。总线型运动控制系统拥有多种诊断功能。可以实时监控电机的运行状态,实时获取运行状态的信息。如果电机运行有异常,其相应的电机驱动器可通过总线向上位机发送异常信息。如线缆短路或短路、接头接触不良,电压异常等物理层诊断。 3.方便调试。 总线型运动控制系统,可以通过上位应用软件监控和调整各电机驱动器节点的参数。不用通过各电机驱动器的显示面板调整参数。 4.可靠性高 传统运动控制系统的中脉冲信号和模拟量信号,容易受到电磁干扰,可导致信号失真。总线型运动控制系统数字式通讯方式,无信号漂移问题。 总线型运动控制系统应用示例:3S总线控制系统通过EherCAT总线控制7轴运动。3S 总线系统可以控制多达128个轴,支持复杂插补运算;可控制多达10台不同类型的机器人;提供多达8192点数字量或模拟扩展功能;可接入视觉系统实现定位功能。

PCI总线驱动

PCI总线驱动的机制 1.总线子系统初始化 系统初始化时会调用 ■void __init driver_init(void) { 。。。。。。 buses_init(); 。。。。。。 } ■ ★I nclude/linux/kobject.h #define decl_subsys(_name,_type,_uevent_ops) \ struct subsystem _name##_subsys = { \ .kset = { \ .kobj = { .name = __stringify(_name) }, \ .ktype = _type, \ .uevent_ops =_uevent_ops, \ } \ } ★ Drivers/base/bus.c static struct kobj_type ktype_bus = { .sysfs_ops = &bus_sysfs_ops, }; ★ static decl_subsys(bus, &ktype_bus, NULL); bus_subsys={ .ket = { .kobj = { .name = “bus”, .ktype = &ktype_bus, .uevent_ops = NULL, } } ★int __init buses_init(void) { return subsystem_register(&bus_subsys); }

在buses_init中调用subsystem_register时,bus_subsys作为sysfs root 目录下的项被建立(因为其kset.kobj.parent的值为NULL) ■pci总线初始化 ★struct bus_type pci_bus_type = { .name = "pci", .match = pci_bus_match, .uevent = pci_uevent, .probe = pci_device_probe, .remove = pci_device_remove, .suspend = pci_device_suspend, .suspend_late = pci_device_suspend_late, .resume_early = pci_device_resume_early, .resume = pci_device_resume, .shutdown = pci_device_shutdown, .dev_attrs = pci_dev_attrs, }; ★struct device_attribute pci_dev_attrs[] = { __ATTR_RO(resource), __ATTR_RO(vendor), __ATTR_RO(device), __ATTR_RO(subsystem_vendor), __ATTR_RO(subsystem_device), __ATTR_RO(class), __ATTR_RO(irq), __ATTR_RO(local_cpus), __ATTR_RO(modalias), #ifdef CONFIG_NUMA __ATTR_RO(numa_node), #endif __ATTR(enable, 0600, is_enabled_show, is_enabled_store), __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), broken_parity_status_show,broken_parity_status_store), __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store), __ATTR_NULL, }; ★static int __init pci_driver_init(void) { return bus_register(&pci_bus_type); } postcore_initcall(pci_driver_init); 通过postcore_initcall声明,使pci_driver_init函数被链接到.initcall.init段。这个段的函数在初始化时由static void __init do_initcalls(void)函数调用。最终系统在初始化线程static int __init

总线设备驱动

linux内核学习---总线,设备,驱动 Linux 设备模型中三个很重要的概念就是总线,设备,驱动.即 bus,device,driver,而实际上内核中也定义了这么一些数据结构,他们是 struct bus_type,struct device,struct device_driver,这三个重要的数据结构都来自一个地方,include/linux/device.h.我们知道总线有很多种,pci总线,scsi 总线,usb 总线,所以我们会看到Linux 内核代码中出现pci_bus_type,scsi_bus_type,usb_bus_type,他们都是 struct bus_type 类型的变量.而struct bus_type 结构中两个非常重要的成员就是 struct kset drivers 和 struct kset devices。kset 和另一个叫做 kobject 正是 Linux Kernel 2.6 中设备模型的基本元素。 这里我们只需要知道,drivers 和 devices 的存在,让struct bus_type 与两个链表联系了起来,一个是devices 的链表,一个是 drivers 的链表,也就是说,知道一条总线所对应的数据结构,就可以找到这条总线所关联的设备有哪些,又有哪些支持这类设备的驱动程序. 而要实现这些,就要求每次出现一个设备就要向总线汇报,或者说注册,每次出现一个驱动,也要向总线汇报,或者说注册.比如系统初始化的时候,会扫描连接了哪些设备,并为每一个设备建立起一个 struct device 的变量,每一次有一个驱动程序,就要准备一个 struct device_driver 结构的变量.把这些变量统统加入相应的链表,device 插入 devices 链表,driver 插入 drivers 链表. 这样通过总线就能找到每一个设备,每一个驱动。 struct bus_type 中为 devices 和 drivers 准备了两个链表,而代表 device 的结构体 struct device 中又有两个成员,struct bus_type *bus 和 struct device_driver *driver。同样,代表driver 的结构体 struct device_driver 同样有两个成员,struct bus_type *bus 和 struct list_head devices。struct device 和struct device_driver 的定义和 struct bus_type 一样,在 include/linux/device.h 中。凭一种男人的直觉,可以知晓,struct device 中的 bus 记录的是这个设备连在哪条总线上,driver 记录的是这个设备用的是哪个驱动,反过来,struct device_driver 中的 bus 代表的也是这个驱动属于哪条总线,devices 记录的是这个驱动支持的那些设备,没错,是 devices(复数),而不是 device(单数),因为一个驱动程序可以支持一个或多个设备,反过来一个设备则只会绑定给一个驱动程序。 上面是理论知识,下面我们具体以展讯平台的I2C设备重力加速度传感器MC3XXX驱动为例进行实例分析: 1.首先在Board-sp7715ga.c文件中通过sc8810_add_i2c_devices函数(其实是i2c_register_board_info函数)将指定的I2C设备( MC3XXX_ACC_I2C_NAME, MC3XXX_ACC_I2C_ADDR---包括设备名和设备地址)申请一个I2C struct device 结构,并且挂入I2C总线中的devices 链表中来。 注意:该device挂入devices链表的操作会先于I2C设备驱动加载的操作被执行。i2c_register_board_info函数对此进行了特别说明:

pci总线驱动

在总结的过程中参考了下面一些资料,在此表示感谢: [1] [2] [3] [4] 3rd Edition. 1. 总线、设备和驱动 1.1 简单介绍 Linux设备模型中三个很重要的概念就是总线、设备和驱动,即bus,device和driver。它们分别对应的数据结构分别为structbus_type,struct device和structdevice_driver。 总线是处理器与一个或多个设备之间的通道,在设备模型中,所有的设备都通过总线相连。在最底层,Linux 系统中的每一个设备都用device结构的一个实例来表示。而驱动则是使总线上的设备能够完成它应该完成的功能。 在系统中有多种总线,如PCI总线、SCSI总线等。系统中的多个设备和驱动是通过总线让它们联系起来的。在bus_type中两个很重要的成员就是structkset drivers和structkset devices。它分别代表了连接在这个总线上的两个链,一个是设备链表,另一个则是设备驱动链表。也就是说,通过一个总线描述符,就可以找到挂载到这条总线上的设备,以及支持该总线的不同的设备驱动程序。 1.2 总线、设备与驱动的绑定 在系统启动时,它会对每种类型的总线创建一个描述符,并将使用该总线的设备链接到该总线描述符的devices链上来。也即是说在系统初始化时,它会扫描连接了哪些设备,并且为每个设备建立一个struce device变量,然后将该变量链接到这个设备所连接的总线的描述符上去。另一方面,每当加载了一个设备驱动,则系统也会准备一个structdevice_driver结构的变量,然后再将这个变量也链接到它所在总线的描述符的drivers链上去。 对于设备来说,在结构体struct device中有两个重要的成员,一个是structbus_type *bus,另一个是structdevice_driver *driver。bus成员就表示该设备是链接到哪一个总线上的,而driver成员就表示当前设备是由哪个驱动程序所驱动的。对于驱动程序来说,在结构体structdevice_driver中也有两个成员,structbus_type *bus和structlist_head devices,这里的bus成员也是指向这个驱动是链接到哪个总线上的,而devices这个链表则是表示当前这个驱动程序可以去进行驱动的那些设备。一个驱动程序可以支持一个或多个设备,而一个设备则只会绑定给一个驱动程序。 对于device与device_driver之间建立联系的方式,主要有两种方式。第一种,在计算机启动的时候,总线开始扫描连接在其上的设备,为每个设备建立一个struct device变量并链接到该总线的devices链上,然后开始初始化不同的驱动程序,驱动程序到它所在的总线的devices链上去遍历每一个还没有被绑定给某个驱动的设备,然后再查看是否能够支持这种设备,如果它能够支持这种设备,则将这个设备与这个驱动联系起来。即,将这个设备的device变量加到驱动的devices链上,同时让struct device中的device_driver指向当前这个驱动。第二种则是热插拔。也即是在系统运行时插入了设备,此时内核会去查找在该bus链上注册了的device_driver,然后再将设备与驱动联系起来。设备与驱动根据什么规则联系起来,它们是如何被联系起来的代码我们将在后面的章节进行详细的描述。 1.3 PCI总线 PCI是一种在CPU与I/O设备之间进行高速数据传输的一种总线。有很多设备都是使用PCI总线的,网卡就是其中之一。我们在前面讲了那些总线、设备与驱动方面的知识,原因就在于网卡是连接到PCI总线上,所以PCI总线、网卡设备以及网卡驱动就成了我们研究网卡的一个很重要的线索,尤其是在网络的链路层部分。下图显示了在一个系统中PCI设备的一个框图:

相关主题
文本预览
相关文档 最新文档