一个mcu 物理连接两块彩屏,使用一个lvgl内核实现对双显示器的显示驱动。
V8.3.x
disp_flush
),根据坐标进行判断,属于显示器1 范围的数据,写到物理显示器1;属于显示器2范围的数据,写到物理显示器2。LCD_SCR1_Y_MAX
);显示缓冲区初始化和显示器注册的处理部分都在 lv_port_disp.c
文件中;复制一份 lv_port_disp.c
(lv_port_disp.h
)文件,改名为 lv_port_disp_2.c
( lv_port_disp_2.h
)负责显示器2的初始化。
在调用 lv_port_disp_init()
后面,调用 lv_port_disp_init_2()
完成上面步骤之后,就已经完成了显示器缓冲区分配,显示驱动注册。
通过阅读官方帮助文档,我们知道 lv_disp_set_default(disp)
用来切换当前的默认显示器。
void lv_disp_set_default(lv_disp_t * disp)
{
disp_def = disp;
}
参数 disp
就是要设置的显示器指针。
大致看了一遍相关的源码文件,没看到直接返回显示器1,显示器2的相关接口函数。重新研究了一遍注册显示器的过程,发现 lv_disp_drv_register
注册显示驱动函数,会返回当前注册的显示器指针。这个函数在lv_port_disp.c
文件中调用。
由于默认只有一个显示器,所以默认也没接收这个函数的返回值,记录为当前显示器指针。
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
以显示器1 为例说明。以下代码都是在 lv_port_disp.c
文件中实现。
static lv_disp_t *_local_lv_disp_1;
_local_lv_disp_1 = lv_disp_drv_register( &disp_drv );
lv_disp_t *lv_port_get_screen_1( void )
{
return _local_lv_disp_1;
}
查看lv_disp_drv_register
函数,发现函数的第一行实现如下:
lv_disp_t * disp = _lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));
插入一个 接节点到列表LV_GC_ROOT(_lv_disp_ll)
的头部,并返回新插入的节点的指针。列表 LV_GC_ROOT(_lv_disp_ll)
就是物理显示器列表。
那么,我们遍历整个 LV_GC_ROOT(_lv_disp_ll)
列表,就能依次返回物理显示器的指针。由于应用层先注册显示器1,所以显示器1的指针位于队列尾。
lv_disp_t *lv_port_get_screen_1( void )
{
return _lv_ll_get_tail( &LV_GC_ROOT( _lv_disp_ll ) );
}
lv_disp_t *lv_port_get_screen_2( void )
{
return _lv_ll_get_head( &LV_GC_ROOT( _lv_disp_ll ) );
}
lv_disp_set_default(lv_port_get_screen_1());
lv_disp_set_default(lv_port_get_screen_2());