UEFI开发探索102 – ACPI探究01(UEFI配置表)

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

最近有项工作,是修改ACPI表。问题本身并不复杂,但是由于代码需要移植到Option ROM上,遇到不少奇怪的现象。因此,花了不少时间,对ACPI进行研究。

任务是完成了,我的好奇心又被勾起来了。准备发挥“格物致知”的信念,把我认为的ACPI各方面的知识,好好地捋一捋。

1 大致规划

这次的ACPI探索的博客,估计会有不少篇章。准备从三个角度来了解ACPI的知识,包括UEFI的角度、操作系统的角度和ACPI规范的角度。

内容的编排不会那么规范,想到哪里就写到哪里,大致的计划如下:

1) UEFI配置表中的ACPI;
2) ACPI规范简介;
3) 使用UEFI Protocol分析AML Code;
4) ShellPkg中的acpiview
5) EDK2中对ACPI的实现
6) 独立于操作系统的ACPICA
7) Windows/Linux下使用ACPI分析工具
8) 其他ACPI相关课题

ACPI作为独立于操作系统的一套底层规范,在现代操作系统中发挥了巨大的作用。目前其规范已经移交给UEFI官网维护,可以在UEFI.org上下载各版本的规范文档。

本篇先借用好友lab-z博客中的方法,通过UEFI配置表,找到ACPI相关的各种表格,博客地址如下:http://www.lab-z.com/studsdt/

继续阅读“UEFI开发探索102 – ACPI探究01(UEFI配置表)”

5,762 total views, 9 views today

UEFI开发探索101 – PCD探究

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

从《UEFI编程实践》出版后,一系列的事情接踵而来,终于在今天,算是告一段落了。

这段时间,有不少机会和业内人员讨论UEFI和BIOS。反思自己对这个领域的理解,深感自己理论的不足。

看过《UEFI编程实践》的网友,应该能了解,书中对于概念的理论部分,阐述得相对较少。我一般都是遵循“提出问题-介绍UEFI相关知识-提供实例”的框架,围绕某一课题进行研究。

其中的一个原因,是因为我本来就是奔着实践为目的,将平时开发中所遇到的课题逐渐展开讨论。另一个原因,是没有深入到EDK2的具体实现去。

因此,从UEFI开发探索第101篇开始,我想逐渐转向对EDK2的代码研究了。如之前研究PCI Option ROM开发一样,这次设立的目标包括:

  1. 对OvmfPkg源代码进行研究,搞清楚固件架构、编译过程、各阶段代码实现等;
  2. 了解Qemu怎么使用固件启动的,以及如何启动操作系统;
  3. 了解Ovmf固件如何提供操作系统所需要的各种Table、Runtime Services,甚至SMI Handler等。搞清楚一个UEFI操作系统如何与BIOS结合的。

我了解这是一个不小的目标,会遇到不少的困难,兴趣所在,倒不是特别畏惧。本来的想法,是在树莓派上进行实验,在lab-z(博客:https://www.lab-z.com/)的建议下,觉得OvmfPkg做实验更方便些。

主题确定,后续想到哪里不熟就补足哪里的知识。嗯,先从EDK2全局配置的关键核心-PCD开始研究。

1 PCD简介

Platform Configuration Database(PCD)是EDK2用来进行全局配置的机制,可在代码复用、模块化方面发挥巨大作用。

PCD是把代码里面的可配置选项抽取出来,在platform需要修改的时候,可以不用去修改源代码。其参数的配置,可以在编译过程中、运行时中都可以配置,甚至在二进制文件中也可以配置。

这种设计方式就比较让人着迷,这也使得定制化更为容易,代码更容易维护。

早期我一直以为PCD如同C/C++中的宏,用来提取公用代码,这是错误的。它提供的功能更为广泛,也更复杂。

首先直观地看下平常程序中用到的PCD,以前几篇中的Diskdump工程为例,使用如下命令编译,提取出其所用的PCD信息:

C:\vUDK2018\edk2>build -Y PCD -y pcd.log -p RobinPkg\RobinPkg.dsc -m RobinPkg\Applications\Diskdump\Diskdump.inf -a IA32

输出的信息,存在了pcd.log中。查看下log信息:

图1 Diskdump中用到的PCD
继续阅读“UEFI开发探索101 – PCD探究”

9,095 total views, 15 views today

国产单片机替代-CH32替代STM32

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

随着芯片价格疯涨,项目的不可控性越来越大。特别是价格方面,达到了无法想象的地步了。

以之前《UEFI编程实践》所用的YIE002开发板为例,当时选择使用STM32F103C8T6,也是因为它是一款性价比较高的MCU。当然,也有我之前用这款CPU做过几个项目,比较熟悉的原因在。

按我的记忆,之前项目中所用的STM32F103C8T6,价格在9元左右;而现在到立创商城上去查,单片价格到了惊人的109元!十几倍的涨幅,哪个项目还敢用它?

因此,大部分公司,都在准备各种替代方案。

我们也一样,预备使用CH32F103C8T6替代STM32F103C8T6。这两种芯片引脚兼容,内部的资源差不多,理论上代码移植也比较方便。

我就是这么想的,然后就被打脸了。

最大的原因在于,厂家提供的资料太少了!编程相关的CH32F103应用手册,只有短短的31页。我想看的USB设备控制器的寄存器细节,甚至都没有。想想STM32丰富的应用资料、例程和各种视频,感觉从新手级难度到了骨灰级难度了。

不过,再想想CH32这友好的价格,也就释然了。

周末两天,把之前的USB HID通信,在CH32F103C8T6上实现了,估计不久能很快地应用到项目中去。

预计也也有不少网友有类似的需求,我把探索的过程记录下来。

1 固件下载

CH32F103的芯片,支持WCH-Link或者其他SW仿真工具下载,也支持使用WCHISPTool通过USB和串口下载。考虑到后续开发的时候需要调试,我使用的是WCH-Link进行下载。

如图1所示,给出了WCH-Link的实物图(摘自《WCH-Link使用说明-V1.3》)。

图1 WCH-Link实物

由于我的目标是使用它下载程序到CH32F103C8T6中,只需要使用ARM模式就行了,不需要关注RISC-V模式。

继续阅读“国产单片机替代-CH32替代STM32”

2,684 total views, 3 views today

UEFI开发探索100 – 《UEFI编程实践》发布啦

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

经过四百多天的奋斗,新书终于上市了(京东官方书店 https://item.jd.com/13406126.html):

每天晚上9点,在安排好孩子睡觉后,就坐在书桌前敲打键盘;每个周末,都逼迫自己进入代码和Spec的海洋,一句句调试,一点点查询。

看到书稿成型的那一刻,感觉一切的付出都值得了!

封面以红色色调为主,占据视觉中心的芯片,周边的器件和数字0、1,表明这是本计算机底层实践的书。在各种器件间专心走着的漫画小人,让我想起每个专心调试的日日夜夜。我很喜欢这个封面的感觉,工程师的文化感扑面而来。

书中提供了33个UEFI应用和驱动示例,以及多个用来配合实验的Windows程序、Linux程序和嵌入式程序。涵盖了构建程序架构、调试方法、构建GUI、各种总线外设的访问、网络应用开发、UEFI驱动和Option ROM开发等内容,特别介绍了国产计算机下的UEFI开发,是偏实战操作的技术性书籍。

继续阅读“UEFI开发探索100 – 《UEFI编程实践》发布啦”

3,504 total views, 5 views today

YIE002开发探索-Gitee代码仓库说明

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

周末花了点时间,把YIE002的代码整理了一下,上传到了Gitee仓库中。

这次整理的主要是和之前博客对应的代码,也就是使用STM32 Cube MX开发的几个项目,用来练手的Legacy Library代码没有上传。

仓库地址为:
YIE002开发探索 https://gitee.com/luobing4365/yie002-explorer

下图为代码仓库的截图:

图1 YIE002开发探索仓库截图

如仓库中的介绍,YIE002是我编写《UEFI编程实践》第9章时,用来做实验的设备。

继续阅读“YIE002开发探索-Gitee代码仓库说明”

2,120 total views, 2 views today

UEFI开发探索99 – UEFI Shell下截屏工具

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

最近有些程序,只能在实际机器的UEFI Shell下进行测试。比如上一篇的diskdump程序,在模拟器下是没法运行的。

模拟器上运行,可以直接使用各种截屏软件截图,图像还是比较清晰的。在实际机器上运行,只能使用手机录像或者拍照。自己的拍照技术有多糟糕,我还是很清楚的。所拍出的照片,只能勉强看清楚程序的运行情况。因此,后期还得在电脑上用PS处理一下。

这种情况遇到多了,总得想个办法解决一下。

今天早上上班的路上,冒出一个想法,何不写个UEFI Shell下截屏的软件?

需要解决的问题不多,主要包括以下几个:
1) 截屏程序要能常驻内存,以允许其他程序在运行的时候唤出;
2) 设置键盘热键,可以随时唤出后台运行的截屏程序;
3) 将整个屏幕以bmp图像的格式,存储在硬盘或者U盘上。

有点类似以前DOS系统下的常驻内存程序TSR一样,早期的DOS中有大量这样的程序存在。

想了一下实现方法,觉得应该可以在UEFI下把这个截屏软件实现出来。常驻内存应该可以通过UEFI驱动的方式实现,屏幕获取和存取BMP图像比较简单,之前写的图像处理代码稍微修改就可以了。

不过,越深入思考,越觉得在哪看过这样的想法。

查了下平常的开发日志,果然,微软的Github库中,提供了同样功能的软件。很久以前我就看过了,只是一直没有去编译测试。

这个UEFI程序存在于微软在Github上的mu_plus库中,库的地址为:https://github.com/microsoft/mu_plus.git。

截图软件位于mu_plus的MsGraphicsPkg中,名称为PrintScreenLogger。

既然已经有了,就没必要再写了,本篇试着了解其实现原理,并在实际环境中测试一下。

1 PrintScreenLogger的代码结构

从整体设计上来看,与想象的差不多。PrintScreenLogger采用了UEFI驱动的形式,让程序可以常驻内存。

其代码结构如图1所示。

图1 PrintScreenLogger程序结构图
继续阅读“UEFI开发探索99 – UEFI Shell下截屏工具”

1,927 total views, 1 views today

UEFI开发探索98 – 硬盘访问Diskdump

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

之前在CSDN上建了一个专栏,名字为汇编语言探索,准备聊一些用汇编写的小项目。大概写了十几篇关于Foxdisk运行原理的文章,后面还会不定期的写写,特别是最近看到一个俄罗斯程序员用FASM写的KolibriOS,贼有意思了,找时间读一读。

Foxdisk本来是我为自己写的一个多操作系统引导的软件,类似于Grub。核心点在于,在Foxdisk内可以将硬盘分成若干区域,每个区域装一个操作系统,各操作系统间可以通过共享的分区分享数据。而提供的图形界面,比单调的Grub让我舒服些。

这是一个很好的想法,能满足我使用多个操作系统的开发习惯。Foxdisk开发了3代,前两代是纯粹用汇编语言写的,3.0则使用了C语言嵌汇编。再然后,我迷上了UEFI,对于在Legacy BIOS下开发的Foxdisk,就这么抛弃了。

Foxdisk 3.0中,内置了对硬盘分区的功能(相当于Fdisk或spfdisk之类的工具)。实际上,Foxdisk大部分的工作,都是在和硬盘打交道。

进入UEFI后,一直不怎么想去研究硬盘访问。总觉得UEFI本身已经将硬盘访问封装得很好了,没什么必要再去开发分区、格式化之类的软件了。

刚好在近期的项目中,需要在Option ROM中查看某几个扇区的数据。为了比对Option ROM的代码,需要开发一个UEFI小程序,实现类似功能。

1 UEFI的存储介质访问栈

UEFI规范中提供了大量的存储介质Protocol(Media Protocol),甚至包括内存虚拟盘(RAM Disk)都支持了。

Legacy BIOS下是通过Int 0x13进行硬盘访问的,由寄存器AH标识各种功能号,供程序员调用。习惯了这种思维,再看UEFI的访问方式,总是有点别扭。

首先需要找出类似功能的访问接口,UEFI提供了从硬盘协议层的Protocol,一直到文件系统的Protocol,非常完善,其架构如图1所示。

图1 UEFI的存储介质访问栈
继续阅读“UEFI开发探索98 – 硬盘访问Diskdump”

1,675 total views, no views today

UEFI开发探索97 – EDK2模拟器搭建网络环境

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

最近一段时间,很多网友问的问题都是和网络相关的。讨论的问题大部分是关于网络环境的搭建,有些现象我也没有遇到过。

在UEFI开发探索49中,介绍过在Nt32模拟器和真实环境中搭建UEFI网络环境。当时我使用的EDK2是UDK2018的版本。

随着EDK2版本的升级,原有的NT32模拟器(使用Nt32Pkg编译)已经取消了,随之替代的是EmulatorPkg。后者提供的功能更为全面,提供了32位和64位的模拟器,之前的博客中也曾经介绍过。

因此,本篇准备用EmulatorPkg编译的模拟器重新搭建网络测试环境。之前的模拟器使用Nt32Pkg编译,所以我取名为Nt32模拟器;现在的EmulatorPkg名字太长了,为方便行文,称之为EDK2模拟器了。

1 搭建EDK2开发环境

详细的搭建过程,可以参考UEFI开发探索22和57,这里简单描述本次的搭建过程。步骤如下:

1)工具安装

安装必要的开发工具,包括Visual Studio、Python、ASL和Nasm;

2)下载代码库

使用Git将EDK2的代码和StdLib的代码下载到本地。

在C盘新建目录edk202011,使用如下命令下载:

robin@robin-PC MINGW64 /c/edk202011
$ git clone --branch stable/202011 https://gitee.com/luobing4365/edk2.git
$ git clone https://gitee.com/luobing4365/edk2-libc.git

请注意,这里下载的地址是我的私有仓库,我把github上的edk2和edk2-libc的仓库同步到我在gitee上的仓库中了,方便自己下载。

不要按照我给的命令去下载,原始的仓库为https://github.com/tianocore/edk2.git 和https://github.com/tianocore/edk2-libc.git,可以使用如下命令去下载:

$ git clone --branch stable/202011 https://github.com/tianocore/edk2.git
$ git clone https://github.com/tianocore/edk2-libc.git

当然,取决于你所在地方的网速,下载速度会很慢。建议使用同样的方法,将github上的仓库同步到gitee上,或者直接在gitee上找到同样的仓库再下载。

本篇使用的分支为stable/202011,后续的实验结果均是基于此版本得出的。

3)更新子模块

修改edk2中的.gitmodules,更子模块。

如果能使用github直接下载,可以不用修改.gitmodules,直接运行后续的更新命令就可以了。我修改的内容如下:

[submodule "CryptoPkg/Library/OpensslLib/openssl"]
	path = CryptoPkg/Library/OpensslLib/openssl
	url = https://gitee.com/luobing4365/openssl.git
[submodule "SoftFloat"]
	path = ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
	url = https://gitee.com/luobing4365/berkeley-softfloat-3.git
[submodule "UnitTestFrameworkPkg/Library/CmockaLib/cmocka"]
	path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka
	url = https://gitee.com/luobing4365/cmocka.git
[submodule "MdeModulePkg/Universal/RegularExpressionDxe/oniguruma"]
	path = MdeModulePkg/Universal/RegularExpressionDxe/oniguruma
	url = https://gitee.com/luobing4365/oniguruma.git
[submodule "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli"]
	path = MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
	url = https://gitee.com/luobing4365/brotli.git
[submodule "BaseTools/Source/C/BrotliCompress/brotli"]
	path = BaseTools/Source/C/BrotliCompress/brotli
	url = https://gitee.com/luobing4365/brotli.git
ignore = untracked

再次提醒,上述的子模块给出的地址,均是我将子模块在github上的仓库,导到gitee上的地址。可以参考我的方法,但是不要直接使用,这些都是我的私有地址,没法直接用。

具体的导入方法,可以参考UEFI开发探索57的内容。

继续阅读“UEFI开发探索97 – EDK2模拟器搭建网络环境”

2,113 total views, no views today

UEFI开发探索96 – 温度计小游戏

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

syslibforuefi中,还有几个小程序。从我的角度来看,最值得学习的是他将图像变为HII资源的方式,其他图形图像的知识,在很久以前的博客中,已经研究了很多了。

早上打开CSDN,让我吃了一惊:

图1 CSDN的评价

悄没声息地跑到了游戏领域内容榜的第2名了!

上次我就说过,我这是UEFI开发的博客啊,又不是介绍游戏开发的。这奇怪的评价,让我都不知道从哪里吐槽了。

我是不是转行去开发游戏比较好?

继续阅读“UEFI开发探索96 – 温度计小游戏”

1,529 total views, no views today

UEFI开发探索95 – 弹跳小游戏

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

昨天闲暇的时候,把Tim Lewis的迷宫游戏编译了一下,自娱自乐在UEFI下玩了一把。

奇怪的是,CSDN竟然给我发了“入选《游戏领域内容榜》第27名”,如下图:

图1 CSDN奇怪的评选

嗯,虽然从理论上来说,这篇博客也算写了个游戏,可我主要写的是UEFI程序啊。除了这篇博客的名字外,在关键字里我也没有设置“游戏”字样。

实在搞不懂CSDN的评判算法。

继续阅读“UEFI开发探索95 – 弹跳小游戏”

1,444 total views, no views today

UEFI开发探索94 – 迷宫小游戏

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

最近一直在写YIE002开发探索的博客,偶尔看看其他人写的和BIOS开发相关的博客。

经常看的博客有Tim Lewis、Vincent Zimmer等,总是能学到一些东西。

今天下班后,可能是因为最近公司的事情比较繁杂,精神有点不振。虽然计划了近期要写的嵌入式代码,可是怎么也提不起劲,开发工具都不想打开。

我无聊地翻阅着常看的几位作者的博客,Tim Lewis有个关于UEFI和C++的议题,稍微有点兴趣,就点进去看了。

他的代码放在了sourceforge上,地址为:https://sourceforge.net/projects/syslibforuefi/。下载了之后,我浏览了目录结构,发现几个有意思的程序。其中有些是可以在UEFI下玩的小游戏,看来程序员的想法很类似啊,我之前也开发了UEFI下的贪吃蛇游戏。

今天休息一下,拜读下顶级BIOS程序员写的UEFI程序。

1 Maze程序结构分析

源程序在文末给出了,可以试玩一下。

整个迷宫程序的主要实现目标包括:
1) 自动生成迷宫;
2) 通过方向键,控制角色通过迷宫。

实现的目标比较简单,从代码结构来看,主要包含如下函数,如图1所示。

图1 Maze程序架构图
继续阅读“UEFI开发探索94 – 迷宫小游戏”

1,024 total views, no views today

UEFI开发探索93 – UEFI下使用YIE002随机数发生器

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

在UEFI开发探索72中,曾经规划过YIE002的开发板计划。当时的主要目标是使用YIE002做USB HID的双向通信设备,并在Windows、Linux和UEFI下都实现上位机访问程序。

如今,这些目标都已经实现了。特别是Windows下的测试程序UsbHID,现在成为我专用的测试工具了。

当时的开发计划中,还有一项目前还没有完成,那就是让YIE002开发板提供生成随机数的功能,使得在各个系统下都能通过USB通道得到生成的随机数,包括UEFI系统。

这个目标的灵感来源于国外工程师开发的ChaosKey,是以前学习UEFI开发时,在网上搜寻资料时偶然遇到的。一个小小的产生随机数的设备(U盘大小),作者花了不少心思来制作,让我觉得很有意思。因此,在设计YIE002的时候,就预留了生成随机数的机制。

周末的时候,花了一点时间,终于把这个随机数生成器做成了。具体的过程,请见我的另外一篇博客:YIE002开发探索10-随机数生成器。

今天就来UEFI下使用下这个小设备。

1 代码编写

代码编写的过程实际非常简单,借用了UEFI开发探索88篇的工程HelloHID,稍微修改了下其中的函数,就实现了需要的功能。

将HelloHID改为RngUEFI,包括INF文件和源文件名,都修改下。然后在RobinPkg.dsc中,添加对RngUEFI工程的编译支持,就完成了框架调整。

由于YIE002随机数生成器提供了三种USB HID通信能力,可以使用任意一种方式与之通信。因此,我就直接用Feature Report通信的方式来编写代码了。

继续阅读“UEFI开发探索93 – UEFI下使用YIE002随机数发生器”

1,278 total views, 1 views today

YIE002开发探索10-随机数生成器

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】
(代码仓库地址:https://gitee.com/luobing4365/yie002-explorer
具体参考博客:YIE002开发探索-Gitee代码仓库说明)

在规划YIE002开发板的时候,其中有一个目标是,实现类似ChaosKey一样的,可以在UEFI下访问的随机数生成器。

ChaosKey是一个硬件真随机数生成器,通过USB进行通信。其主页为:https://altusmetrum.org/ChaosKey/。

STM32F2和STM32F4系列的芯片,提供了芯片内部的随机数生成器。而YIE002开发板上使用的STM32F103C8T6,并没有提供。因此,必须使用其他办法来实现目标。

1 随机数生成器构建

上一篇中,已经打通了USB HID的双向通信通道,数据可以很方便地发送给上位机了。所需要的,是产生随机数的源。

在YIE002开发板上,有些引脚是悬空的,其中的PB1可用作ADC通道9进行采样,如图1所示。

图1 YIE002的单片机引脚图
继续阅读“YIE002开发探索10-随机数生成器”

973 total views, no views today

YIE002开发探索09-USB(HID双向通信)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】
(代码仓库地址:https://gitee.com/luobing4365/yie002-explorer
具体参考博客:YIE002开发探索-Gitee代码仓库说明)

编写《UEFI编程实践》的时候,为了演示如何在UEFI下访问USB HID设备,我使用了正点原子的探索者F4开发板,做了一个双向通信的HID设备。随后考虑到版权问题,觉得还是不要放到书中较好。

毕竟书是需要出版的,而探索者F4的HID代码是在正点原子的USB代码上修改的。因此自己弄了个YIE002开发板,重新做了个HID设备。

以上的过程,在UEFI开发探索的系列博客中都写过,相关的代码也贴出过。

本篇所做的工作,是使用STM32 Cube MX重写USB代码,实现双向通信的HID设备。

1 YIE002上的USB

YIE002上使用的主芯片为STM32F103C8T6,它自带了USB,不过只能用作设备,不能作为主机使用。

USB 发展到现在已经有 USB1.0/1.1/2.0/3.0/4.0 等多个版本。目前用的最多的就是 USB1.1 (比如大部分的USB键鼠)和USB2.0、 USB3.0。实际上USB2.0也基本上接近淘汰,常见的USB设备基本都是USB3.0设备了。STM32F103 自带的 USB 符合 USB2.0 规范。

STM32F103的单片机自带USB从控制器,PC主机和单片机在传输时,是通过共享一个专用的数据缓冲区来完成的。缓冲区的大小由所用的端到数目和每个端到最大的数据分组决定,每个端点最大可使用512字节缓冲区,最多可用于16个单向或8个双向端点。

USB 模块同 PC 主机通信,根据 USB 规范实现令牌分组的检测,数据发送/接收的处理,和握手分组的处理。整个传输的格式由硬件完成,其中包括 CRC 的生成和校验。每个端点都有一个缓冲区描述块,描述该端点使用的缓冲区地址、大小和需要传输的字节数。

USB 的中断映射单元:将可能产生中断的 USB 事件映射到三个不同的 NVIC 请求线上:
1) USB 低优先级中断(通道 20):可由所有 USB 事件触发(正确传输, USB 复位等)。固件在处理中断前应当首先确定中断源;
2)USB 高优先级中断(通道 19):仅能由同步和双缓冲批量传输的正确传输事件触发,目的是保证最大的传输速率;
3)USB 唤醒中断(通道 42):由 USB 挂起模式的唤醒事件触发。

如图1所示,给出了USB设备框图。

图1 USB设备框图
继续阅读“YIE002开发探索09-USB(HID双向通信)”

1,343 total views, no views today

YIE002开发探索08-串口(485)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】
(代码仓库地址:https://gitee.com/luobing4365/yie002-explorer
具体参考博客:YIE002开发探索-Gitee代码仓库说明)

在YIE002开发探索05中,我们介绍过RS485一些基本参数。RS485通信协议由RS232协议改进而来,将物理层改为了差分信号进行传输,因此其抗干扰性强、传输距离远,比较广泛地应用于噪声干扰比较大的工业控制环境中。

1 YIE002上的RS485

RS485的电气特性与RS-232不大一样,采用两线的时候为半双工。其基本的特点包括:

1) 接口电平低,不易损坏芯片。RS485 的电气特性:逻辑“1”以两线间的电压差为+(2~6)V 表示;逻辑“0”以两线间的电压差为-(2~6)V 表示。接口信号电平比 RS232 降低了,不易损坏接口电路的芯片,且该电平与 TTL 电平兼容,可方便与 TTL 电路连接;
2) 传输速率高。 10 米时, RS485 的数据最高传输速率可达 35Mbps,在 1200m 时,传输速度可达 100Kbps;
3) 抗干扰能力强。 RS485 接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能力增强,即抗噪声干扰性好;
4) 传输距离远, 支持节点多。 RS485 总线最长可以传输 1200m 以上(速率≤100Kbps)一般最大支持 32 个节点,如果使用特制的 485 芯片,可以达到 128 个或者 256 个节点,最大的可以支持到 400 个节点。

从软件工程师的角度来看,RS485与RS232的编程几乎一样,需要关注的是其半双工的特性(因为开发板上使用的是两线),必须通过使能脚配置其为发送状态或接收状态。

如图1所示,给出了YIE002的RS485部分的线路图。

图1 YIE002的RS485
继续阅读“YIE002开发探索08-串口(485)”

955 total views, no views today

YIE002开发探索07-串口(DMA)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】
(代码仓库地址:https://gitee.com/luobing4365/yie002-explorer
具体参考博客:YIE002开发探索-Gitee代码仓库说明)

在实际应用中,单片机的CPU是最“忙”的,需要完成的任务非常多。因此,CPU资源是非常宝贵的,能够少用就尽量少用,这也能很大程度上提高系统的稳定性。

DMA(直接存储器访问)就是用来解决类似问题的。它用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输,无须CPU干预,就可以实现数据的快速移动。

我曾和朋友开发过一款DTU的产品,是使用STM32单片机和FreeRTOS构建的系统。系统中有三个串口都需要发挥作用,如果只用中断的话,CPU频繁被中断跳转,效率是很低的,根本无法满足现场的数据需求。因此,我们根据应用需求,使用DMA构建了环状的串口数据接收和发送架构,产品最终表现很好。

本篇准备尝试在新的开发方式下,实现串口的DMA数据传输。

1 STM32的DMA

DMA全称为Direct Memory Access,也即直接存储器访问。CPU完成初始化动作,传输的动作则是由DMA控制器来实现完成的。

典型的例子是移动外设的数据到内存区,这样的操作不需要处理器干预,因此可以让处理器去排程做其他工作。

DMA传输对于高效能嵌入式系统算法和网络很重要,它没有中断处理的现场保留和恢复的过程,通过硬件为内存和外部I/O设备构建直接传输数据的通道,大大提高了CPU的效率。

1.1 STM32的DMA功能

STM32 最多有 2 个 DMA 控制器(DMA2 仅存在大容量产品中), DMA1 有 7 个通道。 DMA2 有 5个通道。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁起来协调各个 DMA 请求的优先权。

STM32的DMA主要特性如下:
● 12个独立的可配置的通道(请求): DMA1有7个通道, DMA2有5个通道;
● 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置;
● 在同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推) ;
● 独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐;
● 支持循环的缓冲器管理;
● 每个通道都有3个事件标志(DMA半传输、 DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求;
● 支持存储器和存储器间的传输;
● 支持外设和存储器、存储器和外设之间的传输;
● 闪存、 SRAM、外设的SRAM、 APB1、 APB2和AHB外设均可作为访问的源和目标;
● 可编程的数据传输数目:最大为65535。

从外设(TIMx、 ADC、 SPIx、 I2Cx 和 USARTx)产生的 DMA 请求,通过逻辑或输入到DMA 控制器,这就意味着同时只能有一个请求有效。外设的 DMA 请求,可以通过设置相应的外设寄存器中的控制位,被独立地开启或关闭。

如图1,给出各外设的DMA对应通道。

图1 DMA1各通道一览
继续阅读“YIE002开发探索07-串口(DMA)”

863 total views, 1 views today