一,前言
vl.c中main开始初始化,然后就是一个while循环进行事件处理。今天主要从QOM模型入手来分析初始化代码。且围绕boards-discovery.c中注册的函数来分析,主要了解什么时候注册,什么时候使用,通过这样来了解设计方法。
二,源码分析
-
通过每个模块的type_init在main函数调用前就进行注册,加入到hash表就不多说了。static GHashTable *type_table;
-
然后就开始调用这个hash表了,Type_new函数就是把TypeInfo内容复制到TypeImpl。
-
总的来说type_register_internal就是创建一个TypeImpl类,然后添加到hash表中。
static TypeImpl *type_register_internal(const TypeInfo *info)
{
TypeImpl *ti;
ti = type_new(info);
type_table_add(ti);
return ti;
}
- 可以看到ti->name为key,ti为value。
static void type_table_add(TypeImpl *ti)
{
assert(!enumerating_types);
g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
}
- 关于父类继承是通过parent_type进行的连接。type_get_by_name通过hash表的name找到TypeImpl,然后子类指向父类的TypeImpl,其实是在type_initialize函数中处理的type_get_parent。
static TypeImpl *type_get_parent(TypeImpl *type)
{
if (!type->parent_type && type->parent) {
type->parent_type = type_get_by_name(type->parent);
g_assert(type->parent_type != NULL);
}
return type->parent_type;
}
在代码中,其实就是通过name进行了父类关系连接。
![](https://img.haomeiwen.com/i12010880/8744f4667d5933ce.jpg)
- type_initialize是一个关键函数,利用了归递方式,这是类似图形HMI编程常用的方法,比如litegul和LVGL都有类似的归递代码来处理图层,从底层绘制到顶层。当前qemu中是从父类开始,先复制父类的class到子类,然后一次进行type实例中class的初始化。
![](https://img.haomeiwen.com/i12010880/529a9f4fc904708f.jpg)
- type_initialize还将Objectclass和TypeImpl进行了挂钩。
ti->class->type = ti;
-
stm32f4_discovery_board_class_init_callback函数的关键路径。
居然是find_default_mechine后进行foreach循环处理之前添加到hash表的TypeImpl对象,然后进行归递初始化mc。
-
MachineClass *mc = MACHINE_CLASS(oc);我理解直接指向class等于直接引用,但是mc是个临时变量啊,有什么用?那么就看看赋值的函数在哪里用吧!那么我就在这个函数内打断点。
- 看上去来源是machine_class,在select_machine函数中,也就是qemu启动传入的参数里面包括board名字,然后就找到了machine_class。
MachineClass *mc = find_machine(board_name);
if (mc == NULL) {
cm_board_help_func("?");
} else {
machine_class = mc;
}
刚刚说的mc临时参数,原来是find_machine的返回值,而且还给了变量machine_class,所以找到了关系。只是里面用了g_hash_table_foreach等api,不熟悉,仅先猜测功能,当黑盒处理。
![](https://img.haomeiwen.com/i12010880/b5ebe30e43b89413.jpg)
三,小结
继续逐各击破来分析。真心不清楚,现在简书的图上传后怎么自动压缩了。
网友评论