U-Boot Driver Model领域模型设计 (转)
需求分析
在2014年以前,uboot没有一种类似于linux kernel的设备驱动模型,随着uboot支持的设备越来越多,其一直受到如下问题困扰:
- 设备初始化流程都独立实现,而且为了集成到系统,需要修改核心公共代码(如init_sequence)
- 很多子系统只允许一个驱动,比如无法同时支持USB2.0和USB3.0
- 子系统间的交互实现各异,开发难度大
- 没有个统一的设备视图(如linux的/sys)
uboot driver model(U-Boot驱动模型,以下简写dm)的提出就是为了解决这些问题,它的设计目标包括:
- 提供统一设备驱动框架,降低设备驱动的开发复杂度
- 提供设备树视图
- 支持设备组
- 支持设备lazy init
- 支持设备驱动沙盒测试
- 较小的系统开销(内存和CPU)
对象设计
对象的设计之所以区分静态形式和运行态形式,考量的出发点是设计模块化。
静态表达形式的对象是离散的,和系统和其他对象隔离开,减小对象的复杂度,利于模块化设计,遵循人类表达习惯。
运行态形式的对象是把所有对象组合成层次视图,有着清晰的数据关联视图。方便系统运行时数据的流动。
静态表达形式
device: FDT(设备树文本描述) 或者 静态数据结构U_BOOT_DEVICE(以数据段形式组织)
driver: 静态数据结构U_BOOT_DRIVER(以数据段形式组织)
运行态形式
udevice: 设备对象(以链表形式组织)
driver: 驱动对象。作为udevice的一个属性
uclass:设备组公共属性对象(以链表形式组织),外部顶层对象,作为udevice的一个属性
uclass_driver: 设备组公共行为对象,作为uclass的一个属性
领域建模
uboot设备模型中udevice为核心对象,以树型模型组织(如下),其为dm的顶层结构。

单个udevice建模如下,详细对象定义参见《附:核心数据结构》小节。
所有对象可以按udevice或者uclass进行遍历。

DM初始化流程
DM初始化流程包括:
- 模型初始化
- 静态对象初始化
- 运行态对象初始化
- 设备组公共初始化
- 设备初始化
DM初始化的总入口接口:dm_init_and_scan(),其主要由以下三块组成:
dm_init():创建udevice和uclass空链表,创建根设备(root device)
dm_scan_platdata():扫描U_BOOT_DEVICE定义的设备,创建对应的udevice和uclass对象,查找并绑定相应driver,并调用probe流程。
dm_scan_fdt():扫描由FDT设备树文件定义的设备,创建对应的udevice和uclass对象,查找并绑定相应driver,并调用probe流程。
附:核心数据结构

U_BOOT_DRIVER(demo_shape_drv) = {
.name = "demo_shape_drv",
.of_match = demo_shape_id,
.id = UCLASS_DEMO,
.ofdata_to_platdata = shape_ofdata_to_platdata,
.ops = &shape_ops,
.probe = dm_shape_probe,
.remove = dm_shape_remove,
.priv_auto_alloc_size = sizeof(struct shape_data),
.platdata_auto_alloc_size = sizeof(struct dm_demo_pdata),
};
#define U_BOOT_DRIVER(__name) \
ll_entry_declare(struct driver, __name, driver)
#define ll_entry_declare(_type, _name, _list) \
_type _u_boot_list_2_##_list##_2_##_name __aligned(4) \
__attribute__((unused, \
section(".u_boot_list_2_"#_list"_2_"#_name)))
struct driver {
char *name;
enum uclass_id id;
const struct udevice_id *of_match;
int (*bind)(struct udevice *dev);
int (*probe)(struct udevice *dev);
int (*remove)(struct udevice *dev);
int (*unbind)(struct udevice *dev);
int (*ofdata_to_platdata)(struct udevice *dev);
int (*child_post_bind)(struct udevice *dev);
int (*child_pre_probe)(struct udevice *dev);
int (*child_post_remove)(struct udevice *dev);
int priv_auto_alloc_size;
int platdata_auto_alloc_size;
int per_child_auto_alloc_size;
int per_child_platdata_auto_alloc_size;
const void *ops; /* driver-specific operations */
uint32_t flags;
};
U_BOOT_DEVICE(demo0) = {
.name = "demo_shape_drv",
.platdata = &red_square,
};
#define U_BOOT_DEVICE(__name) \
ll_entry_declare(struct driver_info, __name, driver_info)
struct driver_info {
const char *name;
const void *platdata;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
uint platdata_size;
#endif
};
struct uclass {
void *priv;
struct uclass_driver *uc_drv;
struct list_head dev_head;
struct list_head sibling_node;
};
UCLASS_DRIVER(demo) = {
.name = "demo",
.id = UCLASS_DEMO,
};
#define UCLASS_DRIVER(__name) \
ll_entry_declare(struct uclass_driver, __name, uclass)
struct uclass_driver {
const char *name;
enum uclass_id id;
int (*post_bind)(struct udevice *dev);
int (*pre_unbind)(struct udevice *dev);
int (*pre_probe)(struct udevice *dev);
int (*post_probe)(struct udevice *dev);
int (*pre_remove)(struct udevice *dev);
int (*child_post_bind)(struct udevice *dev);
int (*child_pre_probe)(struct udevice *dev);
int (*init)(struct uclass *class);
int (*destroy)(struct uclass *class);
int priv_auto_alloc_size;
int per_device_auto_alloc_size;
int per_device_platdata_auto_alloc_size;
int per_child_auto_alloc_size;
int per_child_platdata_auto_alloc_size;
const void *ops;
uint32_t flags;
};
struct udevice {
const struct driver *driver;
const char *name;
void *platdata;
void *parent_platdata;
void *uclass_platdata;
int of_offset;
ulong driver_data;
struct udevice *parent;
void *priv;
struct uclass *uclass;
void *uclass_priv;
void *parent_priv;
struct list_head uclass_node;
struct list_head child_head;
struct list_head sibling_node;
uint32_t flags;
int req_seq;
int seq;
#ifdef CONFIG_DEVRES
struct list_head devres_head;
#endif
};

U-Boot Driver Model领域模型设计 (转)的更多相关文章
- U-Boot Driver Model领域模型设计
需求分析 在2014年以前,uboot没有一种类似于linux kernel的设备驱动模型,随着uboot支持的设备越来越多,其一直受到如下问题困扰: 设备初始化流程都独立实现,而且为了集成到系统,需 ...
- Apworks框架实战(五):EasyMemo的领域模型设计
在上一讲中,我们已经新建了一个聚合根对象Account,并已经可以开始设计领域模型了.在这一讲中,我们会着重介绍EasyMemo领域模型的分析和设计,并引入Visual Studio Ultimate ...
- 和S5933比较起来,开发PLX9054比较不幸,可能是第一次开发PCI的缘故吧。因为,很多PCI的例子都是对S5933,就连微软出版的《Programming the Microsoft Windows Driver Model》都提供了一个完整的S5933的例子。 在这篇有关DDK的开发论文里。
和S5933比较起来,开发PLX9054比较不幸,可能是第一次开发PCI的缘故吧.因为,很多PCI的例子都是对S5933,就连微软出版的<Programming the Microsoft Wi ...
- DDD(Domain Driver Designer) 领域驱动设计简介
领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...
- NHibernate实战详解(一)领域模型设计
关于NHibernate的资料本身就不多,中文的就更少了,好在有一些翻译文章含金量很高,另外NHibernate与Hibernate的使用方式可谓神似,所以也有不少经验可以去参考Hibernate. ...
- 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?
写在前面 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repository(仓储)职责所在? Domain Model(领域模型)重新设计 Domain ...
- DDD 领域驱动设计-如何完善 Domain Model(领域模型)?
上一篇:<DDD 领域驱动设计-如何 DDD?> 开源地址:https://github.com/yuezhongxin/CNBlogs.Apply.Sample(代码已更新) 阅读目录: ...
- DDD(领域驱动设计)应对具体业务场景,Domain Model(领域模型)到底如何设计?
DDD(领域驱动设计)应对具体业务场景,Domain Model(领域模型)到底如何设计? 写在前面 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领域模型的 ...
- DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?
DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)? 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repositor ...
随机推荐
- ExtJs6.2环境配置
http://extjs.org.cn/node/831 注意环境变量就是把 创建的项目文件放在C盘中
- python-爬虫-史书典籍
import requests import os from lxml import html import time def get_title_url(tree): '''一级 获取标题''' # ...
- Ubuntu重启关机命令
重启命令 : 1.reboot 立刻重启 2.shutdown -r now 立刻重启 3.shutdown -r 10 过10分钟自动重启 4.shutdown -r 20:35 在时间为20:3 ...
- win7中文版 切换成 英文版
打开[控制面版]-->[更改显示语言] 2.点击[安装/卸载语言] 3.启用Windows Update 4.更新完后,打开可选更新,拉到底,选上 英语语言包 同时记得取消所有重要更新的,再 ...
- Ubuntu关机等待时间解决方案
关于GDM问题(a stop job is running for session c1 of user root 1 min 30 s) 注意了,这个不是系统的问题,是配置的问题.鼓捣了老久才找出来 ...
- jsp文件
新建的jsp文件比新建的html文件多了一行内容<%@ page contentType="text/html; charset=utf-8" %>,这样不会显示乱码 ...
- # 解决MongoDB突然无法连接的问题
解决MongoDB突然无法连接的问题 使用命令,加上路径sudo mongod --dbpath=/var/lib/mongodb 这种情况一般是上一次使用的时候没有正常关闭数据库,正常启动:mong ...
- JavaScript更改css样式
来源:https://www.w3school.com.cn/js/js_htmldom_css.asp 1, document.getElementById(id).style.property = ...
- Codeforces 1201C. Maximum Median
传送门 看到中位数考虑先把数排序一下 然后有个显然的贪心,一个数增加后一定不能比下一个数大,不然我们直接增加下一个数显然更优 所以初始时的中位数操作后也是中位数 那么我们只要考虑中间再往后怎么加使得答 ...
- VMware中centos7访问外网配置
1.配置虚拟机网络适配器,选择NAT模式 2.在编辑->虚拟机网络编辑器->更改设置 选择目前使用的网卡 3.通过ifconfig查看网卡配置 4.编辑网络配置对应上面网卡名称ens33 ...