【入门指南】图解如何使用 USBTinyIsp

每一个Arduino 的玩家都应该准备一个 ISP 下载器,有了它能让你的 Uno 玩出很多花样。这里就介绍一下如何使用 USBTinyISP。本文将介绍使用这款工具的三种刷写方式:

  • 第三方软件刷写 328P BootLoader的方法
  • Arduino IDE 刷写 328P BootLoader的方法
  • Arduino IDE 刷写328P上面程序的方法

首先,你要有一个USBTinyISP烧录器。下面的是购买自淘宝的 OCROBOT 出品,价格是 45元,属于较贵的。
image001

这款需要安装驱动才能工作,淘宝很多出售的号称不需要驱动程序,我也曾经入手过一个,一直无法使用。因此,建议购买之前要和卖家沟通好,索要驱动,特别的如果卖家要求关闭数字签名才能安装驱动也请不要购买。这样做会让你的系统暴露在风险之中,另外,64位Windows由于本身的特性无法关闭数字签名功能。

插入之后安装驱动,驱动来自【参考1】。安装之后是下面这样(特别提醒,如果插入之后出现无法获得USB Descriptor 的提示,那么请更换一个USB端口,产生这个问题的原因可能是某些USB3.0端口和这个卡上的控制芯片有兼容问题)

image002

image004

image003

image005

Arduino UNO 上有2个烧录口,一个是给 USB 转串口芯片使用的,一个是给 328P 使用的。通常我们需要烧录的是328P 【参考】。也就是下图中的橘色标记口。
image006

直接将USBTinyISP的头插入这个位置即可。需要注意的是:

  1. 建议切断Uno上的外部供电之后进行烧写;
  2. 插入是有方向的,插入之后无论正反,板子上的灯都会亮。但是反插无需担心烧毁

至此,硬件部分准备完毕,下面就是如何使用软件进行烧写了。

  • 第三方软件Avrdudess刷写 328P BootLoader的方法

运行 Avrdudess,先选择 USBTinyISP

image007
然后使用右侧Detect 按钮进行芯片识别。正常情况下,主芯片应该是328P,USB转串口芯片应该是16U2或者8U2如果没有识别,应该是插线反了导致的,请调换方向重新插入
image008
最后,选择要烧写的文件,再使用GO 按钮即可进行烧录
image009
特别提醒:不要调整右侧 Fuses 选项。

二.      Arduino IDE 刷写 328P BootLoader的方法

  1. Tools->Board->选择你的板子型号,比如:Uno
  2. Tools->Programmer->USBTinyISP 选择烧写器的型号

image0103.Tools->BurnBootloader 直接烧写 328P 的Bootloader

image011

烧写成功的话,会有下面的提示信息

image012

  • Arduino IDE 刷写328P上面程序的方法

某些情况下,我们需要直接烧写328P上面的程序,方法如下:

  1. IDE中保证你的代码能够正常编译通过
  2. IDE中选择板子型号和烧写器型号和上面介绍的步骤一样
  3. 使用File->Upload Using Programmer

image013
运行成功后有下面类似提示

image014

本文首发 http://www.arduino.cn/thread-21619-1-1.html

文章中提到的工具和驱动也可以在上面的网址找到

参考:

  1. https://learn.adafruit.com/usbtinyisp/drivers 其实国内大多数 Arduino 产品都是仿造国外的而已,软件和Firmware一直是软肋。
  2. https://www.lab-z.com/ardfim/

Step to UEFI (94)Source Level Debug

直接进行 Source Level的 Debug 对于学习过是非常有用,本文就介绍一下如何在 NT32Pkg的模拟环境下进行 Source Level Debug 的方法。使用的环境是 Windows7 + UDK2015+VS2013。调试的目标是 UDK2015 AppPkg 自带的 Hello。

在 Hello.INF 中加入下面的编译参数:

[BuildOptions]
MSFT:DEBUG_*_IA32_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /ALIGN:4096 /FILEALIGN:4096 /SUBSYSTEM:CONSOLE

 

此外,在代码中加入_asm int 3 ,当编译器遇到这个命令时,会自动停止准备调试

INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  _asm int 3  
  Print(L"Hello there fellow Programmer.\n");
  Print(L"Welcome to the world of EDK II.\n");

  return(0);
}

 

上述修改完成后,正常编译

Build –a IA32 –p AppPkg\AppPkg.dsc

编译完成之后,在NT32 模拟环境中运行 hello.efi, 会出现下面的错误信息,选择使用 VS2013 调试
image001

然后就可以看到带着源码的调试界面了
image003

我试验了一下,感觉还不错。

一般情况下BIOS工程师不会进行源码级别的调试,最直接的原因是:这样的调试过于复杂,必须额外的硬件支持,要么需要 AMI Debugger ,要么需要 XDP 之类的高级工具,单纯的准备就需要花费很多时间。

自从有了UEFI 的架构,串口 Debug 信息是 BIOS 工程师最忠实的伙伴。

【注释】:本文根据《UEFI 原理与编程》一书 P59 3.4 调试 UEFI 写成。只是这本书上给出来的方法我试验并不好用,疑惑之间搜索到了该书作者在他的Blog上提到这个问题,试验之后完全没有问题:

http://www.cppblog.com/djxzh/archive/2015/02/08/209766.html
“书中讲到了如何利用_asm int 3 调试代码。
_asm int 3需要配合Nt32Pkg使用。也就是说通过Nt32Pkg编译出的.efi文件才能够调试。
如果你带_asm int 3语句的工程是通过非Nt32Pkg编译出来的(例如AppPkg),在SecMain模拟器中调试会导致断点停在Image.c文件如下代码中
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
在模拟器控制台会输出
WARNING: No source level debug
表明SecMain在加载你的模块时没有成功加载调试符号。
解决方案
在.inf文件中添加如下代码
[BuildOptions]
MSFT:DEBUG_*_IA32_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /ALIGN:4096 /FILEALIGN:4096 /SUBSYSTEM:CONSOLE

VS2013 编译的问题

最近安装了一个 VS2013进行 UEFI 的编译,碰到了其怪的错误:

“C:\Program Files\Microsoft Visual Studio 12.0\Vc\bin\link.exe” /out:”c:\udk2015\Build\NT32IA32\DEBUG_VS2013\IA32\SecMain.exe” /base:0x10000000 /pdb:”c:\udk2015\Build\NT32IA32\DEBUG_VS2013\IA32\SecMain.pdb” /LIBPATH:”C:\Program Files\Microsoft Visual Studio 12.0\VC\\Lib” /LIBPATH:”C:\Program Files\Windows Kits\8.1\Lib\winv6.3\um\x86″ /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib /EXPORT:InitializeDriver=_ModuleEntryPoint /BASE:0x10000 /ALIGN:4096 /FILEALIGN:4096 /SUBSYSTEM:CONSOLE @c:\udk2015\Build\NT32IA32\DEBUG_VS2013\IA32\Nt32Pkg\Sec\SecMain\OUTPUT\static_library_files.lst

SecMain.lib(WinNtThunk.obj) : error LNK2001: unresolved external symbol _SetCons
oleCursorInfo@8
c:\udk2015\Build\NT32IA32\DEBUG_VS2013\IA32\SecMain.exe : fatal error LNK1120: 1
51 unresolved externals

build…
: error 7000: Failed to execute command
C:\Program Files\Microsoft Visual Studio 12.0\Vc\bin\nmake.exe /nologo t
build [c:\udk2\015\Build\NT32IA32\DEBUG_VS2013\IA32\Nt32Pkg\Sec\SecMain]

仔细研究发现是虚拟机无法找到一些 Windows SDK 的内容。后来经过研究发现错误的原因是因为我使用了错误 VS2013 的控制台。我想编译 X64的UEFI 代码,但是进入了 x86(IA32)的控制台。

tt

正确的做法是:

如果你要编译x64 的代码,那么需要进入上面红色框中的命令行模式。然后,Conf\Target.txt 中的TOOL_CHAIN_TAG 必须是VS2013;

如果你要编译IA32的代码,那么需要进入上面绿色框中的命令行模式。然后,Conf\Target.txt 中的TOOL_CHAIN_TAG 必须是VS2013x86;

否则编译器无法找到对应的SDK 文件。

简单代码打造 Arduino 整蛊设备

如果你使用的是Intel 集成显卡的话,安装好驱动之后可以使用键盘上的 Ctrl + Alt+方向键旋转屏幕。根据这个功能,我们可以尝试制作一个整蛊的硬件。原理上来说就是使用 Leonardo模拟按下这个组合键,发送给系统来实现转动。当然为了防止你的朋友们变成下面这个样子,代码使用随机转动:
image001

代码非常简单

#define KEY_LEFT_CTRL		0x80
#define KEY_LEFT_ALT		0x82
#define KEY_UP_ARROW		0xDA
#define KEY_DOWN_ARROW		0xD9
#define KEY_LEFT_ARROW		0xD8
#define KEY_RIGHT_ARROW		0xD7

void setup() {
  // put your setup code here, to run once:
  Keyboard.begin();
}

void loop() {

  delay(5000);
  
  // CTRL-ALT-LEFT
  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press(KEY_LEFT_ALT);
  
  switch(random(3)){
    case 0:
      Keyboard.press(KEY_LEFT_ARROW);    
      break;
    case 1:
      Keyboard.press(KEY_RIGHT_ARROW);        
      break;
    case 2:
      Keyboard.press(KEY_UP_ARROW);        
      break;
    case 3:
      Keyboard.press(KEY_DOWN_ARROW);        
      break;
  }
  Keyboard.releaseAll();

}

 

运行之后的效果:

image003

image002

关于按键信息在下面这个文件中可以看到:
\hardware\arduino\sam\cores\arduino\USB\USBAPI.h
弄明白上面的原理,你还可以做一个能够遥控旋转的设备,如果你不想让别人动你的电脑就让他转起来,很快对方就会知难而退的。

Step to UEFI (93)FTDI 串口驱动

FDTI232系列芯片是最好的USB转串口芯片,驱动全,芯片本身很稳定,兼容性也很好。这次介绍一个FTDI USB串口芯片的项目,地址是

https://github.com/tianocore/tianocore.github.io/wiki/Tasks-USB-Serial-Adapter-driver#Real_UEFI_system

项目的简介如下:

“Today there are many inexpensive USB Serial adapters available, and most systems are built with USB ports available. But at the same time, the dedicated Serial port is becoming less common to find available in a system.
A serial port can still be useful for software debugging purposes. (debug trace messages)
It can also be useful in providing a secondary terminal to the UEFI system.
This task would involve writing a USB driver which interfaces with a USB Serial Adapter.
Ideally, this project should enable a driver that will attach to the USB Serial Adapter and produce the SerialIo protocol to enable the UEFI terminal to become available through the USB Serial adapter.”。

简单的说如果你的系统当前有 FTDI的USB串口,那么驱动会帮你生成一个 SerialIO 供你使用。这样你就可以在UEFI 环境中使用 FTDI 的USB 串口进行通讯。
在使用之前,请确定你的USB串口设备ID,例如:我现在使用的USB串口在 Windows下面看到的信息是这样的:
image002

image001

本文并不打算做原理上的分析,只是介绍如何编译和实验。
实验环境是 UDK2015

1.在 C:\EDK\Nt32Pkg\Nt32Pkg.dsc 文件的 [Components] 段中添加下面的内容

 

Nt32Pkg/WinNtBlockIoDxe/WinNtBlockIoDxe.inf
Nt32Pkg/WinNtSerialIoDxe/WinNtSerialIoDxe.inf
Nt32Pkg/WinNtGopDxe/WinNtGopDxe.inf
Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystemDxe.inf
MdeModulePkg/Application/HelloWorld/HelloWorld.inf
#LabZ_Start
FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
#LabZ_End
#
# Network stack drivers
# To test network drivers, need network Io driver(SnpNt32Io.dll), please refer to NETWORK-IO Subproject.
#

特别说明:如果有可能,最好在你当前的项目上重新这样编译一次。比如,你打算在BayTrail上用这个驱动,那么最好再Baytrail的BIOS中重新编译一次,这样最为稳妥。
2.将FtdiUsbSerialDxe目录拷贝到你UDK 的根目录下 例如: C:\EDK\
3.使用 Build 命令编译 NT32,这次是编译为 X64 的驱动。 命令式 Build –a X64
至此,驱动程序已经编译完成。可以在Build目录下找到我们需要的驱动,名称是 FtdiUsbSerialDxe.efi。 接下来我们就可以进行实验。
实验是在实体机上进行的,让一款“酷比魔方”的平板电脑和台式机进行通讯。实验中我使用了2个USB串口设备,还有一段双母头线(因为USB转串口都是公头)。

1. 首先检查一下,当前系统中没有 SerialIo Protocol
image003

2. 加载驱动image004

3. 再次检查会发现系统中多了一个 SerialIO protocol
image005
直接 dh 进行检查会发现多了2个handle 一个是驱动,一个是新增的挂protocol
image006
4. 之后使用我们前面介绍过的串口工具【参考1】
image007
看起来在启动的时候串口上会有一些乱码

在 Windows 端启动串口工具,双方可以进行通讯。
image008

完整的代码下载
FtdiUsbSerialDxe
编译好的X64 驱动下载
FtdiUsbEFI

特别注意:本文提到的代码是在 Windows7 VS2013 UDK2015环境下编译生成。

参考:
1. http://www.lab-z.com/stu91/ Step to UEFI (91) Shell下的串口测试软件