UEFI开发探索76- YIE001PCIe开发板(09 界面和键盘控制)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】

在开发板YIE001上进行开发,实际上和之前博客中开发UEFI应用,并没有本质的区别。所要注意的,是在Option ROM被BIOS加载之时,所用的UEFI机制以及Protocol是否能正常使用。

一般来说, GraphicsOutput Protocol和ConOut Protocol是可以正常使用的。但是,其他的Protocol,比如创建Event,就很难说了。笔者目前测试的机器上,在加载Option ROM时,创建的Event完全无法按照预期运作。而同样的代码,在同一机器的UEFI Shell下测试却是正常的。

本篇代码的编程过程如下。

1 图形支持和汉字支持

UEFI开发探索中的代码,特别是图形和汉字部分,是从我的开源项目Foxdisk中移植过来的。针对UEFI的机制,进行了改动。所以,在博客中的代码,同文件名的,其内容都差不多。

当然,随着各个课题的展开,代码也在不断地修改。甚至对我而言,也很难分清楚目前所用的文件是什么时候修改的。比如近期又在处理键盘的源文件中,添加了检查键盘按键的非阻塞处理函数CheckKey()。

我尽力维持一个松散而逻辑一致的结构,保证源文件可以直接使用。处理同一硬件的或者同一逻辑层的代码,基本上会在相同的源文件中。

以下列出了源文件的功能:

表1 源文件的功能

源文件引脚名称
Graphic.c, Graphic.h功能
Keyboard.c, Keyboard.h键盘处理
Window.c, Window.h界面相关的代码,比如背景设置等
Font.c, Font.h文字的显示,包括汉字、英文的显示
Common.c, Common.h提供各种Protocol实例,以及共用的一些函数

将以上的文件,拷贝到之前构建好的Option ROM框架代码的文件夹下,修改相应的INF文件,就可以直接使用了。

对于汉字的显示机制,之前的博客中已经讨论得比较多了,可以查看下之前的博客及代码。

不过,博客中讨论的议题还是比较分散的。《UEFI编程实践》的书中,为了编译阅读,将这些议题整理成章了。考虑到版权问题,各种汉字库的提取工具也重新编写了。新书发布的时候,我将会把代码和工具在Gitee和GitHub上共享,有兴趣的技术同好到时可以直接去下载使用。

2 界面及键盘控制编程

Option ROM的代码,只有在BIOS加载到内存中才能运行。在这点上,开发板YIE001和YIE002有很大不同,YIE001毕竟不是独立的MCU,无法独立运行。

本篇的代码,将键盘的控制与YIE001的硬件控制联系起来了。具体实现代码如下:

VOID HelloUEFI(VOID)
{
  UINT64 flag;
  EFI_INPUT_KEY key={0,0};  
  UINT8 *s_text = "Alasse' aure,";  //《魔戒》精灵语的 “你好,日安”
  UINT8 *s_text1 = "欢迎进入UEFI的世界!";
  UINT8 *s_text2 = "按'ESC'键退出此界面";
  flag = InintGloabalProtocols(GRAPHICS_OUTPUT);
  Print(L"flag=%x\n",flag);
  
  //图形显示测试
  SwitchGraphicsMode(TRUE);
  SetBKG(&(gColorTable[DEEPBLUE]));
  
  draw_string(s_text, 110, 60, &MyFontArray, &(gColorTable[WHITE]));
  draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[WHITE]));
  draw_string(s_text2, 135, 140, &MyFontArray1, &(gColorTable[YELLOW]));
  while(key.ScanCode!=0x17) //ESC
  {
    GetKey(&key);
    if(key.ScanCode ==1 ) //UP 
      draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[DEEPBLUE]));
    else if(key.ScanCode ==2 ) //DOWN
      draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[WHITE]));  
    if(key.UnicodeChar == 0x31)   
      SetLed(MyIoBaseAddr,LED1,LEDON);
    if(key.UnicodeChar == 0x32)   
      SetLed(MyIoBaseAddr,LED2,LEDON);
    if(key.UnicodeChar == 0x33)   
      SetLed(MyIoBaseAddr,LED1,LEDOFF);
    if(key.UnicodeChar == 0x34)   
      SetLed(MyIoBaseAddr,LED2,LEDOFF);
  }
  SetMyMode(OldGraphicsMode);
  SwitchGraphicsMode(FALSE);
}

代码的逻辑并不复杂,在设置了图形模式,显示相应的提示字符后,直接进入按键获取的循环。只有接受到用户的ESC按键后,才会退出循环。

方向键的上下键用来控制屏幕上字符串s_text1的显示和消除;数字键1、2、3和4,分别用来控制LED1、LED2的亮和灭。

3 测试

编译命令如下:

C:\UEFIWorkspace>build -t VS2015x86 -p RobinPkg\RobinPkg.dsc \
-m RobinPkg\Drivers\YIE1CG\YIE1CG.inf -a X64

按照UEFI开发探索75介绍的方法,将YIE1CG.rom刷入YIE001的Flash中,并插在实际的机器上进行测试(也可以不刷入,使用UEFI开发探索71中介绍的方法,使用load命令测试)。

Option ROM的界面显示如图1所示。

图1 YIE1CG的界面

通过键盘控制LED灯的演示,只能通过视频拍下转换为GIF。不过,GIF文件太大,就不贴出了。有条件的技术同好,可以按照本篇的方法,修改代码进行实验。

Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目所用ROM文件位于:/ 76 YIE1CG下

1,165 total views, 1 views today

发表评论

电子邮件地址不会被公开。