2024年2月更新,Step to UEFI 文章索引:
PVD:Battery 虚拟电池
前面的 PVD(Physical Virtual Device)设计过普通鼠标,绝对值鼠标, 这次带来的是一个虚拟电池的设计。在进行功耗和性能测试的时候,电池状态(AC/DC)对于Windows性能释放有着很大的影响。因此需要有手段来虚拟电池,之前我设计过2款虚拟电池软件的,但是这种软件是通过驱动来实现的,在具体使用时会有很大局限性。
这次带来的是使用 CH554模拟的USB HID 设备,它将自身报告为一个 UPS 设备,然后通过 USB 接口将当前电池信息报告给 Windows。代码是 Arduino 写成的,通俗易懂,只需要有 USB 知识就可以掌握。整体框架来自另外一个基于 Leonardo 的Arduino 项目。
硬件部分非常简单,就是一个 CH554e的最小系统(MSOP10)封装,非常适于制作小型设备。
#ifndef USER_USB_RAM
#error "This example needs to be compiled with a USER USB setting"
#endif
#include <WS2812.h>
#include "src/CdcHidCombo/USBCDC.h"
#include "src/CdcHidCombo/USBHIDKeyboardMouse.h"
#include "src/CdcHidCombo/PowerDevice.h"
#include "src/CdcHidCombo/USBconstant.h"
#define NUM_LEDS 1
#define COLOR_PER_LEDS 3
#define NUM_BYTES (NUM_LEDS*COLOR_PER_LEDS)
__xdata uint8_t ledData[NUM_BYTES];
#define MINUPDATEINTERVAL 26000UL
#define OnBoardLED 0x03
const byte bDeviceChemistry = IDEVICECHEMISTRY;
const byte bOEMVendor = IOEMVENDOR;
uint16_t iPresentStatus = 0, iPreviousStatus = 0;
byte bRechargable = 1;
byte bCapacityMode = 0; // units are in mWh
// Physical parameters
const uint16_t iConfigVoltage = 1380;
uint16_t iVoltage = 1300, iPrevVoltage = 0;
uint16_t iRunTimeToEmpty = 0, iPrevRunTimeToEmpty = 0;
uint16_t iAvgTimeToFull = 7200;
uint16_t iAvgTimeToEmpty = 7200;
uint16_t iRemainTimeLimit = 600;
int16_t iDelayBe4Reboot = -1;
int16_t iDelayBe4ShutDown = -1;
byte iAudibleAlarmCtrl = 2; // 1 - Disabled, 2 - Enabled, 3 - Muted
// Parameters for ACPI compliancy
uint8_t iDesignCapacity = 0xFF;
byte iWarnCapacityLimit = 10; // warning at 10%
byte iRemnCapacityLimit = 5; // low at 5%
const byte bCapacityGranularity1 = 1;
const byte bCapacityGranularity2 = 1;
uint8_t iFullChargeCapacity = 0xFF;
uint8_t iRemaining = 0xFF, iPrevRemaining = 0;
int iRes = 0;
unsigned long iIntTimer=0;
// Data format
// Keyboard(Total 9 bytes): 01(ReportID 01) + Keyboard data (8 Bytes)
// Mouse(Total 5 bytes): 02(ReportID 02) + Mouse Data (4 Bytes)
uint8_t recvStr[9];
uint8_t recvStrPtr = 0;
unsigned long Elsp;
uint8_t FeatureBuffer[256];
FeatureType FeatureList[32];
uint8_t FeatureRecord = 0;
uint16_t iManufacturerDate = 0,bCycles=20;
void setFeature(uint8_t id, uint8_t* Data, int Len)
{
/*
Serial0_print("ID:");
Serial0_print(id);
Serial0_print_c(' ');
Serial0_print(Data[0]);
Serial0_print_c(' ');
if (Len>1) {
Serial0_print(Data[1]);
Serial0_print_c(' ');
}
Serial0_print(Len);
Serial0_println_c(' ');
*/
FeatureList[id].Index = FeatureRecord;
FeatureList[id].Size = Len;
for (uint8_t i = 0; i < Len; i++) {
FeatureBuffer[FeatureRecord] = Data[i];
FeatureRecord++;
}
}
void setup() {
Serial0_begin(500000);
delay(1000);
Serial0_println("st");
uint8_t strIndex;
strIndex = 5;
setFeature(HID_PD_IPRODUCT, &strIndex, sizeof(strIndex));
strIndex = 6;
setFeature(HID_PD_MANUFACTURER, &strIndex, sizeof(strIndex));
strIndex = 7;
setFeature(HID_PD_SERIAL, &strIndex, sizeof(strIndex));
strIndex = 8;
setFeature(HID_PD_IDEVICECHEMISTRY, &strIndex, sizeof(strIndex));
setFeature(HID_PD_PRESENTSTATUS, &iPresentStatus, sizeof(iPresentStatus));
setFeature(HID_PD_RUNTIMETOEMPTY, &iRunTimeToEmpty, sizeof(iRunTimeToEmpty));
setFeature(HID_PD_AVERAGETIME2FULL, &iAvgTimeToFull, sizeof(iAvgTimeToFull));
setFeature(HID_PD_AVERAGETIME2EMPTY, &iAvgTimeToEmpty, sizeof(iAvgTimeToEmpty));
setFeature(HID_PD_REMAINTIMELIMIT, &iRemainTimeLimit, sizeof(iRemainTimeLimit));
setFeature(HID_PD_DELAYBE4REBOOT, &iDelayBe4Reboot, sizeof(iDelayBe4Reboot));
setFeature(HID_PD_DELAYBE4SHUTDOWN, &iDelayBe4ShutDown, sizeof(iDelayBe4ShutDown));
setFeature(HID_PD_RECHARGEABLE, &bRechargable, sizeof(bRechargable));
setFeature(HID_PD_CAPACITYMODE, &bCapacityMode, sizeof(bCapacityMode));
setFeature(HID_PD_CONFIGVOLTAGE, &iConfigVoltage, sizeof(iConfigVoltage));
setFeature(HID_PD_VOLTAGE, &iVoltage, sizeof(iVoltage));
setFeature(HID_PD_IOEMINFORMATION, &bOEMVendor, sizeof(bOEMVendor));
setFeature(HID_PD_AUDIBLEALARMCTRL, &iAudibleAlarmCtrl, sizeof(iAudibleAlarmCtrl));
setFeature(HID_PD_DESIGNCAPACITY, &iDesignCapacity, sizeof(iDesignCapacity));
setFeature(HID_PD_FULLCHRGECAPACITY, &iFullChargeCapacity, sizeof(iFullChargeCapacity));
setFeature(HID_PD_REMAININGCAPACITY, &iRemaining, sizeof(iRemaining));
setFeature(HID_PD_WARNCAPACITYLIMIT, &iWarnCapacityLimit, sizeof(iWarnCapacityLimit));
setFeature(HID_PD_REMNCAPACITYLIMIT, &iRemnCapacityLimit, sizeof(iRemnCapacityLimit));
setFeature(HID_PD_CPCTYGRANULARITY1, &bCapacityGranularity1, sizeof(bCapacityGranularity1));
setFeature(HID_PD_CPCTYGRANULARITY2, &bCapacityGranularity2, sizeof(bCapacityGranularity2));
setFeature(HID_PD_CYCLECOUNT,&bCycles,sizeof(bCycles));
setFeature(HID_PD_CONFIGVOLTAGE, &iConfigVoltage, sizeof(iConfigVoltage));
iManufacturerDate = (2025 - 1980) * 512 + 1 * 32 + 1;
setFeature(HID_PD_MANUFACTUREDATE, &iManufacturerDate, sizeof(iManufacturerDate));
/*
for (uint8_t i=0;i<32;i++) {
FeatureList[i].Index=i;
FeatureList[i].Size=1;
FeatureBuffer[i]=i;
}
for (uint8_t i=0;i<32;i++) {
Serial0_print(i);
Serial0_print_c(' ');
Serial0_print(FeatureList[i].Index);
Serial0_print_c(' ');
Serial0_print(FeatureList[i].Size);
Serial0_println_c(' ');
}
for (uint8_t i=0;i<FeatureRecord;i++) {
Serial0_print(FeatureBuffer[i]); Serial0_print_c(' ');
}
*/
USBInit();
bitSet(iPresentStatus, PRESENTSTATUS_CHARGING);
bitSet(iPresentStatus, PRESENTSTATUS_ACPRESENT);
bitSet(iPresentStatus , PRESENTSTATUS_BATTPRESENT);
bitSet(iPresentStatus , PRESENTSTATUS_PRIMARYBATTERY);
recvStr[0] = HID_PD_PRESENTSTATUS;
recvStr[1] = iPresentStatus & 0xFF;
recvStr[2] = (iPresentStatus >> 8) & 0xFF;;
USB_EP3_send(recvStr, 3);
setFeature(HID_PD_PRESENTSTATUS, &iPresentStatus, sizeof(iPresentStatus));
/*
iRemaining = 40;
recvStr[0] = HID_PD_REMAININGCAPACITY;
recvStr[1] = iRemaining & 0xFF;
USB_EP3_send(recvStr, 2);
setFeature(HID_PD_REMAININGCAPACITY, &iRemaining, sizeof(iRemaining));
*/
}
void loop() {
while (USBSerial_available()) {
uint8_t serialChar = USBSerial_read();
recvStr[recvStrPtr++] = serialChar;
if (recvStrPtr == 4) {
/*
for (uint8_t i = 0; i < 9; i++) {
Serial0_write(recvStr[i]);
}
*/
if (recvStr[0] == HID_PD_PRESENTSTATUS) {
//USB_EP3_send(recvStr, 3);
iPresentStatus=recvStr[1]+(recvStr[2]<<8);
Serial0_print("ps:");
Serial0_println(iPresentStatus);
}
if (recvStr[0] == HID_PD_REMAININGCAPACITY) {
iRemaining=recvStr[1];
Serial0_print("rm:");
Serial0_println(iRemaining);
}
if (recvStr[0] == OnBoardLED) {
set_pixel_for_GRB_LED(ledData, 0, recvStr[1], recvStr[2], recvStr[3]);
neopixel_show_P1_5(ledData, NUM_BYTES);
}
recvStrPtr = 0;
}
Elsp = millis();
}
// If there is no data in 100ms, clear the receive buffer
if (millis() - Elsp > 100) {
recvStrPtr = 0;
Elsp = millis();
}
if((iPresentStatus != iPreviousStatus) || (iRemaining!=iPrevRemaining) || (millis()-iIntTimer>MINUPDATEINTERVAL) ) {
recvStr[0]=HID_PD_REMAININGCAPACITY;
recvStr[1]=iRemaining;
USB_EP3_send(recvStr, 2);
setFeature(HID_PD_REMAININGCAPACITY, &iRemaining, sizeof(iRemaining));
recvStr[0]=HID_PD_PRESENTSTATUS;
recvStr[1]=iPresentStatus&0xFF;
recvStr[2]=(iPresentStatus>>8)&0xFF;
USB_EP3_send(recvStr, 3);
setFeature(HID_PD_PRESENTSTATUS, &iPresentStatus, sizeof(iPresentStatus));
Serial0_println("a:");
iPreviousStatus=iPresentStatus;
iPrevRemaining=iRemaining;
iIntTimer=millis();
}
}
简单的说,开始之后,通过 HID Descriptor 报告当前设备属性,其中有很多 Feature项目。之后 Arduino 代码通过下面这种将描述符中的 Report ID 和 数值关联起来。后面,当Ch554收到 Feature Request 之后就根据前面的注册信息返回对应值。
setFeature(HID_PD_DESIGNCAPACITY, &iDesignCapacity, sizeof(iDesignCapacity));
除了USB HID 设备,Ch554还实现了一个 USB CDC 设备,在 loop 中我们接收来自USB 串口的数据,如果是以HID_PD_PRESENTSTATUS 开头的,或者HID_PD_REMAININGCAPACITY开头的,那么直接更改状态,然后从HID 对应的 EndPoint中发送出去,这样 Windows 接收到后会更新电池状态。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
string targetVid = "VID_1209";
string targetPid = "PID_C55C";
string portName = FindUsbDevicePort(targetVid, targetPid);
if (!string.IsNullOrEmpty(portName))
{
Console.WriteLine($"Found device on port: {portName}");
}
else
{
Console.WriteLine("Device not found.");
}
Console.ReadKey();
}
static string FindUsbDevicePort(string vid, string pid)
{
string query = "SELECT * FROM Win32_PnPEntity WHERE DeviceID LIKE '%" + vid + "&" + pid + "%'";
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
foreach (ManagementObject device in searcher.Get())
{
string deviceId = device["DeviceID"]?.ToString();
if (deviceId != null && deviceId.Contains(vid) && deviceId.Contains(pid))
{
string caption = device["Caption"]?.ToString();
if (caption != null && caption.Contains("(COM"))
{
int startIndex = caption.IndexOf("(COM") + 1;
int endIndex = caption.IndexOf(")", startIndex);
return caption.Substring(startIndex, endIndex - startIndex);
}
}
}
}
return null;
}
}
}
完整的 Arduino 代码:
完整的 C#代码:
网站故障说明
2015年1月8日早晨,我和平时一样打开浏览器,准备登录网站查看留言,结果发现无法登录。开始想着是偶尔的维护,过一会又试验了一下发现仍然没有恢复。只好登录辰讯云(https://www.chenxunyun.com/)联系客服,随后得知了一个消息:服务器硬盘损坏,数据正在恢复中。大约到了中午,再次询问的时候,得到的消息是完全损坏,全部丢失。
不幸中的万幸是每个月我都会手工备份,上一次的备份时2024年12月中旬,于是等到再次上线只好重装系统和一干软件,重新搭建服务器所需内容。盘点下来网站内容丢失不多。
如果你在使用中遇到网站任何问题,欢迎在本文留言。
ASCII 一览表
工作需要经常查看 ASCII 数值,索性弄了一个列表和在线查询的功能:
这是在线查询的功能,使用 JavaScript 实现,有兴趣的朋友也可以直接保存到本地使用:
ASCII control characters (character code 0-31)
The first 32 characters in the ASCII-table are unprintable control codes and are used to control peripherals such as printers.
DEC | OCT | HEX | BIN | Symbol | HTML Number | HTML Name | Description |
---|---|---|---|---|---|---|---|
0 | 000 | 00 | 00000000 | NUL | � | Null character | |
1 | 001 | 01 | 00000001 | SOH |  | Start of Heading | |
2 | 002 | 02 | 00000010 | STX |  | Start of Text | |
3 | 003 | 03 | 00000011 | ETX |  | End of Text | |
4 | 004 | 04 | 00000100 | EOT |  | End of Transmission | |
5 | 005 | 05 | 00000101 | ENQ |  | Enquiry | |
6 | 006 | 06 | 00000110 | ACK |  | Acknowledge | |
7 | 007 | 07 | 00000111 | BEL |  | Bell, Alert | |
8 | 010 | 08 | 00001000 | BS |  | Backspace | |
9 | 011 | 09 | 00001001 | HT | 	 | Horizontal Tab | |
10 | 012 | 0A | 00001010 | LF | | Line Feed | |
11 | 013 | 0B | 00001011 | VT |  | Vertical Tabulation | |
12 | 014 | 0C | 00001100 | FF |  | Form Feed | |
13 | 015 | 0D | 00001101 | CR | | Carriage Return | |
14 | 016 | 0E | 00001110 | SO |  | Shift Out | |
15 | 017 | 0F | 00001111 | SI |  | Shift In | |
16 | 020 | 10 | 00010000 | DLE |  | Data Link Escape | |
17 | 021 | 11 | 00010001 | DC1 |  | Device Control One (XON) | |
18 | 022 | 12 | 00010010 | DC2 |  | Device Control Two | |
19 | 023 | 13 | 00010011 | DC3 |  | Device Control Three (XOFF) | |
20 | 024 | 14 | 00010100 | DC4 |  | Device Control Four | |
21 | 025 | 15 | 00010101 | NAK |  | Negative Acknowledge | |
22 | 026 | 16 | 00010110 | SYN |  | Synchronous Idle | |
23 | 027 | 17 | 00010111 | ETB |  | End of Transmission Block | |
24 | 030 | 18 | 00011000 | CAN |  | Cancel | |
25 | 031 | 19 | 00011001 | EM |  | End of medium | |
26 | 032 | 1A | 00011010 | SUB |  | Substitute | |
27 | 033 | 1B | 00011011 | ESC |  | Escape | |
28 | 034 | 1C | 00011100 | FS |  | File Separator | |
29 | 035 | 1D | 00011101 | GS |  | Group Separator | |
30 | 036 | 1E | 00011110 | RS |  | Record Separator | |
31 | 037 | 1F | 00011111 | US |  | Unit Separator |
ASCII printable characters (character code 32-127)
Codes 32-127 are common for all the different variations of the ASCII table, they are called printable characters, represent letters, digits, punctuation marks, and a few miscellaneous symbols. You will find almost every character on your keyboard. Character 127 represents the command DEL.
DEC | OCT | HEX | BIN | Symbol | HTML Number | HTML Name | Description |
---|---|---|---|---|---|---|---|
32 | 040 | 20 | 00100000 | SP |   | Space | |
33 | 041 | 21 | 00100001 | ! | ! | ! | Exclamation mark |
34 | 042 | 22 | 00100010 | " | " | " | Double quotes (or speech marks) |
35 | 043 | 23 | 00100011 | # | # | # | Number sign |
36 | 044 | 24 | 00100100 | $ | $ | $ | Dollar |
37 | 045 | 25 | 00100101 | % | % | % | Per cent sign |
38 | 046 | 26 | 00100110 | & | & | & | Ampersand |
39 | 047 | 27 | 00100111 | ' | ' | ' | Single quote |
40 | 050 | 28 | 00101000 | ( | ( | &lparen; | Open parenthesis (or open bracket) |
41 | 051 | 29 | 00101001 | ) | ) | &rparen; | Close parenthesis (or close bracket) |
42 | 052 | 2A | 00101010 | * | * | * | Asterisk |
43 | 053 | 2B | 00101011 | + | + | + | Plus |
44 | 054 | 2C | 00101100 | , | , | , | Comma |
45 | 055 | 2D | 00101101 | - | - | Hyphen-minus | |
46 | 056 | 2E | 00101110 | . | . | . | Period, dot or full stop |
47 | 057 | 2F | 00101111 | / | / | / | Slash or divide |
48 | 060 | 30 | 00110000 | 0 | 0 | Zero | |
49 | 061 | 31 | 00110001 | 1 | 1 | One | |
50 | 062 | 32 | 00110010 | 2 | 2 | Two | |
51 | 063 | 33 | 00110011 | 3 | 3 | Three | |
52 | 064 | 34 | 00110100 | 4 | 4 | Four | |
53 | 065 | 35 | 00110101 | 5 | 5 | Five | |
54 | 066 | 36 | 00110110 | 6 | 6 | Six | |
55 | 067 | 37 | 00110111 | 7 | 7 | Seven | |
56 | 070 | 38 | 00111000 | 8 | 8 | Eight | |
57 | 071 | 39 | 00111001 | 9 | 9 | Nine | |
58 | 072 | 3A | 00111010 | : | : | : | Colon |
59 | 073 | 3B | 00111011 | ; | ; | ; | Semicolon |
60 | 074 | 3C | 00111100 | < | < | < | Less than (or open angled bracket) |
61 | 075 | 3D | 00111101 | = | = | = | Equals |
62 | 076 | 3E | 00111110 | > | > | > | Greater than (or close angled bracket) |
63 | 077 | 3F | 00111111 | ? | ? | ? | Question mark |
64 | 100 | 40 | 01000000 | @ | @ | @ | At sign |
65 | 101 | 41 | 01000001 | A | A | Uppercase A | |
66 | 102 | 42 | 01000010 | B | B | Uppercase B | |
67 | 103 | 43 | 01000011 | C | C | Uppercase C | |
68 | 104 | 44 | 01000100 | D | D | Uppercase D | |
69 | 105 | 45 | 01000101 | E | E | Uppercase E | |
70 | 106 | 46 | 01000110 | F | F | Uppercase F | |
71 | 107 | 47 | 01000111 | G | G | Uppercase G | |
72 | 110 | 48 | 01001000 | H | H | Uppercase H | |
73 | 111 | 49 | 01001001 | I | I | Uppercase I | |
74 | 112 | 4A | 01001010 | J | J | Uppercase J | |
75 | 113 | 4B | 01001011 | K | K | Uppercase K | |
76 | 114 | 4C | 01001100 | L | L | Uppercase L | |
77 | 115 | 4D | 01001101 | M | M | Uppercase M | |
78 | 116 | 4E | 01001110 | N | N | Uppercase N | |
79 | 117 | 4F | 01001111 | O | O | Uppercase O | |
80 | 120 | 50 | 01010000 | P | P | Uppercase P | |
81 | 121 | 51 | 01010001 | Q | Q | Uppercase Q | |
82 | 122 | 52 | 01010010 | R | R | Uppercase R | |
83 | 123 | 53 | 01010011 | S | S | Uppercase S | |
84 | 124 | 54 | 01010100 | T | T | Uppercase T | |
85 | 125 | 55 | 01010101 | U | U | Uppercase U | |
86 | 126 | 56 | 01010110 | V | V | Uppercase V | |
87 | 127 | 57 | 01010111 | W | W | Uppercase W | |
88 | 130 | 58 | 01011000 | X | X | Uppercase X | |
89 | 131 | 59 | 01011001 | Y | Y | Uppercase Y | |
90 | 132 | 5A | 01011010 | Z | Z | Uppercase Z | |
91 | 133 | 5B | 01011011 | [ | [ | [ | Opening bracket |
92 | 134 | 5C | 01011100 | \ | \ | \ | Backslash |
93 | 135 | 5D | 01011101 | ] | ] | ] | Closing bracket |
94 | 136 | 5E | 01011110 | ^ | ^ | ^ | Caret - circumflex |
95 | 137 | 5F | 01011111 | _ | _ | _ | Underscore |
96 | 140 | 60 | 01100000 | ` | ` | ` | Grave accent |
97 | 141 | 61 | 01100001 | a | a | Lowercase a | |
98 | 142 | 62 | 01100010 | b | b | Lowercase b | |
99 | 143 | 63 | 01100011 | c | c | Lowercase c | |
100 | 144 | 64 | 01100100 | d | d | Lowercase d | |
101 | 145 | 65 | 01100101 | e | e | Lowercase e | |
102 | 146 | 66 | 01100110 | f | f | Lowercase f | |
103 | 147 | 67 | 01100111 | g | g | Lowercase g | |
104 | 150 | 68 | 01101000 | h | h | Lowercase h | |
105 | 151 | 69 | 01101001 | i | i | Lowercase i | |
106 | 152 | 6A | 01101010 | j | j | Lowercase j | |
107 | 153 | 6B | 01101011 | k | k | Lowercase k | |
108 | 154 | 6C | 01101100 | l | l | Lowercase l | |
109 | 155 | 6D | 01101101 | m | m | Lowercase m | |
110 | 156 | 6E | 01101110 | n | n | Lowercase n | |
111 | 157 | 6F | 01101111 | o | o | Lowercase o | |
112 | 160 | 70 | 01110000 | p | p | Lowercase p | |
113 | 161 | 71 | 01110001 | q | q | Lowercase q | |
114 | 162 | 72 | 01110010 | r | r | Lowercase r | |
115 | 163 | 73 | 01110011 | s | s | Lowercase s | |
116 | 164 | 74 | 01110100 | t | t | Lowercase t | |
117 | 165 | 75 | 01110101 | u | u | Lowercase u | |
118 | 166 | 76 | 01110110 | v | v | Lowercase v | |
119 | 167 | 77 | 01110111 | w | w | Lowercase w | |
120 | 170 | 78 | 01111000 | x | x | Lowercase x | |
121 | 171 | 79 | 01111001 | y | y | Lowercase y | |
122 | 172 | 7A | 01111010 | z | z | Lowercase z | |
123 | 173 | 7B | 01111011 | { | { | { | Opening brace |
124 | 174 | 7C | 01111100 | | | | | | | Vertical bar |
125 | 175 | 7D | 01111101 | } | } | } | Closing brace |
126 | 176 | 7E | 01111110 | ~ | ~ | ˜ | Equivalency sign - tilde |
127 | 177 | 7F | 01111111 | DEL |  | Delete |
The extended ASCII codes (character code 128-255)
There are several different variations of the 8-bit ASCII table. The table below is according to Windows-1252 (CP-1252) which is a superset of ISO 8859-1, also called ISO Latin-1, in terms of printable characters, but differs from the IANA's ISO-8859-1 by using displayable characters rather than control characters in the 128 to 159 range. Characters that differ from ISO-8859-1 is marked by light blue color.
DEC | OCT | HEX | BIN | Symbol | HTML Number | HTML Name | Description |
---|---|---|---|---|---|---|---|
128 | 200 | 80 | 10000000 | € | € | € | Euro sign |
129 | 201 | 81 | 10000001 | Unused | |||
130 | 202 | 82 | 10000010 | ‚ | ‚ | ‚ | Single low-9 quotation mark |
131 | 203 | 83 | 10000011 | ƒ | ƒ | ƒ | Latin small letter f with hook |
132 | 204 | 84 | 10000100 | „ | „ | „ | Double low-9 quotation mark |
133 | 205 | 85 | 10000101 | … | … | … | Horizontal ellipsis |
134 | 206 | 86 | 10000110 | † | † | † | Dagger |
135 | 207 | 87 | 10000111 | ‡ | ‡ | ‡ | Double dagger |
136 | 210 | 88 | 10001000 | ˆ | ˆ | ˆ | Modifier letter circumflex accent |
137 | 211 | 89 | 10001001 | ‰ | ‰ | ‰ | Per mille sign |
138 | 212 | 8A | 10001010 | Š | Š | Š | Latin capital letter S with caron |
139 | 213 | 8B | 10001011 | ‹ | ‹ | ‹ | Single left-pointing angle quotation |
140 | 214 | 8C | 10001100 | Œ | Œ | Œ | Latin capital ligature OE |
141 | 215 | 8D | 10001101 | Unused | |||
142 | 216 | 8E | 10001110 | Ž | Ž | Ž | Latin capital letter Z with caron |
143 | 217 | 8F | 10001111 | Unused | |||
144 | 220 | 90 | 10010000 | Unused | |||
145 | 221 | 91 | 10010001 | ‘ | ‘ | ‘ | Left single quotation mark |
146 | 222 | 92 | 10010010 | ’ | ’ | ’ | Right single quotation mark |
147 | 223 | 93 | 10010011 | “ | “ | “ | Left double quotation mark |
148 | 224 | 94 | 10010100 | ” | ” | ” | Right double quotation mark |
149 | 225 | 95 | 10010101 | • | • | • | Bullet |
150 | 226 | 96 | 10010110 | – | – | – | En dash |
151 | 227 | 97 | 10010111 | — | — | — | Em dash |
152 | 230 | 98 | 10011000 | ˜ | ˜ | ˜ | Small tilde |
153 | 231 | 99 | 10011001 | ™ | ™ | ™ | Trade mark sign |
154 | 232 | 9A | 10011010 | š | š | š | Latin small letter S with caron |
155 | 233 | 9B | 10011011 | › | › | › | Single right-pointing angle quotation mark |
156 | 234 | 9C | 10011100 | œ | œ | œ | Latin small ligature oe |
157 | 235 | 9D | 10011101 | Unused | |||
158 | 236 | 9E | 10011110 | ž | ž | ž | Latin small letter z with caron |
159 | 237 | 9F | 10011111 | Ÿ | Ÿ | Ÿ | Latin capital letter Y with diaeresis |
160 | 240 | A0 | 10100000 | NBSP |   | | Non-breaking space |
161 | 241 | A1 | 10100001 | ¡ | ¡ | ¡ | Inverted exclamation mark |
162 | 242 | A2 | 10100010 | ¢ | ¢ | ¢ | Cent sign |
163 | 243 | A3 | 10100011 | £ | £ | £ | Pound sign |
164 | 244 | A4 | 10100100 | ¤ | ¤ | ¤ | Currency sign |
165 | 245 | A5 | 10100101 | ¥ | ¥ | ¥ | Yen sign |
166 | 246 | A6 | 10100110 | ¦ | ¦ | ¦ | Pipe, broken vertical bar |
167 | 247 | A7 | 10100111 | § | § | § | Section sign |
168 | 250 | A8 | 10101000 | ¨ | ¨ | ¨ | Spacing diaeresis - umlaut |
169 | 251 | A9 | 10101001 | © | © | © | Copyright sign |
170 | 252 | AA | 10101010 | ª | ª | ª | Feminine ordinal indicator |
171 | 253 | AB | 10101011 | « | « | « | Left double angle quotes |
172 | 254 | AC | 10101100 | ¬ | ¬ | ¬ | Negation |
173 | 255 | AD | 10101101 | SHY | ­ | ­ | Soft hyphen |
174 | 256 | AE | 10101110 | ® | ® | ® | Registered trade mark sign |
175 | 257 | AF | 10101111 | ¯ | ¯ | ¯ | Spacing macron - overline |
176 | 260 | B0 | 10110000 | ° | ° | ° | Degree sign |
177 | 261 | B1 | 10110001 | ± | ± | ± | Plus-or-minus sign |
178 | 262 | B2 | 10110010 | ² | ² | ² | Superscript two - squared |
179 | 263 | B3 | 10110011 | ³ | ³ | ³ | Superscript three - cubed |
180 | 264 | B4 | 10110100 | ´ | ´ | ´ | Acute accent - spacing acute |
181 | 265 | B5 | 10110101 | µ | µ | µ | Micro sign |
182 | 266 | B6 | 10110110 | ¶ | ¶ | ¶ | Pilcrow sign - paragraph sign |
183 | 267 | B7 | 10110111 | · | · | · | Middle dot - Georgian comma |
184 | 270 | B8 | 10111000 | ¸ | ¸ | ¸ | Spacing cedilla |
185 | 271 | B9 | 10111001 | ¹ | ¹ | ¹ | Superscript one |
186 | 272 | BA | 10111010 | º | º | º | Masculine ordinal indicator |
187 | 273 | BB | 10111011 | » | » | » | Right double angle quotes |
188 | 274 | BC | 10111100 | ¼ | ¼ | ¼ | Fraction one quarter |
189 | 275 | BD | 10111101 | ½ | ½ | ½ | Fraction one half |
190 | 276 | BE | 10111110 | ¾ | ¾ | ¾ | Fraction three quarters |
191 | 277 | BF | 10111111 | ¿ | ¿ | ¿ | Inverted question mark |
192 | 300 | C0 | 11000000 | À | À | À | Latin capital letter A with grave |
193 | 301 | C1 | 11000001 | Á | Á | Á | Latin capital letter A with acute |
194 | 302 | C2 | 11000010 | Â | Â | Â | Latin capital letter A with circumflex |
195 | 303 | C3 | 11000011 | Ã | Ã | Ã | Latin capital letter A with tilde |
196 | 304 | C4 | 11000100 | Ä | Ä | Ä | Latin capital letter A with diaeresis |
197 | 305 | C5 | 11000101 | Å | Å | Å | Latin capital letter A with ring above |
198 | 306 | C6 | 11000110 | Æ | Æ | Æ | Latin capital letter AE |
199 | 307 | C7 | 11000111 | Ç | Ç | Ç | Latin capital letter C with cedilla |
200 | 310 | C8 | 11001000 | È | È | È | Latin capital letter E with grave |
201 | 311 | C9 | 11001001 | É | É | É | Latin capital letter E with acute |
202 | 312 | CA | 11001010 | Ê | Ê | Ê | Latin capital letter E with circumflex |
203 | 313 | CB | 11001011 | Ë | Ë | Ë | Latin capital letter E with diaeresis |
204 | 314 | CC | 11001100 | Ì | Ì | Ì | Latin capital letter I with grave |
205 | 315 | CD | 11001101 | Í | Í | Í | Latin capital letter I with acute |
206 | 316 | CE | 11001110 | Î | Î | Î | Latin capital letter I with circumflex |
207 | 317 | CF | 11001111 | Ï | Ï | Ï | Latin capital letter I with diaeresis |
208 | 320 | D0 | 11010000 | Ð | Ð | Ð | Latin capital letter ETH |
209 | 321 | D1 | 11010001 | Ñ | Ñ | Ñ | Latin capital letter N with tilde |
210 | 322 | D2 | 11010010 | Ò | Ò | Ò | Latin capital letter O with grave |
211 | 323 | D3 | 11010011 | Ó | Ó | Ó | Latin capital letter O with acute |
212 | 324 | D4 | 11010100 | Ô | Ô | Ô | Latin capital letter O with circumflex |
213 | 325 | D5 | 11010101 | Õ | Õ | Õ | Latin capital letter O with tilde |
214 | 326 | D6 | 11010110 | Ö | Ö | Ö | Latin capital letter O with diaeresis |
215 | 327 | D7 | 11010111 | × | × | × | Multiplication sign |
216 | 330 | D8 | 11011000 | Ø | Ø | Ø | Latin capital letter O with slash |
217 | 331 | D9 | 11011001 | Ù | Ù | Ù | Latin capital letter U with grave |
218 | 332 | DA | 11011010 | Ú | Ú | Ú | Latin capital letter U with acute |
219 | 333 | DB | 11011011 | Û | Û | Û | Latin capital letter U with circumflex |
220 | 334 | DC | 11011100 | Ü | Ü | Ü | Latin capital letter U with diaeresis |
221 | 335 | DD | 11011101 | Ý | Ý | Ý | Latin capital letter Y with acute |
222 | 336 | DE | 11011110 | Þ | Þ | Þ | Latin capital letter THORN |
223 | 337 | DF | 11011111 | ß | ß | ß | Latin small letter sharp s - ess-zed |
224 | 340 | E0 | 11100000 | à | à | à | Latin small letter a with grave |
225 | 341 | E1 | 11100001 | á | á | á | Latin small letter a with acute |
226 | 342 | E2 | 11100010 | â | â | â | Latin small letter a with circumflex |
227 | 343 | E3 | 11100011 | ã | ã | ã | Latin small letter a with tilde |
228 | 344 | E4 | 11100100 | ä | ä | ä | Latin small letter a with diaeresis |
229 | 345 | E5 | 11100101 | å | å | å | Latin small letter a with ring above |
230 | 346 | E6 | 11100110 | æ | æ | æ | Latin small letter ae |
231 | 347 | E7 | 11100111 | ç | ç | ç | Latin small letter c with cedilla |
232 | 350 | E8 | 11101000 | è | è | è | Latin small letter e with grave |
233 | 351 | E9 | 11101001 | é | é | é | Latin small letter e with acute |
234 | 352 | EA | 11101010 | ê | ê | ê | Latin small letter e with circumflex |
235 | 353 | EB | 11101011 | ë | ë | ë | Latin small letter e with diaeresis |
236 | 354 | EC | 11101100 | ì | ì | ì | Latin small letter i with grave |
237 | 355 | ED | 11101101 | í | í | í | Latin small letter i with acute |
238 | 356 | EE | 11101110 | î | î | î | Latin small letter i with circumflex |
239 | 357 | EF | 11101111 | ï | ï | ï | Latin small letter i with diaeresis |
240 | 360 | F0 | 11110000 | ð | ð | ð | Latin small letter eth |
241 | 361 | F1 | 11110001 | ñ | ñ | ñ | Latin small letter n with tilde |
242 | 362 | F2 | 11110010 | ò | ò | ò | Latin small letter o with grave |
243 | 363 | F3 | 11110011 | ó | ó | ó | Latin small letter o with acute |
244 | 364 | F4 | 11110100 | ô | ô | ô | Latin small letter o with circumflex |
245 | 365 | F5 | 11110101 | õ | õ | õ | Latin small letter o with tilde |
246 | 366 | F6 | 11110110 | ö | ö | ö | Latin small letter o with diaeresis |
247 | 367 | F7 | 11110111 | ÷ | ÷ | ÷ | Division sign |
248 | 370 | F8 | 11111000 | ø | ø | ø | Latin small letter o with slash |
249 | 371 | F9 | 11111001 | ù | ù | ù | Latin small letter u with grave |
250 | 372 | FA | 11111010 | ú | ú | ú | Latin small letter u with acute |
251 | 373 | FB | 11111011 | û | û | û | Latin small letter u with circumflex |
252 | 374 | FC | 11111100 | ü | ü | ü | Latin small letter u with diaeresis |
253 | 375 | FD | 11111101 | ý | ý | ý | Latin small letter y with acute |
254 | 376 | FE | 11111110 | þ | þ | þ | Latin small letter thorn |
255 | 377 | FF | 11111111 | ÿ | ÿ | ÿ | Latin small letter y with diaeresis |
上述来自: https://www.ascii-code.com/
一个简单的计数批处理文件
@echo off
setlocal enabledelayedexpansion
:: 定义计数文件
set counter_file=counter.txt
:: 检查计数文件是否存在
if not exist %counter_file% (
echo 0 > %counter_file%
)
:: 从文件中读取当前计数值
set /p counter=<%counter_file%
:: 显示当前计数值
echo Current counter value: %counter%
:: 将计数值加1
set /a counter+=1
:: 将新的计数值写入文件
echo %counter% > %counter_file%
:: 显示新的计数值
echo New counter value: %counter%
::为了看的清楚,这里加入一个 Pause
pause
endlocal
MAX98357 I2S功放模块测试
之前购买了一个MAX98357 I2S功放模块,这次编写简单的代码进行测试。
硬件连接如下:
MAX98357 | ESP32S3 | 用途 |
SPK+/- 连接喇叭 | 连接喇叭正负极,喇叭输出 | |
DIN | 48 | 从 ESP32S3 发送的 I2S数据 |
BCLK | 45 | 从 ESP32S3 发送的 I2S Clock |
LRC | 35 | 从 ESP32S3 发送的 I2S 左右声道选择信号 |
GND | GND | 地 |
VCC | 5V | 供电 |
按照上述方案连接好后,烧录如下代码:
#include <I2S.h>
const int frequency = 440; // frequency of square wave in Hz
const int amplitude = 32000; // amplitude of square wave
const int sampleRate = 8000; // sample rate in Hz
const int bps = 16;
const int halfWavelength = (sampleRate / frequency); // half wavelength of square wave
short sample = amplitude; // current sample value
int count = 0;
i2s_mode_t mode = I2S_PHILIPS_MODE; // I2S decoder is needed
// i2s_mode_t mode = ADC_DAC_MODE; // Audio amplifier is needed
// Mono channel input
// This is ESP specific implementation -
// samples will be automatically copied to both channels inside I2S driver
// If you want to have true mono output use I2S_PHILIPS_MODE and interlay
// second channel with 0-value samples.
// The order of channels is RIGH followed by LEFT
//i2s_mode_t mode = I2S_RIGHT_JUSTIFIED_MODE; // I2S decoder is needed
void setup() {
Serial.begin(115200);
Serial.println("I2S simple tone");
delay(5000);
//setAllPins(int sckPin, int fsPin, int sdPin, int outSdPin, int inSdPin);
I2S.setAllPins(45 , 35 , 48 , 48 , -1);
// start I2S at the sample rate with 16-bits per sample
if (!I2S.begin(mode, sampleRate, bps)) {
Serial.println("Failed to initialize I2S!");
while (1); // do nothing
}
}
void loop() {
while (Serial.available()) {
char c = Serial.read();
if (c == '3') {
ESP.restart();
}
// 主机端发送 l, 回复 z 用于识别串口
if (c == '1') {
Serial.print('z');
}
// 主机端发送 l, 回复 z 用于识别串口
if (c == '2') {
Serial.printf("getSckPin:%d getFsPin:%d getDataPin:%d",
I2S.getSckPin(),
I2S.getFsPin(),
I2S.getDataPin());
}
}
if (count % halfWavelength == 0 ) {
// invert the sample every half wavelength count multiple to generate square wave
sample = -1 * sample;
}
if(mode == I2S_PHILIPS_MODE || mode == ADC_DAC_MODE){ // write the same sample twice, once for Right and once for Left channel
I2S.write(sample); // Right channel
I2S.write(sample); // Left channel
}else if(mode == I2S_RIGHT_JUSTIFIED_MODE || mode == I2S_LEFT_JUSTIFIED_MODE){
// write the same only once - it will be automatically copied to the other channel
I2S.write(sample);
}
// increment the counter for the next sample
count++;
}
测试的视频在下面可以看到:
WinPE下面制造一个蓝屏
正常的 Windows下面蓝屏很常见,实际上 WinPE 下面也是可以出现蓝屏的。这次介绍通过修改 WinPE 的注册表,实现USB键盘上按下右 Ctrl+快速按下Scroll键即可触发蓝屏 【参考1】。
最关键的步骤是修改 WinPE的注册表,打开这个触发蓝屏的功能。
1.将 Windows安装盘中的 Boot 解压,放在 c:\labz 目录下,然后运行如下命令解包之:
dism /mount-wim /wimfile:c:\labz\boot.wim /index:1 /mountdir:c:\m1
2.打开本机的注册表工具,先选中 HKEY_USERS,然后在菜单上选择 Load Hive
3.在对话框上选择 c:\m1\windows\system32\config\system 文件
4.设置一个加载点
这样操作之后可以看到挂载到如下位置了
5.我们在LABZ\ControlSet001\Services\kbhid\Parameters 下面创建 CrashOnCtrlScroll 并且赋值为1
6.选中注册表上的 “LABZ”,然后菜单选择 Unload Hive,这样就从注册表中卸载了WinPE的注册表
7.之后 关闭注册表编辑器,然后使用如下命令写入 WIM(特别注意,实践中发现有时候无法正常写入,错误信息是 Windows有占用目录下的文件,这种情况下重启操作系统再运行一次即可)
dism /unmount-wim /MountDir:c:\m1 /Commit
8.接下来再次解包 Boot.WIM (原因和之前” 制作全自动安装的 Windows 11 ISO”文章提到的一样,BOOT.WIM 中有2个WindowPE环境)
dism /mount-wim /wimfile:c:\labz\boot.wim /index:2 /mountdir:c:\m1
之后同样执行2-7步骤,最终我们就得到了一个修改后的 BOOT.WIM
使用,ISO 编辑工具将BOOT.WIM 写入 ISO 之后,我们就得到了一个测试 Windows安装镜像文件。在安装过程中使用 USB 键盘,按下右侧Ctrl然后快速按下2测 Scoll 键就能够触发蓝屏了。
可以看到蓝屏发生后,显示一段之后会自动重启。
最后讲个有意思的事情。很多年前,我碰到过一个奇怪的问题:工厂那边反映我们 Release 的BIOS有问题,会导致生产过程中重启。负责这个事情的BIOS工程师是一个妹子,被这个问题折磨很久。问题发生之后,她不修改任何代码,只是重新编译一次BIOS,发给产线使用问题就会消失。但是后面不知道什么时候问题又会出来。出于好奇后来我接手这个问题进行研究。所有的整机无论是笔记本还是台式机,在生产的过程中都会有灌装系统运行产测软件的步骤。在这个过程中,会检查一些基本的功能,比如:是否会有声音,屏幕键盘鼠标能否工作正常等等。这个测试通常需要一气呵成完成的,每个测试都会收集测试结果,然后上报到服务器中的,因此如果发生意外重启会打断整个流程。测试结束后,会重新安装一个新的操作系统然后再交给客户。作为BIOS工程师,我是不太相信BIOS会导致这样的问题。因此,我和工厂要了一下他们的产测软件在实验室进行研究。产线使用 WinPE环境,我手上没有,只能在普通 Windows上试验。试验几次之后,我发现其中的测试软件会出现Windows的报错对话框。于是,将关注点放在了这个软件上。咨询产线得知这个软件的作用是在0xF0000 中搜索一个字符串。听到这里我心里就有了大概,Windows下访问物理内存,出现错误是很重要的。之后和产线要到的源代码,简单读了了一下很快就定位了问题。这个软件需要在物理内存中搜索,于是作者调用了一个 Window API 做了一下映射,将 0xF0000开始的64K物理内存映射到应用程序的内存上,然后用 memcmp 进行查找。发生问题的原因是,要查找的字符串刚好卡在结尾处,比如我们需要在内存中查找“LAB-Z.COM”这个字符串,但是刚好碰到这个字符串在内存中分布如下:
0xFFFFA | 0xFFFFB | 0xFFFFC | 0xFFFFD | 0xFFFFE | 0xFFFFF | 0x10 0000 | 0x10 0001 | 0x10 0002 | 0x10 0003 |
L | A | B | - | Z | . | C | O | M | 0 |
当直接使用 memcpy 查找的时候,它会先找到 “LAB-Z”,但是继续比较字符串剩余部分的时候就碰到“指针出界”的问题。如果在正常的Windows下是可以抛出这个问题继续运行的,但是在WinPE环境下就直接变为重启。最终,经过努力这次的问题没有让BIOS工程师来背锅。
另外多说一句:即便相同的产线,相同的物料,白班和夜班的质量也会有差别。原因是白天人全,技术和后端都在,出了问题会有人处理;夜班的话,人不全,出了问题通常的处理方法是“小车不倒只管推”了。
参考:
1. https://www.lab-z.com/wdbg/ WinDBG 分析键盘生成的 Dump 文件
ASCII数字
因为 UEFI Shell 是 CUI 界面,很多测试需要用 ASCII 显示结果。所以有些时候我们需要足够大的字来展示。
最近偶然发现了这个 ASCII 字体的网站,可以用来取得一些 ASCII 拼凑出来的字形。例如:
░▒▓█▓▒░ ░▒▓██████▓▒░░▒▓███████▓▒░░▒▓████████▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓██▓▒░
░▒▓█▓▒░ ░▒▓████████▓▒░▒▓███████▓▒░ ░▒▓██▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓██▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░
░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓███████▓▒░░▒▓████████▓▒░
__ __ ____ ____
( ) /__\ ( _ \ ___(_ )
)(__ /(__)\ ) _ <(___)/ /_
(____)(__)(__)(____/ (____)
___ ___ ___ ___
/\__\ /\ \ /\ \ /\ \
/:/ / /::\ \ /::\ \ \:\ \
/:/ / /:/\:\ \ /:/\:\ \ \:\ \
/:/ / /::\~\:\ \ /::\~\:\__\ \:\ \
/:/__/ /:/\:\ \:\__\ /:/\:\ \:|__| _______\:\__\
\:\ \ \/__\:\/:/ / \:\~\:\/:/ / \::::::::/__/
\:\ \ \::/ / \:\ \::/ / \:\~~\~~
\:\ \ /:/ / \:\/:/ / \:\ \
\:\__\ /:/ / \::/__/ \:\__\
\/__/ \/__/ ~~ \/__/
有兴趣的朋友可以在这里看到:
http://www.patorjk.com/software/taag/#p=testall&f=Alpha&t=LAB-Z
UEFI TIPS:Print=UnicodeSPrint+ ConOut
最近有在屏幕输出数据的需求,但是无法直接使用 Print 。经过对于 PrintLib 的一番研究,得出了结论:
UEFI Shell 下的Print 的实现可以看作两个动作,一个根据输入格式化得到字符串,另外一个是使用 gST 进行输出。简单的说就是:
Print=UnicodeSPrint+ gST->ConOut->OutputString
编写测试代码:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <Library/PrintLib.h>
extern EFI_SYSTEM_TABLE *gST;
INTN
EFIAPI
ShellAppMain (
IN UINTN Argc,
IN CHAR16 **Argv
)
{
CHAR16 Buffer[32];
UnicodeSPrint((CHAR16 *)Buffer,sizeof(Buffer),L"%x\n",2024);
gST->ConOut->OutputString(gST->ConOut,Buffer);
return(0);
}
运行结果:
如果你在调试 Application 或者Driver遇到无法直接使用 Print 的情况,不妨考虑本文提到的方法。当然,如果你有从串口或者其他设备输出调试数据的时候,也可以考虑UnicodeSPrint()来实现数据格式化方便阅读调试。
一些Unicode 数字符号定义
1.圈中带有数字
⓪ ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳
㉑ ㉒ ㉓ ㉔ ㉕ ㉖ ㉗ ㉘ ㉙ ㉚ ㉛ ㉜ ㉝ ㉞ ㉟ ㊱ ㊲ ㊳ ㊴ ㊵
㊶ ㊷ ㊸ ㊹ ㊺ ㊻ ㊼ ㊽ ㊾ ㊿
2.实心方块中空圆形数字
⓿ ❶ ❷ ❸ ❹ ❺ ❻ ❼ ❽ ❾ ❿
⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
3.实心方块数字
⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾
4.中文
㊀ ㊁ ㊂ ㊃ ㊄ ㊅ ㊆ ㊇ ㊈ ㊉
来源:http://xahlee.info/comp/unicode_circled_numbers.html
此外,在 https://altcodeunicode.com/alt-codes-circled-number-letter-symbols-enclosed-alphanumerics/ 还有一些圆圈的英文序号
制作全自动安装的 Windows 11 ISO
前面提 到通过应答文件来实现自动安装【参考1】,使用这个方法在虚拟机上测试正常,但是实体机上在分区拷贝完成之后会进入OOBE的界面要求手工选择,因此并非全自动安装。
针对这个问题进行了更深入的研究,原来除了在安装盘下面放置autounattend.xml 之外,在对应的 WinPE 盘,Windows\Panther 目录下还需要放置一个 unattend.xml 应答文件。更具体的操作是,安装 ADK
1。解压Windows 11 安装 ISO
2.取出其中的 boot.wim 文件
3.在 “Deployment and Imaging Tools Environment”中使用如下命令解压 Boot.WIM 到 m1 目录下
dism /mount-wim /wimfile:c:\LABZ\boot.wim /index:1 /mountdir:c:\m1
4.将unattend.xml拷贝到 m1\Windows\Panther目录下
5.将修改回写到 boot.wim 中
dism /unmount-wim /MountDir:c:\m1 /Commit
6.同样在 “Deployment and Imaging Tools Environment”中再次解压 Boot.WIM 到 m1 目录下(Boot 中有个 Index,上一次用的是 1,这次用的是 2)
dism /mount-wim /wimfile:c:\LABZ\boot.wim /index:2 /mountdir:c:\m1
7.将unattend.xml拷贝到 m1\Windows\Panther目录下
8.将修改回写到 boot.wim 中
dism /unmount-wim /MountDir:c:\m1 /Commit
这样就有了一个更换过 unattend.xml的Boot.WIM 其中是一个完整的 WinPE 环境,接下来使用工具将Boot.WIM替换回原始的安装 ISO。最终我们就有了一个全自动的Window安装盘。
这样的ISO通过 Refuse或者Ventoy 制作出来的启动U盘上都可以正常启动,并且能够做到完全自动的安装。
本文提到的制作好的 Windows 11 可以在这里下载(文件超过4G, 分割为2个ZIP 压缩文件)
对应的2个 xml 文件可以在这里下载:
参考:
1. https://www.lab-z.com/winut/
测试的视频,在 LattePanda MU 上进行的测试: