UEFI开发探索20 – 串口通信
(请保留-> 作者: 罗冰)串口可能是生命力最强的接口标准了,从1980年到现在,仍旧在发挥巨大的作用。特别是工业环境下,可说是王者标准了。前几年开发过网络转串口,我惊奇的发现很多金融场合也在用串口。扯远了,回到UEFI下的串口通信。1 Shell命令查看串口我的开发环境仍旧是虚拟机winxp+UDK2010,一直没有时间去搭建UDK2018。UEFI Shell中有个命...
(请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365)
串口可能是生命力最强的接口标准了,从1980年到现在,仍旧在发挥巨大的作用。特别是工业环境下,可说是王者标准了。
前几年开发过网络转串口,我惊奇的发现很多金融场合也在用串口。
扯远了,回到UEFI下的串口通信。
1 Shell命令查看串口
我的开发环境仍旧是虚拟机winxp+UDK2010,一直没有时间去搭建UDK2018。UEFI Shell中有个命令Sermode,可以查看以及设置串口参数。
图1 TianoCore模拟环境中枚举串口
设备管理器中有两个串口,TianoCore的模拟环境中也列出了两个串口。下面的问题是,如何与虚拟机中的串口通信?
2 与虚拟机中的串口通信
有段时间我学习使用windbg,用来调试驱动代码。它可以配合虚拟机调试OS的执行情况,或者进行内核态的源代码调试。
Windbg使用的是命名管道来与虚拟机通信,这给了我一定的启示。我开发了一个小工具,用来读写命名管道。虚拟机常用的管道名称是,\\.\pipe\com_1,如下图所示。
图2 宿主机与虚拟机的串口通信
这样就把虚拟机和宿主机的串口通信通道打通了。当然,也可以直接用两台计算机用串口进行通信,不过现在有串口的机器都比较少,比较难找。
3 UEFI下的串口函数
串口的协议比较简单,网上也有大把的资料说明。没有必要一一解释其原理,我主要还是关注UEFI下操作串口的函数。
UEFI Spec的12.8 Serial I/O protocol中很详细的描述了相关的串口函数。
图3 Serial IO Protocol (UEFI Spec 2.8 page 466)
按照Spec的说明,编写了读写的函数,以及测试用的函数:
EFI_STATUS DisplayAllSerialMode(void);
EFI_STATUS DisplaySerialMode(void);
EFI_STATUS SendDataToSerial(UINTN length,VOID *buffer);
EFI_STATUS GetDataFromSerial(UINTN *length,VOID *buffer);
EFI_STATUS SetSerialPortAttrib(UINT64 BaudRate, EFI_PARITY_TYPE Parity,UINT8 DataBits, EFI_STOP_BITS_TYPE StopBits);
第一个函数把系统上的所有串口信息打印出来,类似于Sermode的枚举功能。剩余的几个函数只使用第一个找到的串口,对其进行读写。
这种操作方式让我有点不习惯。以前编写串口程序,不管是windows app还是单片机,习惯都是先打开串口设备。而在UEFI下,在枚举Handle的过程中,每个Handle对应的就是串口设备。
把数据发向串口很容易,直接用Write函数就行了。读串口我没有想到什么办法,UEFI不提供中断,我也没有找到串口数据来之后,会触发什么事件。
在测试过程中,从Host OS发过来的数据,偶尔会打印出来。代码还是有问题。
4 编译运行
运行的结果如图所示。
图4 程序运行结果
程序测试了三个功能:
- 打印当前所有串口设备参数,很明显,与Sermode的信息是一致的;
- 向串口发送测试字符串。字符串被写的调试工具抓到了;
- 读取从串口发过来的信息。失败!
我写串口的目的是希望有一个打印的调试手段,方便在图形模式下调试程序。从这个角度来说,目前的程序代码已经满足要求了。
不过,找不到好的机制来读取串口数据,总归不爽。
希望了解这方面的大牛可以指点一二^_^
5 One more thing
在写这个程序的过程中,发现一个现象。所有TianoCore模拟环境下,显示在屏幕上的数据都会传送到我写的命名管道调试工具中。
而通过命名管道发送的数据,也会输入到Shell下。我所写的调试工具,其发送编辑框重载了Enter键,所以可以连Enter键也一起发过去。以Sermode为例:
图5 用命名管道调试工具发送shell命令
通过调试工具写入sermode(回车),点击“发送”按钮,Shell直接就执行了此命令。
另外一个让我感兴趣的是,通过命名管道调试工具发送的数据能很好的被TianoCore模拟环境收到。它应该是通过串口接收的,这通过上述的实验已经证明了。
也就是说,UEFI下有很好的机制来接收串口数据,只是我不知道而已。
我觉得可以把这个调试工具好好改造一下,成为一个方便的UEFI开发辅助工具。所以我把源代码也一起放上去了,和本篇博客的代码放在同一文件夹下。此工具使用VS2015,在Win10下开发。
Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目代码位于:/13 SerialPort-PipeTool下。
/luo2:UEFI的串口调试代码;
/PipeTool.exe: 命名管道调试工具的执行文件,32位程序,兼容winxp—win10系列系统;
/pipetool:PipeTool的源代码,VS2015编译。
更多推荐
所有评论(0)