uboot移植(十七)实现 LCD 显示

arch/arm/lib/board.c 中的 board_init_f 函数

如果定义了 CONFIG_LCD,就会调用了 lcd_setmem 函数,这个函数用来分配帧缓存地址, 其定义在common/lcd.c

        这个函数调用了 panel_info 变量,这个变量在每个具体的 lcd 驱动中定义,定义了具体 LCD 的相关信息,比如这里通过 debug 打印了它的成员变量: vl_col(列)、 vl_row(行)和 vl_bpixBPP)。 然后调用lcd_get_size 函数来获得帧缓存大小。 lcd_get_size common/lcd.c 中定义为一个弱符号,我们可以在自己的 LCD 驱动中重定义这个函数,也可以使用默认的。

arch/arm/lib/board.c 中的 board_init_r 函数

这里调用了 stdio_init,初始化标准输入、标准输出、标准错误输出等 IO。 它在 common/stdio.c 中定义common/stdio.c 中的 stdio_init 函数

如果定义了 CONFIG_LCD,就调用 drv_lcd_init,其定义在 common/lcd.c

这个函数又调用了当前文件中的 lcd_init,初始化 LCD

        这个函数调用了 lcd_ctrl_init,这个函数在具体的 LCD 驱动中实现,我们需要自己实现这个函数,它进行具体的硬件初始化,下面调用 lcd_clear 清屏, lcd_enable 使能 LCD 控制器,这个函数也需要我们自己实现。 分析到这里,我们就可以开始移植 LCD 驱动了。
        首先在
drivers/video 目录下创建文件 s5pv210_fb.c,同时修改 drivers/video/Makefile,把 s5pv210_fb.c
编译进 u-boot.bin

然后在 smdkv210.h 中定义相关宏

按照惯例,我们需要在 s5pv210_fb.c 中操作 LCD 控制器的寄存器,因此需要在arch/arm/include/asm/arch-s5pc1xx/下创建 lcd_reg.h,定义 LCD 控制器的寄存器结构体

同样需要修改 arch/arm/include/asm/arch-s5pc1xx/cpu.h

定义 LCD 控制器的基地址

定义获得 LCD 控制器基地址的宏
然后仿照裸机编程中
LCD 一节的代码,在 s5pv210_fb.c 中实现 lcd_ctrl_init 函数和 lcd_enable 函数。
还要定义一个用来描述
LCD 相关信息的结构体

这个结构体中使用了一个宏 LCD_COLOR24,表示使用 24BPP,在 include/lcd.h 中只定义了下面几个表示颜色位深的宏

我们的 LCD 使用的是 24BPP,因此需要在其后面添加一个 LCD_COLOR24

另外,在下面定义了默认的 LCD_BPP LCD_COLOR8

我们使用的是 24BPP,因此需要在 smdkv210.h 中定义 LCD_BPP 24BPP

下面开始编译,出错

找到 common/lcd.c 106

        如果 LCD_BPP == LCD_COLOR8 或者 LCD_BPP == LCD_COLOR16 ,就定义 COLOR_MASK,否则就输出
错误信息
Unsupported LCD BPP,我们的 BPP 24,因此需要修改这段代码

我们还需要修改 lcd_drawchars 函数,也是与 BPP 相关的,否则屏幕没输出

我们使用 24BPP,一个像素在内存中占 32 位,有一个字节被浪费掉了

再次编译,成功将文字输出到 LCD 上了

        stdio 为串口, stdou stderr 已经定向到 lcd 了,我们可以在串口终端输入东西,但是我们只能在 LCD
上看到我们输入了什么。

我们可以设置环境变量 stdout=serial,将标准输出重新定向到串口,我们在串口终端输入
set stdout serial
注意:我们的输入没法在串口终端显示出来,但可以在 LCD 上看到我们的输入,然后按回车执行后,
就将标准输出切换到串口终端了。
u-boot 中,将标准输出(stdou)定向到 LCD 是没什么意义的, 我希望的是在 u-boot 中显示开机
画面,这样避免了在
u-boot 启动到内核启动期间屏幕一直黑屏。
common/lcd.c 中的 lcd_clear 函数中调用了当前文件中的 lcd_logo

splash screen 即启动画面的意思。
如果定义了
CONFIG_SPLASH_SCREEN,就会执行下面这段代码。首先获得环境变量 splashimage 的值保存到 s 中,然后调用 simple_strtoul 将它转换为 16 进制的整数保存到 addr 中。
环境变量
splashimage 保存了要显示的图片的地址,然后调用 splash_screen_prepare 做一些准备工作,比如:我们的图片实际保存在 SD 卡或者 FLASH 中, splash_screen_prepare 这个函数就可以从 SD 卡或者 FLASH 中将图片读取到环境变量 splashimage 指定的地址,接着调用 bmp_display 函数显示图片,给它传了一个参数 addraddr 保存了要显示的图片在内存中的地址。 因此,我们需要准备一张 BMP 格式的图片。
首先在
smdkv210.h 中定义宏 CONFIG_SPLASH_SCREEN

        我们还需要修改分区信息,增加一个分区用来存储 BMP 图片,我制作了一张 800x480 BMP 格式
的图片,大约
1M 多点。我们就给它分配 2M 的空间。

我们可以在CONFIG_EXTRA_ENV_SETTINGS 中定义一下额外的环境变量,将默认的删除掉,然后定义splashimage 0x23000000,我们将 BMP 图片从 FLASH 中加载到这个地址。

另外,我们还需要实现 splash_screen_prepare 函数,用来从 FLASH 中拷贝 BMP 图片到环境变量splashimage 指定的地址。 我们在 s5pv210_fb.c 中定义 splash_screen_prepare

这里我们使用了 run_command_list 来执行命令,这样比较方便。
编译出错


没有定义 bmp_display,通过 SourceInght 跟踪代码发现 bmp_display common/cmd_bmp.c 中定义,
我们看下
common 下的 Makefile

发现需要定义 CONFIG_CMD_BMP 这个宏,我们在 smdkv210.h 中来定义它

再次编译,成功生成 u-boot-a.bin,如果还是出错,需要执行 make distclean,重新配置、编译。
前面移植了
u-boot LCD 驱动,把输出定向到了 LCD,我们通过设置环境变量 stdout 重新将标准输出定向到串口(前面讲过),然后烧写 u-boot-a.bin NAND FLASH

然后重启
我们发现,添加启动画面后,
u-boot 已经不再把标准输出定向到 LCD 了,看 common/console.c 中的console_init_r 就明白了

如果定义了环境变量 splashimage,就把标准输出定向到了 serial
由于现在还没有烧写图片到
NAND FLASH,所以 LCD 没有显示,下面烧写图片到 NAND log 分区
首先需要加载默认的分区,然后查看一下分区,看是否有
log 分区

执行 saveenv 将新的分区信息保存到 NAND

将制作好的 bmp 图片写入 NAND

然后重启, LCD 没有显示图片,串口输出一条错误信息

提示需要 32 位的图片,我之前制作了 2 bmp 图片,一张 24 位,一张 32 位,现在我烧写 32 位的图片。
首先我们添加几个菜单,方便以后操作


我们添加了
3 个菜单, 菜单 0 通常用来执行 bootcmd 指定的命令,用来启动内核,默认执行菜单 0,由于现在我们还没移植内核,所以用 echo 命令打印空,什么也不做。 另外添加了更新 u-boot log的菜单。

现在我们可以使用上下键选择菜单 download log 来下载图片了,将 32 位图片下载到 NAND 后重启

没有提示错误了,但 LCD 还是没有显示,跟踪代码发现,在 bmp_display 中调用的lcd_display_bitmap 函数是根据 CONFIG_BMP_xx 来决定如何显示图片的,我们没有定义这个宏,导致 lcd_display_bitmap 没有显示任何东西。我们需要定义的是 CONFIG_BMP_32BPP,在 smdkv210.h 中定义

重新编译,把u-boot-a.bin烧写到NAND,重启开发板,选择update u-boot(u-boot-a.bin)菜单更新u-boot

更新完成后重启

我们需要进行如下操作再次加载默认分区表

烧写 32 位图片到 NAND log 分区

重启开发板,已经显示图片了

下面教大家如何使用 Photoshop 制作 32 位的 BMP 图片
打开
Photoshop,文件->新建


输入宽度和高度,背景色透明,确定
选择 文件
->置入,找到你要制作的图片后,单击置入


然后拖动图片到背景框的大小

然后双击图片

然后选择 文件->存储为 ,选择格式为 BMP ,然后单击保存


选择深度为 32 位,确定,制作完成。

猜你喜欢

转载自blog.csdn.net/jerrygou/article/details/80645913