台州市网站制作,秦皇岛做网站公司有哪些,江苏廉政建设网站,医院网站1、平台总线模型
平台总线模型是Linux系统虚拟出来的总线#xff0c;而I2C、SPI等物理总线是真实存在的。 平台总线模型将一个驱动分成两个部分#xff0c;分别是device.c和driver.c#xff0c;分别用来描述硬件信息和控制硬件。 平台总线通过字符串比较#xff0c;将name…1、平台总线模型
平台总线模型是Linux系统虚拟出来的总线而I2C、SPI等物理总线是真实存在的。 平台总线模型将一个驱动分成两个部分分别是device.c和driver.c分别用来描述硬件信息和控制硬件。 平台总线通过字符串比较将name相同的device.c和driver.c匹配到一起来控制硬件。
平台总线模型的优点
减少编写重复代码提高效率提高代码的利用率
2、platform device
//\Linux-4.9.88\include\linux\platform_device.h
struct platform_device {const char *name;//设备名int id; //设备ID号bool id_auto;struct device dev; //包含一个具体的device结构体u32 num_resources; //资源的数量struct resource *resource; //用来保存硬件资源的结构体 io资源中断资源内存资源const struct platform_device_id *id_entry; //平台设备的idchar *driver_override; /* Driver name to force a match *//* MFD cell pointer */struct mfd_cell *mfd_cell; //用户多功能卡多功能设备的实现/* arch specific additions */struct pdev_archdata archdata;
};
extern int platform_device_register(struct platform_device *); //注册平台总线设备
extern void platform_device_unregister(struct platform_device *);//删除平台总线设备
2.1、struct device
struct device {struct device *parent;struct device_private *p;struct kobject kobj;const char *init_name; /* initial name of the device */const struct device_type *type;struct mutex mutex; /* mutex to synchronize calls to* its driver.*/struct bus_type *bus; /* type of bus device is on */struct device_driver *driver; /* which driver has allocated thisdevice */void *platform_data; /* Platform specific data, devicecore doesnt touch it */void *driver_data; /* Driver data, set and get withdev_set/get_drvdata */struct dev_links_info links;struct dev_pm_info power;struct dev_pm_domain *pm_domain;#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAINstruct irq_domain *msi_domain;
#endif
#ifdef CONFIG_PINCTRLstruct dev_pin_info *pins;
#endif
#ifdef CONFIG_GENERIC_MSI_IRQstruct list_head msi_list;
#endif#ifdef CONFIG_NUMAint numa_node; /* NUMA node this device is close to */
#endifu64 *dma_mask; /* dma mask (if dmaable device) */u64 coherent_dma_mask;/* Like dma_mask, but foralloc_coherent mappings asnot all hardware supports64 bit addresses for consistentallocations such descriptors. */unsigned long dma_pfn_offset;struct device_dma_parameters *dma_parms;struct list_head dma_pools; /* dma pools (if dmable) */struct dma_coherent_mem *dma_mem; /* internal for coherent memoverride */
#ifdef CONFIG_DMA_CMAstruct cma *cma_area; /* contiguous memory area for dmaallocations */
#endif/* arch specific additions */struct dev_archdata archdata;struct device_node *of_node; /* associated device tree node */struct fwnode_handle *fwnode; /* firmware device node */dev_t devt; /* dev_t, creates the sysfs dev */u32 id; /* device instance */spinlock_t devres_lock;struct list_head devres_head;struct klist_node knode_class;struct class *class;const struct attribute_group **groups; /* optional groups */void (*release)(struct device *dev);struct iommu_group *iommu_group;struct iommu_fwspec *iommu_fwspec;bool offline_disabled:1;bool offline:1;
};
3、platform driver
这个结构体包含了平台驱动需要实现的相关函数操作
struct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver; //内嵌了一个设备驱动结构体/*平台设备ID这与platform_device中的struct platform_device_id *id_entry是相同的主要是完成总线的匹配操作platform总线的匹配操作第一匹配要素就是该元素。而不再是简单的name选项*/const struct platform_device_id *id_table;bool prevent_deferred_probe;
};3.1、 struct device_driver
struct device_driver {const char *name;struct bus_type *bus;struct module *owner;const char *mod_name; /* used for built-in modules */bool suppress_bind_attrs; /* disables bind/unbind via sysfs */enum probe_type probe_type;const struct of_device_id *of_match_table;const struct acpi_device_id *acpi_match_table;int (*probe) (struct device *dev);int (*remove) (struct device *dev);void (*shutdown) (struct device *dev);int (*suspend) (struct device *dev, pm_message_t state);int (*resume) (struct device *dev);const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p;
};4、实验demo
4.1 platform_device.c
#include linux/module.h
#include linux/fs.h
#include linux/errno.h
#include linux/miscdevice.h
#include linux/kernel.h
#include linux/major.h
#include linux/mutex.h
#include linux/proc_fs.h
#include linux/seq_file.h
#include linux/stat.h
#include linux/init.h
#include linux/device.h
#include linux/tty.h
#include linux/kmod.h
#include linux/gfp.h
#include linux/platform_device.h//static struct resource * res;static void platform_dev_release(struct device *dev)
{printk(this is a test for platform_device\n);
} static struct resource platform_dev_resource[] {};struct platform_device platform_dev_test {.name 100ask_test,.num_resources ARRAY_SIZE(platform_dev_resource),.id -1,.resource platform_dev_resource,.dev {.release platform_dev_release,},
};static int __init platform_dev_test_init(void)
{int err;err platform_device_register(platform_dev_test); return 0;
}static void __exit platform_dev_test_exit(void)
{platform_device_unregister(platform_dev_test);}module_init(platform_dev_test_init);
module_exit(platform_dev_test_exit);MODULE_LICENSE(GPL);
4.2 platform_driver.c
#include linux/module.h
#include linux/fs.h
#include linux/errno.h
#include linux/miscdevice.h
#include linux/kernel.h
#include linux/major.h
#include linux/mutex.h
#include linux/proc_fs.h
#include linux/seq_file.h
#include linux/stat.h
#include linux/init.h
#include linux/device.h
#include linux/tty.h
#include linux/kmod.h
#include linux/gfp.h
#include linux/platform_device.hstatic int platform_drv_probe(struct platform_device *pdev)
{printk(this is a test for platform_drv\n);return 0;}static int platform_drv_remove(struct platform_device *pdev)
{printk(this is in platform_drv_remove\n);return 0;
}static struct platform_driver platform_drv_test {.probe platform_drv_probe,.remove platform_drv_remove,.driver {.name 100ask_test,},
};static int __init platform_drv_test_init(void)
{int err;err platform_driver_register(platform_drv_test); return 0;
}static void __exit platform_drv_test_exit(void)
{platform_driver_unregister(platform_drv_test);
}module_init(platform_drv_test_init);
module_exit(platform_drv_test_exit);MODULE_LICENSE(GPL);
4.3 Makefile # 1. 使用不同的开发板内核时, 一定要修改KERN_DIR
# 2. KERN_DIR中的内核要事先配置、编译, 为了能编译内核, 要先设置下列环境变量:
# 2.1 ARCH, 比如: export ARCHarm64
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILEaarch64-linux-gnu-
# 2.3 PATH, 比如: export PATH$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
# 注意: 不同的开发板不同的编译器上述3个环境变量不一定相同,
# 请参考各开发板的高级用户使用手册KERN_DIR /home/johan/share/linux_bsp/100ask_imx6ull-sdk/Linux-4.9.88all:make -C $(KERN_DIR) Mpwd modules clean:make -C $(KERN_DIR) Mpwd modules clean# 参考内核源码drivers/char/ipmi/Makefile
# 要想把a.c, b.c编译成ab.ko, 可以这样指定:
# ab-y : a.o b.o
# obj-m ab.o#编译成ko
platform_dev-y : platform_device.o
platform_drv-y : platform_driver.o
obj-m platform_dev.o
obj-m platform_drv.o4.4 板子上测试 加载驱动 匹配成功调用prode函数
5、总结
总的来说主要是填充两个结构体struct platform_device和struct platform_driver