概述 bus 模块的功能包括: bus 的注册和注销 本 bus 下有 device 或者 device_driver 注册到内核时的处理 本 bus 下有 device 或者 device_driver 从内核注销时的处理 device_drivers 的 probe 处理 管理 bus 下的所有 device 和 device_driver 数据结构 struct bus_type { const char *name; const char *dev_name; const struct attribute_group **bus_groups; const struct attribute_group **dev_groups; const struct attribute_group **drv_groups; int (*match)(struct device *dev, struct device_driver *drv); int (*uevent)(const struct device *dev, struct kobj_uevent_env *env); int (*probe)(struct device *dev); void (*sync_state)(struct device *dev); void (*remove)(struct device *dev); void (*shutdown)(struct device *dev); int (*online)(struct device *dev); int (*offline)(struct device *dev); int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev); int (*num_vf)(struct device *dev); int (*dma_configure)(struct device *dev); void (*dma_cleanup)(struct device *dev); const struct dev_pm_ops *pm; bool need_parent_lock; }; name : bus 的名称....

2 min

struct device { struct kobject kobj; struct device *parent; struct device_private *p; const char *init_name; /* initial name of the device */ const struct device_type *type; const struct bus_type *bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ void *platform_data; /* Platform specific data, device core doesn't touch it */ void *driver_data; /* Driver data, set and get with dev_set_drvdata/dev_get_drvdata */ struct mutex mutex; /* mutex to synchronize calls to * its driver....

2 min

数据结构 Platform 设备是可以通过 CPU bus 直接寻址的设备, 内核在设备模型 bus, device 和 driver 的基础上, 进行了进一步封装, 抽象了 platform_bus, platform_device, platform_driver. platform 相关的实现在 include/linux/platform_device.h, drivers/base/platform.c中. struct platform_device { const char *name; int id; bool id_auto; struct device dev; u64 platform_dma_mask; struct device_dma_parameters dma_parms; u32 num_resources; struct resource *resource; const struct platform_device_id *id_entry; }; name: platform device 的名称. dev: 指向底层的 device. id: 可以手动设置, 也可设置为宏 PLATFORM_DEVID_NONE 表示没有 id, pdev->dev->name 直接设置为 pdev->name. 设置为宏 PLATFORM_DEVID_AUTO 表示自动生成 id. id_auto: 当 id 设置为 PLATFORM_DEVID_AUTO, id_auto 被置为 true, 在注册 platform_device 时可以自动生成 id....

2 min

概述 include/linux/kobject.h lib/kobject.c Kobject 是基本数据类型,每个 Kobject 都会在"/sys/“文件系统中以目录的形式出现。 Ktype 代表 Kobject 的属性操作集合 (由于通用性,多个 Kobject 可能共用同一个属性操作集,因此把 Ktype 独立出来了). Kset 是一个特殊的 Kobject(因此它也会在"/sys/“文件系统中以目录的形式出现),它用来集合相似的 Kobject(这些 Kobject 可以是相同属性的,也可以不同属性的)。 数据结构 kobject: struct kobject { const char *name; struct list_head entry; struct kobject *parent; struct kset *kset; const struct kobj_type *ktype; struct kernfs_node *sd; /* sysfs directory entry */ struct kref kref; unsigned int state_initialized:1; unsigned int state_in_sysfs:1; unsigned int state_add_uevent_sent:1; unsigned int state_remove_uevent_sent:1; unsigned int uevent_suppress:1; }; name: kobject 的名称, 也是在 sysfs 中的目录名....

2 min

kernel boot 过程,设备树初始化 reserved-memory 节点: early_init_fdt_scan_reserved_mem() fdt_scan_reserved_mem(); fdt_init_reserved_mem(); static int __init fdt_scan_reserved_mem(void) { int node, child; const void *fdt = initial_boot_params; node = fdt_path_offset(fdt, "/reserved-memory"); fdt_for_each_subnode(child, fdt, node) { const char *uname; int err; if (!of_fdt_device_is_available(fdt, child)) continue; uname = fdt_get_name(fdt, child, NULL); /// 存在 reg 属性的情况 err = __reserved_mem_reserve_reg(child, uname); /// 不存在 reg 属性的情况,存在 size 属性 if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) fdt_reserved_mem_save_node(child, uname, 0, 0); } return 0; } /// 先预留 rmem 的 base 和 size 都为 0 void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, phys_addr_t base, phys_addr_t size) { struct reserved_mem *rmem = &reserved_mem[reserved_mem_count]; rmem->fdt_node = node; rmem->name = uname; rmem->base = base; rmem->size = size; reserved_mem_count++; return; } void __init fdt_init_reserved_mem(void) { int i; for (i = 0; i < reserved_mem_count; i++) { struct reserved_mem *rmem = &reserved_mem[i]; unsigned long node = rmem->fdt_node; int len; const __be32 *prop; int err = 0; bool nomap; nomap = of_get_flat_dt_prop(node, "no-map", NULL) !...

3 min

Data Structure struct software_node { const char *name; const struct software_node *parent; const struct property_entry *properties; }; struct swnode { struct kobject kobj; struct fwnode_handle fwnode; const struct software_node *node; int id; /* hierarchy */ struct ida child_ids; struct list_head entry; struct list_head children; struct swnode *parent; unsigned int allocated:1; unsigned int managed:1; }; Provider software_node_register()注册单个 software node, software_node_register_node_group()注册一组 software nodes. 都是将 software nodes 挂入一个全局链表. // 定义属性 static const struct property_entry my_device_properties[] = { PROPERTY_ENTRY_U32("reg", 0), PROPERTY_ENTRY_U32("my_property", 1234), { } }; // 定义 software node static const struct software_node my_device_node = { ....

2 min

v4l2-async.c v4l2-common.h v4l_err()/v4l_warn()/v4l_info()/v4l_dbg(); // for v4l-i2c drivers v4l2_err()/v4l2_warn()/v4l2_info()/v4l2_dbg(); // for v4l2_device and v4l2_subdev // v4l2_ctrl_query_fill(); // v4l2_i2c_new_subdev(); v4l2_i2c_subdev_set_name(); v4l2-ctl.h v4l2-dev.h v4l2_prio_init(); v4l2_prio_change(); v4l2_prio_open(); v4l2_prio_close(); v4l2_prio_max(); v4l2_prio_check(); media_entity_to_video_device(); // to_video_device(); > video_register_device();/video_unregister_device(); // video_register_device_no_warn(); > video_device_alloc();/video_device_release(); > video_device_release_empty(); > v4l2_disable_ioctl(); > video_get_drvdata();/video_set_drvdata(); // get/set video device private data > video_devdata(); // 获取 file 对应的 video device > video_drvdata(); // video_get_drvdata()); > video_device_node_name(); // 获取 device name > video_is_registered(); // 检查 video device 是否已经注册 > video_device_pipeline_start();__video_device_pipeline_start(); > video_device_pipeline_stop();__video_device_pipeline_stop(); > video_device_pipeline_alloc_start(); // 多了 allocate pipeline 的操作,不过一般 pipeline 会嵌在 driver 自定义结构体中,随着上层一起分配。 // video_device_pipeline(); v4l2-device....

2 min

IPCam 3917 isp 模块图: 信号处理路径模块: Crop:裁剪模块,用于裁剪图像的特定区域 BLC:黑电平补偿(Black level Correction) DPC: 坏点校正(Defect Pixel Correction) 2DNR: 2D降噪(2D Noise Reduction) GE: 边缘增强(Gain Enhancement) 3DNR & GE:3D降噪和增益增强 AE Short/Long Gain:自动曝光短/长时间增益控制 HDR Fusion:高动态范围图像融合,合并不同曝光的图像 镜头校正模块: Circle Lens Shading:圆形镜头阴影校正 Grid Lens Shading:网格镜头阴影校正 色彩处理模块: YUV to RGB:YUV色彩空间转换为RGB INTP:demosaic颜色插值, 从raw格式转换到rgb格式 CCM:色彩校正矩阵(Color Correction Matrix) RGB Gamma:RGB伽马校正 WDR:宽动态范围(Wide Dynamic Range)处理 YUV处理模块: YUV420 To YUV422:YUV色彩格式转换 YUV422 To YUV444:YUV色彩格式转换 RGB2YUV444:RGB转YUV444格式 Global Curve:全局曲线调整 UV Tune & UVS:UV通道调整和UV抑制 统计和分析模块: AF Statistics:自动对焦统计数据 AE Short/Long Statistics:自动曝光短/长时间统计数据 Raw Statistics:原始图像统计数据...

1 min

libisp api: global api: rts_av_isp_init/cleanup rts_av_isp_start/stop rts_av_isp_get_status rts_av_isp_register/unregister/get_algo rts_av_isp_bind/unbind_algo rts_av_isp_register/unregister/get/check_sensor rts_av_isp_bind/unbind_sensor rts_av_isp_register_iq mipi out api: rts_av_isp_set_mipiout rts_av_isp_get_mipiout v4l2 control: rts_isp_v4l2_query_ctrl rts_isp_v4l2_query_menu rts_isp_v4l2_g_ctrl rts_isp_v4l2_s_ctrl rts_isp_v4l2_query_ext_ctrl rts_isp_v4l2_g_ext_ctrls rts_isp_v4l2_s_ext_ctrls rts_isp_v4l2_try_ext_ctrls sensor: private mask: 3A Setting: 3A Statis: IQ tuning: other: struct isp_core { struct isp_mod_hash_table hash; struct isp_notify notify; struct v4l2_ctrl_handler ctrl_handler; struct isp_statis statis; struct isp_iq iq; int initialized:1; int running:1; }; hash: hash table, 用来保存 modules. notify: ctrl_hander: statis: iq: initialized: isp_core_init() 之后置 1....

2 min

Chapter 2 Terminology Lane: 单向物理传输 lane, 2(D-PHY) or 3(C-PHY) wire interface for clock or data transmission. Virtual channel: 逻辑层面的概念,每个虚拟通道的数据彼此独立,在 lane 上交错发送,包含标识信息,指明属于哪个外设/通道。 Chapter 7 Physical Layer 有两种 physical layer,D-PHY 和 C-PHY, transmitter 和 receiver 需要一致。 7.1 D-PHY Physical Layer option D-PHY 由多条单向的 data lanes 和一条 clk lane。 对于 clk lane, transmitter 和 receiver 必须实现 continuous clock,non-continuous clock 是可选的。 continuous clk: 保持在 high-speed mode. non-continuous clk: 在两笔数据包之间进入 LP-11 state. 7.2 C-PHY Physical Layer option Chapter 9 Low Level Protocol Features:...

2 min