之前我尝试用 Fritzing 绘制短路图一段时间。这个软件有直观方便的特点。问题是大多数我用到的原件他的库中没有,如果自己绘制的话非常复杂,修改元件管脚也异常麻烦。
http://sourceforge.net/projects/tinycad/
用这个很容易就绘制一个 Arduino Pro Micro的电路
对应文件可以在这里下载
Arduino-Pro-Micro
之前我尝试用 Fritzing 绘制短路图一段时间。这个软件有直观方便的特点。问题是大多数我用到的原件他的库中没有,如果自己绘制的话非常复杂,修改元件管脚也异常麻烦。
http://sourceforge.net/projects/tinycad/
用这个很容易就绘制一个 Arduino Pro Micro的电路
对应文件可以在这里下载
Arduino-Pro-Micro
最近从淘宝上买了一个小水泵和水管给Arduino 用,效果还不错
螃蟹王国 隔膜泵 抽水机 水泵 茶具功夫茶配件 烧水茶具 385水泵 9.9元
http://detail.tmall.com/item.htm?spm=a1z10.3-b.w4011-2934116009.41.OZz7kv&id=27069408842&;rn=19abc97d3a3f333b0532d77acf876c95&abbucket=10
http://detail.tmall.com/item.htm?spm=a220o.1000855.0.0.aUdENI&id=16273533392&;rn=5ae68cf7c122dcfc1738eafece3afc9c&abbucket=0
同样他家选购了一个6V的适配器。
螃蟹王国 电源适配器6V2A 高性能 路由器电源 适配器 充电器 9.9元
http://detail.tmall.com/item.htm?spm=a1z10.3-b.w4011-2934116009.58.24xZpI&id=20618420536&;rn=6257e27c013737241e82d5c120284aaa&abbucket=10
螃蟹王国 DC电源插座 5.5*2.1MM 直流电源接口 DC-005 铜脚 3.95元
http://detail.tmall.com/item.htm?spm=a1z10.3-b.w4011-2934116009.27.pZwIWV&id=20623496826&;rn=1bc29be0dbbabd7042db076efd6ce381&abbucket=10
需要注意的是,这种插座有2个参数,5.5是直径,2.1是长度。也有2.5mm长度的,如果座和插头不匹配的话,插入之后会有部分露在外面。
下面是它工作视频以便参考
http://www.tudou.com/programs/view/7diay5i7Z-c/?resourceId=0_06_02_99
之前,我们介绍过如何用Arduino Uno打造一个PPT遥控器【参考1】,缺点是制作过程复杂,用到的器件较多导致整体稳定性不好。这里介绍使用 Arduino Pro Micro来做一个同样的PPT遥控器。
原理上和之前的并没有多少差别,都是通过模拟USB键盘的方式来进行控制。差别在于Pro Micro是缩小版的 Leonardo ,内部集成了USB Slave控制器,我们不需要再花费精力模拟自己为USB Keyboard.
硬件连接示意图:
代码是直接修改自示例“KeyboardMessage”
/*
Keyboard Button test
For the Arduino Leonardo and Micro.
Sends a text string when a button is pressed.
The circuit:
* pushbutton attached from pin 2 to +5V
* 10-kilohm resistor attached from pin 4 to ground
created 24 Oct 2011
modified 27 Mar 2012
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/KeyboardButton
*/
const int buttonPinA = A1; // input pin for A
const int buttonPinB = A2; // input pin for B
int previousButtonStateA = HIGH; // for checking the state of a pushButton
int previousButtonStateB = HIGH; // for checking the state of a pushButton
void setup() {
// make the pushButtonA pin an input:
pinMode(buttonPinA, INPUT);
// make the pushButtonB pin an input:
pinMode(buttonPinB, INPUT);
// initialize control over the keyboard:
Keyboard.begin();
delay(10000);
}
void loop() {
// read the pushbutton:
int buttonStateA = digitalRead(buttonPinA);
int buttonStateB = digitalRead(buttonPinB);
// if the button state has changed,
if ((buttonStateA != previousButtonStateA)
// and it's currently pressed:
&& (buttonStateA == HIGH)) {
// type out a message
//Keyboard.print("A");
Keyboard.press(KEY_LEFT_ARROW);
Keyboard.releaseAll();
}
// if the button state has changed,
if ((buttonStateB != previousButtonStateB)
// and it's currently pressed:
&& (buttonStateB == HIGH)) {
// type out a message
//Keyboard.print("B");
Keyboard.press(KEY_RIGHT_ARROW);
Keyboard.releaseAll();
}
// save the current button state for comparison next time:
previousButtonStateA = buttonStateA;
previousButtonStateB = buttonStateB;
}
实物图
工作的视频
http://www.tudou.com/listplay/mAjgE5Ac_Sg/Fz0piTvQ9Cs.html?resourceId=414535982_06_02_99
参考:
1. http://www.lab-z.com/%E7%94%A8-arduino-%E6%89%93%E9%80%A0ppt%E9%81%A5%E6%8E%A7%E5%99%A8/ 用 Arduino 打造PPT遥控器
2. http://arduino.cc/en/Reference/KeyboardModifiers 键值定义
根据上一次的LM386的设计【参考1】,以及网上的设计【参考2】,用Arduino做一个音量计。首先,音频从MIC进入,经过LM386的放大后接入到Arduino的模拟输入上,经过 DAC 量化之后显示在 1602上。
电路方面,和【参考1】差别在于我们不再使用喇叭而是直接将放大后的OUT信号接入到 Arduino的A5上。
显示方面,我们使用【参考3】提到的方法来自定义字符充当强度指示。
下面的图片与其说是原理图不如说是连接图更合适
//www.lab-z.com
//在 1602 上显示音量的小程序
#include <Wire.h>
#include "LiquidCrystal_I2C.h"
int value=100;
// custom charaters
LiquidCrystal_I2C lcd(0x27,16,2);
//定义进度块
byte p1[8] = {
0x10,
0x10,
0x10,
0x10,
0x10,
0x10,
0x10,
0x10};
byte p2[8] = {
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18};
byte p3[8] = {
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C};
byte p4[8] = {
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E};
byte p5[8] = {
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F};
void setup() {
lcd.init(); //初始化LCD
lcd.backlight(); //打开背光
//将自定义的字符块发送给LCD
//P1 是第一个,P2 是第二个,以此类推
lcd.createChar(0, p1);
lcd.createChar(1, p2);
lcd.createChar(2, p3);
lcd.createChar(3, p4);
lcd.createChar(4, p5);
//MIC输入放大之后在 A0 输入Arduino
pinMode(A0, INPUT);
}
//显示音量强度
//从左到右一共有 5 * 16 =80 点,一共是 80+1=81 个状态
void showprg(int value)
{
//第一行显示当前VU值
lcd.setCursor(0,0);
lcd.print(" VU=");
lcd.print(value);
//移动光标到第二行
lcd.setCursor(0,1);
//显示全黑的块
for (int i=1;i<value / 5;i++) {
lcd.write(4);
} //for (int i=1;i<a;i++)
// drawing charater's colums
// 显示除去全黑块之后的零头
switch (value % 5) {
case 0:
break;
case 1:
lcd.write(0);
break;
case 2:
lcd.write(1);
break;
case 3:
lcd.write(2);
break;
case 4:
lcd.write(3);
break;
} //switch (peace)
// 用空格填充剩下的位置
for (int i =0;i<(16-value / 5);i++) {
lcd.print(" "); }
}
void loop()
{
//输入的是0-1023,用函数将这个值对应到[0,80]上
showprg(map(analogRead(A0),0,1023,0,80));
delay(100);
}
测试方法,在右边用一个手机播放声音,MIC将音频信号转化为电平信号,经过LM386放大后,通过Arduino A5进行量化,最终显示在LCD1602上。
工作视频:
http://www.tudou.com/programs/view/oW_isUBnIEU/?resourceId=414535982_06_02_99
这个还只是一个模型,很粗糙,对于VU的动态显示范围不大,如果想让人类更容易理解需要考虑将现在的线性显示改为非线性的。
另外,工作时我发现比较奇怪的事情,就是如果静音的时候,会显示UV 大约 35左右,但是如果有动态声音播放的时候反而会出现 16 这样值,不清楚原因。
==============================================================================
另外的另外,研究了一下前面那个口哨开关的模拟输出。下面是电路图,右下角红色框起来的是模拟输出电路部分
查了一下,发现这种用法是电压跟随器,下图来自【参考4】。
电压跟随器,顾名思义,是实现输出电压跟随输入电压的变化的一类电子元件。也就是说,电压跟随器的电压放大倍数恒小于且接近1【参考5】。
多少输入就是多少输出…….这也就是为什么这个模块驱动能力很差带不动喇叭的原因。
参考:
1. http://www.lab-z.com/lm386-with-mic/ LM386 with MIC
2.http://www.arduino-hacks.com/arduino-vu-meter-lm386electret-microphone-condenser/ Arduino VU meter – LM386+electret microphone condenser
3. http://www.lab-z.com/1602progressbar/ 用 1602实现进度条
4. http://www.geek-workshop.com/thread-551-1-1.html LM358双运算放大器
5. http://baike.baidu.com/link?url=85VzUTT6n3IrCaAATZSg5jsg_A-zQYFrizj6jqGP7PzRg1aJe2yTddMihqJ7_UgRMa_GxnAYakSmmjM-9nhsz_ 电压跟随器
最近有一个获取环境声音送入Arduino处理的需求。想起来之前入手过带有microphone模拟输出的模块。找出来之后发现他有模拟输出,但是应该是因为放大后的信号太小(没有功率放大),无法达到Arduino的量化要求(可惜没有示波器否则可以定量分析一下)。

后来又想起之前入手过一个音频放大模块,主芯片是 LM386,于是拿出来实验。
我的第一个错误是:没搞清楚输入和输出。一端是 GND GND IN VCC (两个GND是连通的),一端是 OUT 和 GND。刚开始我错误的认为OUT和GND端应该接MIC,IN 用来驱动喇叭。后来认真看了卖家商品介绍,上面提到“板载喇叭接线座”方才恍然大悟。IN 应该是输入的音频信号,另外一端是对喇叭的直接驱动。
第二个错误是:我将MIC直接接入IN。试验了很久都没有反应。隐约觉得什么地方搞错了。后来在网上搜索了一下LM386的典型应用【参考1】,又恍然大悟,要输入的是不断变化的信号,而非直流。
咪头的接法,来自【参考1】.实际电路中,我用的是24K的电阻。

图片来自【参考1】
下面这部分电路不用管,LM386模块完全负责了。
此外还需要特别注意的是电路中的MIC有正负极的差别,100uF的电容也有正负极的区别,接反了不工作。
最终,实物是这样的:
模块上有一个可以调节放大倍数的可变电阻。放大倍数太大会出现噪音很大失真严重的问题。
工作视频(只是演示工作情况,电路方面和上面的介绍有差别):
http://www.tudou.com/programs/view/KiIwulH_p2s/?resourceId=0_06_02_99
额外的话
1.麦克风的英文是Microphone ,缩写是 MIC(又叫咪头,如果你想在淘宝上买的话,直接搜咪头就好)。我以为英文应该是 micphone,上网搜了一下发现犯这样错的人真不少……
2.供电对功放的影响很大。开始我用USB适配器(220V-5V)作为电源,噪音挺大的;后来换了一个USB充电宝效果就好了很多,估计如果有可能直接用干电池效果会更好吧?
3.时代在变化,上一次买的语音放大套件还都是独立元件,焊接调试都是蛮麻烦的事情,转眼间集成度就高了很多。
参考:
1. http://www.arduino-hacks.com/arduino-vu-meter-lm386electret-microphone-condenser/ Arduino VU meter – LM386+electret microphone condenser
2. http://www.learningaboutelectronics.com/Articles/How-to-connect-a-LM386-audio-amplifier-chip How to Connect a LM386 Audio Amplifier Chip to a Circuit
3. https://lowvoltage.wordpress.com/2011/05/15/lm386-mic-amp/ LM386 microphone amplifier
=================================================================
2015年4月6日 又研究了一下上面提到的带有麦克风的模块,是通过 LM358D 来进行放大的。我在网上查到有LM358和LM386一同工作来做一个小功放的。我试验了一下,结果比我直接MIC+LM368差多了,根本出不来什么声音。可能是电路设计上的缘故吧,毕竟那个模块的主要作用是输出当前是否出现了一个超过设定音强的声音(有个好听的名字叫“口哨开关”)。
首先测试一下普通的 Arduino UNO 的采样速度
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
analogReference(INTERNAL); //调用板载1.1V基准源
}
void loop() {
int i;
float voltage;
int sensorValue;
unsigned long elsp=millis();
for (i=0;i<10000;i++)
{
// read the input on analog pin 0:
sensorValue = analogRead(A0);
}
Serial.println(millis()-elsp);
delay(10000);
}
运行结果是 1120 左右,就是说采样10000次用时1.12s,采样频率大约是 8928.57Hz (次/秒)。
找了一段代码【参考6】能够提高采样速度
// defines for setting and clearing register bits #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif
写个程序测试一下
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
analogReference(INTERNAL); //调用板载1.1V基准源
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
}
void loop() {
int i;
float voltage;
int sensorValue;
unsigned long elsp=millis();
for (i=0;i<10000;i++)
{
// read the input on analog pin 0:
sensorValue = analogRead(A0);
}
Serial.println(millis()-elsp);
delay(10000);
}
运行输出结果在 170 左右,就是说采样10000次用时0.170s,采样频率大约是 58823.53Hz (次/秒)。
原理上来说Arduino 的 ADC 是用一种逐次逼近比较的方法来进行ADC转换的。通俗的说就是内部有一个比较器,每次内部升高一个电压和外部指定的Pin进行比较,根据大于小于来判定外部指定脚上的电压。资料说做这样一个比较大约需要10次,13个机器周期。而比较的频率是主控频率分频给出来的,有一个分频因子,默认是128,分频因子越小,比较的速度也就越快。
这里只是简单说一下,如果想了解ADC具体的工作原理,请阅读参考中提到的文章。
多说两句批评一下《Arduino技术内幕》这本书,刚开始我是阅读这本书来学习Arduino ADC的,但是阅读的时候感觉一直在外面游荡,不知道是原作者不懂还是翻译的人不明白,反正这一章的介绍让我一头雾水。
参考:
1. http://www.geek-workshop.com/thread-1848-1-1.html Arduino入门教程–第十七课–使用内部基准源进行ADC采样
2. 冷知识-这次讲ADC采样率-11月8号更新-上传高速率采样库-后续加入示波器库
http://www.geek-workshop.com/thread-11511-1-1.html
3. http://apcmag.com/arduino-analog-to-digital-converter-how-it-works.htm/ 介绍 Arduino ADC 如何工作
4. http://www.microsmart.co.za/technical/2014/03/01/advanced-arduino-adc/
5. http://wenku.baidu.com/link?url=I3DA7sWeIOxPntLf89u_MO8V30InxZlEWzDu7BxsXPQlJtprgkzUsdQmIEiBPSOBrdq1_iccg-qxxkOh1ROvfz3C9vbt55Axy_f1JAFZJTq 基于Arduino的音乐频谱显示器方案概述
6. http://forum.arduino.cc/index.php?topic=6549.0
7. http://meettechniek.info/embedded/arduino-analog.html Arduino: Analog measurements
目标:用 Arduino 遥控小灯的开关
材料:
1. Arduino Uno 一块
2. 2262/2272四路无线遥控套件M4非锁接收板 配四键无线遥控器(收发一套)
3. 继电器 (因为目前的Demo控制电压很小,所以最基础的型号就可以)
4. 5V充电宝一个
5. 面包板一块
6. 面包板电源一块
7. 小恐龙变色灯一个
选择无线遥控器的原因是:价格便宜,不涉及到解码输出简单稳定,易于使用。
原理上介绍是这样的:Arduino循环判断遥控接收模块输出管脚电压,如果出现HIGH,表示对应的按钮被按下。遥控器上有4个按钮,对应着接收器输入上面的D0-D3。实验使用D0 和 D1 两个脚分别控制继电器的开关。
电路图如下,左侧因为没有面包板电源的元件图样,所以用电池盒表示,实际电路中为一个3.3V电源。右侧因为没有接收模块的元件图样,所以用一个其他模块替代。无线模块在之前的实验中也使用过,可以在【参考1】上看到。
const int InputPinD0=8; //接收模块D0 Pin
const int InputPinD1=9; //接收模块D1 Pin
const int ControlPin=3; //控制继电器
void setup()
{
pinMode(ControlPin,OUTPUT);
pinMode(InputPinD0,INPUT_PULLUP); //输入,上拉10K
pinMode(InputPinD1,INPUT_PULLUP);
}
void loop()
{
int n =digitalRead(InputPinD0); //检查引脚是否有遥控输入
if (n==HIGH) {
digitalWrite(ControlPin,HIGH);
}
int m =digitalRead(InputPinD1);
if (m==HIGH) {
digitalWrite(ControlPin,LOW);
}
}
对于上面提到的10K上拉,可以在【参考2】中查到。
原理图
最后的样子
工作视频
参考:
1. http://www.lab-z.com/%E7%94%A8-arduino-%E6%89%93%E9%80%A0ppt%E9%81%A5%E6%8E%A7%E5%99%A8/ 用 Arduino 打造PPT遥控器
2. http://geek-workshop.com/forum.php?mod=viewthread&tid=2874&highlight=%C9%CF%C0%AD Arduino入门教程–第二十三课–使用IO口内部上拉功能
我们知道,可以使用 ConOut 下面的 SetCursorPosition 来设置光标输出的位置【参考1】。
但是,找了一圈也没有找到 GetCursorPosition ,我怎么知道当前光标在哪呢?查查C手册,通常使用conio.h 中的 wherex,wherey 来完成这个功能。问题是, clib 连这个头文件都没有……..
经过一番查找,在【参考2】中有人提到可以使用 Mode 中的 CursorColumn 和 CursorRow 来完成这个功能。于是,编写简单的程序验证一下,程序非常简单,随机生成一个位置显示X,然后在它后面输出当前这个X的位置:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <Protocol/EfiShell.h>
#include <Library/ShellLib.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/BlockIo.h>
#include <Library/DevicePathLib.h>
#include <Library/HandleParsingLib.h>
#include <Library/SortLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
extern EFI_SYSTEM_TABLE *gST;
/**
Get the position of cursor
**/
VOID GetCursorPosition(
IN UINTN *x,
IN UINTN *y
)
{
*x = gST->ConOut->Mode->CursorColumn;
*y = gST->ConOut->Mode->CursorRow;
return;
}
int
EFIAPI
main (
IN int Argc,
IN char **Argv
)
{
UINTN wherex;
UINTN wherey;
UINTN i;
for (i=0; i<5; i++)
{
gST -> ConOut -> SetCursorPosition(gST -> ConOut,rand()%70,rand() % 20);
GetCursorPosition(&wherex,&wherey);
Print(L"x[%02d]:[%02d] ",wherex, wherey);
}
return EFI_SUCCESS;
}
运行结果:
完整代码下载:
参考:
1.UEFI Spec 2.4 P460
2.http://biosren.com/viewthread.php?tid=4164&highlight=%B9%E2%B1%EA EFI下对应wherex()作用的FUN是哪个?该怎么用?
说点好玩的事情。我刚装机器的时候,安装了一个 ghost 版本的 win7 ,内置了QQ电脑管家,没想到一开机的时候这个软件就会崩溃。万般无奈,卸载之。然后发了一个说说。之后马上有客服加我QQ,后来又有回访的人加了我的QQ。 后来就没有了。
元旦的时候我又发了一次,提到这个事情,发表关于创业公司对大公司挑战的一点感想。其中有关键字,于是又有人加我,随后有下面的对话。
====================================================================
sunshine 2015/1/9 9:47:33
hi 请问您是?
Zt: 之前我遇到过电脑管家的问题
sunshine 2015/1/9 10:45:47
那目前呢?用管家有什么问题吗?
Zt:然后发了说说,你们就加我了.问题是启动的时候报错
sunshine 2015/1/9 10:46:31
是有崩溃的弹窗吗?
Zt:是的,我装的是 ghost 版本的
sunshine 2015/1/9 10:47:16
那下次碰到这个问题的时候 请点弹窗里的“错误详情” 里面会有2个文件,麻烦发给我一下。
Zt: 我可以给你找一下ghost文件,你们找个虚拟机试试
sunshine 2015/1/9 10:49:02
在正式环境下用吧
sunshine 2015/1/9 10:49:44
虚拟机我们自己也有 而且也有用户也在用 崩溃的情况还是很少见的 可能会有触发条件,需要有dump,就是崩溃文件。
Zt: 作为普通用户你觉得有多少人明白 dump文件。作为专业人士,你觉得有多少人用软件遇到问题,会用 windump 去调试?所以,这样的话,我还是换用其他软件了。
sunshine 2015/1/9 10:54:35
崩溃(crash)的时候错误详情里就是dump文件,如果用户点了窗口里的上报,也有会上报记录,我们的开发人员如果发现这个crash率异常升高,会去会查dump必要的话也会回访用户进行联系,但如果没有任何信息,我们也没办法去跟进。
sunshine 2015/1/9 10:55:40
您如果有重现问题,可以及时把这个文件发给我们看看,我们来查询下原因
sunshine 2015/1/9 10:57:03
并不是说我们不用ghost,不用虚拟机,我们版本发布之前会做各种兼容性测试,也会有用户帮我们体验,这部分用户也有很多是用虚拟机的,如果有重现的crash我们都会去跟进,但这些crash的原因并不一定都是一样的。
Zt: 谢谢 理解
====================================================================
事情不大,对我也没有什么影响。qq电脑管家唯一值得称赞的地方就是卸载做的很好。卸载程序运行之后几乎没有残留。
针对这个事情,我觉得值得更深入的思考。
对于腾讯来说,这个并非主营业务,所以毫无影响,最多是给 ghost装机的钱打了水漂(这个是很有中国特色的事情)。客户则会留下腾讯在安全领域毫无实力的印象。这都不是什么大问题。
进一步思考,我觉得这是不能直接让技术人员面对客户的问题,原因有两点:
1.技术人员工资通常比客服高,如果直接让技术人员面对客户,成本比较高
2.技术人员的思维就是纯技术性的。作为技术人员,我也直接面对过客户。深知无法重现的问题确实无法解决。这样的事情不会有耐心去复现。
3.不可能解决所有客户的问题。让大部分人满意或者说让重要的人满意就可以了。我在上一家公司,从老板那里学到的一个很重要的原则是:“客户不是上帝,只有大客户才是”
所以,客服人员之类的还是非常必要的。
上一篇是直接输出一个计数器,我们还可以让他直接打印当前的时间,需要修改的代码不多,替换Timeout函数即可:
/**
The callback function for the timer event used to get map.
@param[in] Event The event this function is registered to.
@param[in] Context The context registered to the event.
**/
VOID
EFIAPI
Timeout (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_TIME ET;
Status = gRT->GetTime(&ET, NULL);
Print(L"%02d:%02d:%02d\r\n",ET.Hour,ET.Minute,ET.Second);
return ;
}
可以看到符合我们的期望。
接下来,我们之前的文章提到CLIB中也有时间相关的函数,我们尝试直接使用ctime函数。改动很小
/**
The callback function for the timer event used to get map.
@param[in] Event The event this function is registered to.
@param[in] Context The context registered to the event.
**/
VOID
EFIAPI
Timeout (
IN EFI_EVENT Event,
IN VOID *Context
)
{
time_t t;
time(&t);
printf("%s\n",ctime(&t));
return ;
}
但是会导致TPL错误
错误原因不详。我请 HZZZ 帮忙看了一下,他发现如果我们使用默认的Shell_Full.efi就会出现问题,但是如果使用代码重新编译一个出来就不会有同样的问题(意思是:我们能够确定这是Shell本身的问题,但是没有会出现问题的Shell代码,因此无从得知Root Cause)。会出现下面的问题
对于这个问题,HZZZ Debug的结果是:新编译出来的Shell不支持 SE2 这个Protocol…….
因此,如果想写一个兼容性强的程序,最好直接使用 UefiShellLib 提供的 ShellGetExecutionBreakFlag 函数。这个函数会自动判断当前有哪个Protocol,然后调用存在的功能。