UEFI开发探索90- YIE002USB开发板(13 Linux编程)

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

上一篇使用hidapi的hidraw方式,实现了Linux上位机与USB HID设备通信的测试程序。不过,只实现了三种通信方式中的两种。本篇将使用hidapi的libusb方式,将三种通信方式全部实现。

1 建立开发目录

与上一篇一样,首先建立开发用的目录。新建文件夹hidlibusb,将以下文件拷贝进去:

libusb/hid.c
hidapi/hidapi.h
hidtest/test.c

为目前的代码编写Makefile,内容如下:

继续阅读“UEFI开发探索90- YIE002USB开发板(13 Linux编程)”

24 total views, 2 views today

UEFI开发探索89- YIE002USB开发板(12 Linux编程)

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

对于USB HID的编程,在YIE002USB开篇时,就已经讨论过:

  1. 下位机是使用YIE002制作的USB HID设备,这是嵌入式开发;
  2. 上位机包括了Windows系统、UEFI系统和Linux系统。

上位机软件中,没有把Mac OSX包含进来,主要是因为我较少在苹果的系统上开发,而且也可以将其等同于Linux系统看待(同属于类Unix系)。

至今为止,Windows系统和UEFI系统,我们都已经完成了上位机的软件编写,下面该进入Linux的USB HID上位机软件开发了。

1 概述

对于Linux下的HID,网站“The Linux Kernel”上有非常详细的描述,值得仔细阅读,网址为:
https://www.kernel.org/doc/html/latest/hid/index.html。

我们所要访问的设备,是USB HID设备。在Linux系统中,常用的USB开源库,是libusb。这是一个用C语言开发的,跨平台的USB设备访问接口库。

在Github上找到这个开源库后,通读了一遍其文档。理论上使用它,可以完整地实现我们所需要的功能。不过,文档中也建议,如果是访问HID设备的话,可以使用hidapi。

hidapi是一个开源的操作HID设备的C语言库,适用于Windows、Linux和Mac OSX平台。它是针对HID设备的,对于其他USB设备不合适。

其源码仓库为:https://github.com/libusb/hidapi,主要目录如下:

hidapi: 头文件(所有平台共用一份头文件)hidapi.h
libusb:Linux系统实现源码文件hid.c,使用libusb库实现的方式
linux:Linux系统实现源码文件hid.c,使用内核接口(hidraw)实现方式
windows:Windows系统实现源码文件hid.c
mac:Mac OSX 系统实现源码文件hid.c
hidtest:测试代码 test.c
继续阅读“UEFI开发探索89- YIE002USB开发板(12 Linux编程)”

24 total views, no views today

UEFI开发探索88- YIE002USB开发板(11 UEFI下访问HID设备)

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

通过前面几个篇章的博客,制作好了USB HID设备,并使用Windows下的上位机工具UsbHID,测试了设备的工作状态。

终于,可以在UEFI系统下构建访问USB HID设备的工程了。

我们所制作的USB HID设备,在Windows系统下可以成功通信,这也意味着,在UEFI环境下,我们也可以与之通信。

首先,使用linux下的lsusb工具,查看下我们之前实现的USB HID设备:

robin@robin-virtual-machine:~$ sudo lsusb -v -d 0x8765:4321
Bus 002 Device 004: ID 8765:4321  
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x8765 
  idProduct          0x4321 
  bcdDevice            2.00
  iManufacturer           1 Robin
  iProduct                2 Robin's UEFI Explorer
  iSerial                 3 My123
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      33
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              32
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              32
Device Status:     0x0003
  Self Powered
  Remote Wakeup Enabled

从中可以看出,自制的USB HID设备,端点1可以使用中断传输的方式进行通信。另外,在上述的信息中没有列出报表描述符,此设备支持通过Output report& Input report、Feature report的方式进行通信,传输字节为16字节。

本篇介绍如何在UEFI系统下,实现对应这三种通信方式的代码,主要实现步骤如下。

继续阅读“UEFI开发探索88- YIE002USB开发板(11 UEFI下访问HID设备)”

24 total views, no views today

UEFI开发探索87- YIE002USB开发板(10 UEFI对USB的支持2)

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

3 EFI_USB_IO_PROTOCOL

EFI_USB_IO_PROTOCOL由USB总线驱动产生,可由UEFI应用和驱动使用,用来访问各种USB设备,比如USB键盘、鼠标和大容量存储设备等。EFI_USB_IO_PROTOCOL所提供的接口,可提供四种类型的传输方式与USB设备通信,即之前介绍过的控制传输、中断传输、批量传输和实时传输。

EFI_USB_IO_PROTOCOL的函数接口如下所示:

typedef struct _EFI_USB_IO_PROTOCOL {
  EFI_USB_IO_CONTROL_TRANSFER UsbControlTransfer;   //控制传输
  EFI_USB_IO_BULK_TRANSFER UsbBulkTransfer;          //批量传输
  EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER  \
                          UsbAsyncInterruptTransfer;   //异步中断传输
  EFI_USB_IO_SYNC_INTERRPUT_TRANSFER UsbSyncInterruptTransfer //同步中断传输
  EFI_USB_IO_ISOCHRONOUS_TRANSFER UsbIsochronousTransfer;      //实时传输
  EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER \
                          UsbAsyncIsochronousTransfer; //异步实时传输
  EFI_USB_IO_GET_DEVICE_DESCRIPTOR UsbGetDeviceDescriptor; //获取设备描述符
  EFI_USB_IO_GET_CONFIG_DESCRIPTOR UsbGetConfigDescriptor; //获取配置描述符
  EFI_USB_IO_GET_INTERFACE_DESCRIPTOR \
                        UsbGetInterfaceDescriptor;               //获取接口描述符
EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR UsbGetEndpointDescriptor;
//获取端点描述符
  EFI_USB_IO_GET_STRING_DESCRIPTOR UsbGetStringDescriptor;//获取字符串描述符
  EFI_USB_IO_GET_SUPPORTED_LANGUAGES UsbGetSupportedLanguages;//获取支持语言
  EFI_USB_IO_PORT_RESET UsbPortReset;                        //重启USB控制器
} EFI_USB_IO_PROTOCOL;

对照之前介绍过的USB协议的知识,很容易理解EFI_USB_IO_PROTOCOL所提供的各类接口函数。下面主要介绍下常用的两个接口函数,UsbGetDeviceDescriptor()和UsbControlTransfer(),其他接口函数的说明,请查询UEFI Spec。

继续阅读“UEFI开发探索87- YIE002USB开发板(10 UEFI对USB的支持2)”

75 total views, no views today

UEFI开发探索86- YIE002USB开发板(09 UEFI对USB的支持1)

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

通过前面几篇博客,我们制作了具备通信能力的USB HID设备。使用之前写的Windows下的测试工具,设备工作得很好。

同样的,UEFI环境下,也可以编写上位机程序,访问USB HID设备。本篇主要介绍UEFI对USB的支持,包括UEFI的USB驱动架构和提供的USB Protocol。

1 UEFI下的USB驱动协议架构

在UEFI系统中,包含USB主控制器驱动、USB总线驱动和USB设备驱动,它们共同工作构建了UEFI平台的USB驱动协议栈。USB驱动协议栈的模型如图1所示,图中演示了USB驱动的关系和使用的Protocol。

图1 UEFI中的USB驱动协议栈

平台硬件的PCI总线上,提供了一个单独的USB控制器。PCI总线驱动为USB主控制器句柄安装Protocol,包括EFI_DEVICE_PATH_PROTOCOL和EFI_PCI_IO_PROTOCOL。而USB主控制器则使用EFI_PCI_IO_PROTOCOL,在其句柄上安装EFI_USB2_HC_PROTOCOL。

继续阅读“UEFI开发探索86- YIE002USB开发板(09 UEFI对USB的支持1)”

58 total views, no views today

UEFI开发探索85- YIE002USB开发板(08 制作HID设备)

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

在介绍完所有背景知识后,终于可以进入实质的嵌入式编程了。

本篇拟使用YIE002开发板,制作一个USB HID设备,支持三种通信方式,以对应UEFI开发探索73和74所讨论的三种上位机通信。

这个系列的博客,主要还是偏向UEFI编程的探索,对于嵌入式的编程,不想讨论过多。对于YIE002的嵌入式开发,请移步我另外一个专栏“嵌入式开发”,在其中我开了一个新坑,用来探索YIE002的编程。

1 YIE002-STM32的USB编程

这款开发板的主芯片是STM32F103C8T6,是我出差最常带的版型。本篇所写的代码,适用于所有F1系列作为主芯片的开发板,比如正点原子的战舰开发板。

从意法的官方资料可知,STM32 MCU有如下USB IP:

  1. USB IP 可作为全速USB设备,存在于STM32F102、STM32F103;
  2. USB+ IP 可作为全速USB设备,存在于STM32F0x2;
  3. FS OTG IP 可作为全速和低速USB主机、全速USB设备,存在于STM32F105、STM32F107、STM32F2、STM32F4;
  4. HS OTG IP 可作为高速、全速和低速USB主机,可作为高速和全速USB设备,存在于STM32F2、STM32F4。

官方也提供了不同的USB库,以适应开发需求。比如针对USB IP和USB+ IP,提供的库如图1所示。

图1 USB(+) IP对应的USB库
继续阅读“UEFI开发探索85- YIE002USB开发板(08 制作HID设备)”

51 total views, no views today

UEFI开发探索84- YIE002USB开发板(07 制作HID设备)

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

在之前的博客中,曾经谈到制作USB HID需要掌握的背景知识。包括USB软件架构、USB描述符和USB命令。前两个已经讨论过了,本篇介绍USB命令。

1 USB命令(USB Device Request)

USB规范定义了设备请求(USB Device Request),以更好地完成USB主机对总线上所有USB设备的统一控制。此设备请求由USB主机发往USB设备,为方便理解USB主机和设备间的主从关系,后续行文中一律称为“USB命令”。

USB命令包括USB标准命令、类命令和厂商命令。这些命令的格式都是相同的,如表1所示。

表1 USB命令的结构

偏移字段 长度数值描述
0  bmRequesType1位图D7:数据的传输方向
  0=主机->设备
  1=设备->主机
D6…5:命令的类型
 0=标准命令 1=类命令
 2=厂商命令 3=保留
D4…0:接收对象
 0=设备 1=接口 2=端点
 3=其他  4…31=保留
1  bRequest1命令的序号
2  wValue2根据不同的命令,含义也不同
4  wIndex2索引或偏移根据不同的命令,含义不同,主要用于传送索引或者偏移
6  wLength2如果有数据阶段,此字段为数据的字节数

标准命令是每种USB设备都要支持的,类命令则与USB设备所述类有关,比如USB HID设备有HID类特有的命令,如Get_Report、SetReport等。

继续阅读“UEFI开发探索84- YIE002USB开发板(07 制作HID设备)”

53 total views, no views today

UEFI开发探索83- YIE002USB开发板(06 制作HID设备)

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

我们所要开发用来通信的USB设备,是HID类设备。HID(Human Interface Devices)为人机接口设备,是USB规范中最早提出并支持的一种设备类。我们日常使用的键盘、鼠标等,都属于HID设备,这是一种使用非常广泛的USB设备。

USB规范中,HID类设备的规范为Device Definiton for Human Interface Devices,每个HID设备都必须符合该规范中对描述符、传输类型等的定义。另外,USB-IF还提供了HID的用例规范,名为HID Usage Tables,定义了HID设备和USB主机之间通信的HID数据。所有的 HID 传输都是使用默认控制管道或是一个中断管道, HID 设备必须有一个中断输入端点来传送数据到主机,中断输出端点则不是必需的。

HID设备的标准描述符同样遵循上一篇所介绍的内容,也即拥有各种标准描述符。对于HID设备,其设备描述符的类代码、子类代码和协议代码都需要设置为0;接口描述符的类代码设为0x03,子类代码为0或者0x01,协议码为0、0x01或0x02。

当然,作为类设备,HID也有自己的描述符,也即人机接口类描述符,本篇介绍这些内容。

HID设备支持3种类描述符:HID描述符、报告描述符和物理描述符。一个USB设备只能包含一个HID描述符,可以支持多个报告描述符,而物理描述符是可选的。在本章的示例中,只用到了HID描述符和报告描述符,没有使用物理描述符,一般的HID设备也不使用该描述符,就不再进行介绍了。

继续阅读“UEFI开发探索83- YIE002USB开发板(06 制作HID设备)”

47 total views, no views today

UEFI开发探索82- YIE002USB开发板(05 制作HID设备)

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

从软件的角度,制作USB HID设备,需要理解的知识包括几大块:
1) USB协议的基本架构和软件架构;
2) USB描述符,包括标准描述符和类描述符;
3) USB命令,包括标准命令和类命令。

当然,如果能从字节序上(比如USB包的构成)了解USB通信的过程,对理解整个USB协议的构成也很有好处。但在编程中,不需要理解到这个地步。大部分介绍USB协议的书籍,以及USB规范中,都很详细地描述了这些过程,非常建议读一读。

在前一篇中,已经简要地概述了USB协议的基本架构和软件架构。本篇主要介绍USB描述符中的标准描述符,这是所有USB设备都要支持的描述符。

1 USB描述符概述

为了方便USB主机对USB设备进行管理,USB-IF对USB设备的功能采用了分层结构,包括设备层、配置层、接口层和端点层。图1给出了一个复合设备的例子,展示了USB设备的分层结构。

图1 USB设备的功能分层结构

这四层的作用分别为:

  1. 设备层。说明USB设备的主要类型特征(如设备类别、接口、端点等属性),保障设备枚举过程的正常进行。
  2. 配置层。选择不同的失败配置满足USB主机对设备功能的选择,可选择复式的设备接口功能,如图1展示的选择鼠标、键盘和游戏杆的复合功能。
  3. 接口层。将具体功能分类,不同的功能对用不同的操作方式。
  4. 端点层。针对特定的设备功能,选择不同的端点,提供不同的数据管道,与USB主机进行数据通讯。
继续阅读“UEFI开发探索82- YIE002USB开发板(05 制作HID设备)”

31 total views, 1 views today

UEFI开发探索81- YIE002USB开发板(04 制作HID设备)

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

YIE002开发板上的开发,停滞了有一段时间了,这几天重新开始编写。

在最早编写的《UEFI编程实践》的书稿中,我是使用正点原子的探索者F4来制作HID设备的。感觉在自己的书中,使用其他家的开发板和代码,总是觉得有点不对。另外,在其代码上进行改造开发,存在版权的问题。

当然,最主要的,我也希望能有一个容易携带的开发板,方便我回家、或者出差的时候使用。于是才构建了这么一个机会,取名为YIE002。YIE中文含义为“易也”,来自于好友张佩的博客网站YIIEE,同音于中文“耶”和英文“yeah”。该是来自于程序员解决BUG、完成任务时,不由自主发出的欢呼声。

YIE002开发板的开篇中,描述了USB HID通信架构,包含USB HID的设备和上位机程序编写。上位机包括Windows系统、Linux系统和UEFI系统。之前用来两篇,介绍了如何在Windows系统下进行上位机编写,并开发了一个方便使用的调试工具。从本篇开始,介绍如何使用开发板制作USB HID设备,并使之支持三种通信方式。

从我的博客编写规划来说,YIE002的开发,到现在为止,都还没有进入实质的UEFI开发。主要原因在于,USB协议比较复杂。目前的开发,主要关注的是HID类协议,所需要了解的背景知识也非常庞杂。

在没有掌握USB协议相关的知识前,去读UEFI中关于USB的Protocol,会满头雾水,无法理解的。

因此,我觉得还是有必要通过学习制作USB HID设备,用几篇博客的篇幅,大致了解了USB协议的框架和编程方法,才能深入理解UEFI下USB设备的访问方法。

1 USB规范简介

通用串行总线(Universal Serial Bus,简称USB)由Intel、IBM、微软等计算机和通信公司,于1995年联合制定,解决旧有接口的问题,以适应当时计算机的飞速发展。作为一种高速串行总线,其极高的传输速度可以满足高速数据传输的应用环境要求。并且由于它供电简单、支持热插拔、扩展端口简单以及传输方式多样化等特点,目前广泛应用于各种计算机、手机等电子设备中。

相比于RS-232、PS/2等传统接口,USB最突出的特点是,其扩展性极强。RS-232等传统接口,一个预留接口只能用来连接一个相关设备,当需要扩展时,必须占用大量的计算机内部资源(如系统I/O口、中断向量和总线地址等)。而一个USB口,可以通过USB集线器,连接127个USB设备。USB简便的外设连接方式,以及优良的数据传输功能,为计算机外设接口带来了革命性的变化。

USB标准规范包括USB1.0、USB1.1、USB2.0、USB3.0,以及2019年9月发布的USB4TM规范。如表1所示,从推出时间、传输速率等方面,对USB规范的各版本进行了描述。

表1 USB规范各版本信息

USB版本最大传输速率名称推出时间
USB1.01.5Mbps低速(Low-Speed)1996年1月
USB2.0480Mbps高速(High-Speed)2000年4月
USB3.0(USB3.2 Gen 1)5Gbps超高速(Super-Speed)2008年11月
USB3.1(USB3.2 Gen 2)10Gbps超高速(Super-Speed 10Gbps)2013年12月
USB3.2(USB3.2 Gen 2×2)20Gbps超高速(Super-Speed 20Gbps)2017年9月
USB4TM (USB4 Gen 2×2)20GbpsUSB4TM 20Gbps2019年9月
USB4TM(USB4 Gen 3×2)40GbpsUSB4TM 40Gbps2019年9月
继续阅读“UEFI开发探索81- YIE002USB开发板(04 制作HID设备)”

33 total views, no views today

YIE002开发探索01-起篇

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

YIE002开发板,是我在撰写UEFI开发探索系列博客,以及编写《UEFI编程实践》的时候,做的一款开发板。

在UEFI下访问USB HID设备,需要一个自制的USB HID设备。最初的时候,我是使用了正点原子的探索者F4的板子,做了一个需要的设备。那个板子很大,在频繁带着它往返家和公司的过程中,终于厌倦了。想着是不是能做个方便携带、可以直接通过USB取电的小开发板,这就是YIE002开发板的来源。

我的需求,本来是只想做个USB HID设备,然后开发个Windows/Linux的上位机程序,以及UEFI下的上位机程序。在定义YIE002的时候,只提出了USB接口和LED灯的要求。将这个想法告诉了做硬件的朋友,他把按键、RS232串口、485串口和TTL串口都加上了,做成了一个不错的小型开发板。

这个过程,我在UEFI开发探索的博客中也曾经说过。既然拿到了这个资源相对丰富的小开发板,我就萌发了再开一个“嵌入式开发”的专栏,按照自己的设想,把一直以来这方面的开发,做个整理。

1 开发板构思

如图1所示,是目前所构思的YIE002的结构图。

图1 YIE002结构图

主要包含以下硬件资源:

4个LED灯和1个电源显示灯;
3个按键;
三类 串口,包括RS232、485和TTL;
USB 全速设备。

当前我在使用的YIE002开发板,其主芯片是STM32F103C8T6。以前曾使用过这个芯片,开发过一些公司的项目,相对比较熟悉。

继续阅读“YIE002开发探索01-起篇”

54 total views, no views today

UEFI开发探索80- YIE001PCIe开发板(终篇 移植杂谈)

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

粗略地数了数,在博客中起码开发了近50个各类UEFI的演示程序。从理论上来说,大部分的代码,实际上都可以移植到YIE001开发板的Option ROM中。

只不过,YIE001所用的Ch366芯片,只支持窗口容量为32K的程序文件(当然,可以通过CH366的I2C两线串口进行扩展)。在这种情况下,对代码的编写设置了一定的限制。

本篇将以《UEFI编程实践》第6章的示例MyGuiFrame为蓝本,将其移植到YIE001的Option ROM框架代码中。此示例在仓库https://gitee.com/luobing4365/uefi-practical-programming.git的/ RobinPkg\Applications\MyGuiFrame下。(目前仍旧在整理中,还没有上传到仓库中,by robin,20210215)

1 Option ROM开发注意点

开发板YIE001主要用来进行Option ROM的开发,由于其本身所用的PCIE芯片CH366的限制,以及UEFI下Option ROM的本身限制,编写代码中还是有不少需要注意的地方。从我的角度出发,有以下点需要注意。

1) 减少生成文件的尺寸

毕竟YIE001的窗口容量只有32K,能够容纳的代码量有限。而且由于代码是用C语言编写的,很难精确地计算生成后文件的大小,必须要注意代码的大小。

因此,第一个规则是尽量使用EDK2提供的库函数。不要使用外部库,比如StdLib库等所提供的函数。使用封装过的库函数,会导致生成文件增大。在EDK2本身提供的库函数中,对内存处理、字符串处理等常用的函数,都有提供,尽量使用这些函数就行。

开发中,最占用空间的是图像、汉字字模等这些资源。一般来说,应该尽可能使用图形函数自己绘制图像,尽量少使用标准的图像进行显示。第二条规则是图形界面尽量简单,汉字库应该采用小字库的技术,也即用哪些汉字,就提取这些汉字的字库。

在之前的博客中,针对汉字的显示,以及图形和图像的显示,已经花了比较多的篇幅进行描述,可以去查看相应的篇章。

当然,也可以用一些无损压缩算法,对资源进行压缩。不过,个人认为在32K的空间内去压缩,也很难容纳较大的文件,有兴趣的技术同好可以试一下。

继续阅读“UEFI开发探索80- YIE001PCIe开发板(终篇 移植杂谈)”

272 total views, no views today

UEFI开发探索79- YIE001PCIe开发板(12 贪吃蛇)

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

上一篇开发的贪吃蛇,除了使用了启动服务所提供的键盘服务函数和延时函数外,主要使用了GraphicsOutput Protocol。

这使得代码无需进行修改,能很容易地移植到Option ROM的框架代码中。

本篇比较短,主要是介绍如何将UEFI应用Snake移植到YIE001的OpROM框架中。

移植的步骤如下。

1 代码整理

上一篇的示例工程Snake,实际上是在以前的RngEvent的示例上进行修改的。所需要的函数,仍旧是RngEvent中使用过的。

在Option ROM的框架示例中,新建C文件GreedSnake.c,把Snake中与贪吃蛇相关的函数全部拷贝进去。函数的功能在上一篇中都介绍了,包括:

VOID CreateMap(VOID);
VOID SnakeElement(UINT32 x,UINT32 y,UINT8 ColorIndex);
VOID InitSnake(VOID);
UINT8 BiteSelf();
VOID RandomFood(VOID);
UINT8 NotCrossWall(VOID);
UINT8 SnakeMove(VOID);
VOID GameRun(VOID);
VOID EndGame(VOID);
继续阅读“UEFI开发探索79- YIE001PCIe开发板(12 贪吃蛇)”

172 total views, no views today

UEFI开发探索78- YIE001PCIe开发板(11 贪吃蛇)

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

是时候实现个有趣的项目了,我选择在UEFI下实现贪吃蛇的游戏。

在Option ROM上直接实现,会很难调试。因此,我首先实现了贪吃蛇的UEFI应用。调试成功后,再将其移植到YIE001上。

1 贪吃蛇框架设计

考虑到代码最终是要移植到YIE001上,我尽量减少所用到的Protocol。主要是在平常开发中发现,不同的主机,在运行Option ROM时能支持的Protocol不大一致。比如在我目前测试用的平台上,就不支持SimplePointer的Protocol(鼠标)。

为简化对程序的思考,我们设计的贪吃蛇由一个个的矩形块组成。主要需要解决的问题包括:
(1) 地图的设计;
(2) 贪吃蛇的数据结构设计;
(3) 如何判断蛇撞墙;
(4) 如何判断蛇咬自身了;
(5) 随机出现蛇吃的食物。

实际上,解决了问题1和2,基本上后续的几个问题都迎刃而解了。

我们把地图、蛇和食物设计成如图1所示:

图1 贪吃蛇概念图
继续阅读“UEFI开发探索78- YIE001PCIe开发板(11 贪吃蛇)”

164 total views, no views today

UEFI开发探索77- YIE001PCIe开发板(10 拨动开关及显示)

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

YIE001上有两个拨动开关,可通过对应的寄存器位得知它们的状态,以实现交互控制。这篇尝试将按键获取,以及图形显示的编码。

1 获取拨动开关状态

UEFI开发探索第75篇中,列出了YIE001开发板的硬件资源。板子上提供了两个拨动开关,分别对应CH366的GPI1和GPI2。

对照CH366的芯片手册,定义其相关的宏定义:

#define CH366GPIR 0x02

#define KEY1 1   //GPI1 -- GPIR(IO基地址+02h) bit 1
#define KEY2 2   //GPI2 -- GPIR(IO基地址+02h) bit 2

在开发板YIE001上,拨动开关拨下(也即靠近PCIE槽的方向),对应的寄存器位值为0;拨上后对应的寄存器值为1。实现代码如下:

/**
  获取开发板YIE001上拨动开关的状态.
  
  @param  IoBaseAddress     YIE001上PCIE芯片的基地址
  @param  KeyNum            拨动开关的标识,Key1和Key2
  @retval 1           拨下(靠近PCIE插槽)
          0           拨上    
**/
UINT8 GetYIE001Key(UINT16 IoBaseAddress,UINT8 KeyNum)
{
  UINT8 regValue=0;

  regValue = IoRead8(MyIoBaseAddr+CH366GPIR);   //GPIR
  if(KeyNum == KEY1)
    regValue &=0x02;
  if(KeyNum == KEY2)
    regValue &=0x04;
  if(regValue)
    return 1;
  else
    return 0;
}
继续阅读“UEFI开发探索77- YIE001PCIe开发板(10 拨动开关及显示)”

175 total views, no views today

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实例,以及共用的一些函数
继续阅读“UEFI开发探索76- YIE001PCIe开发板(09 界面和键盘控制)”

172 total views, no views today