利用微控制器套件快速实现“内置 Alexa”的物联网设计
投稿人:DigiKey 北美编辑
2020-02-11
语音助手已经迅速发展成为几乎所有智能产品的重要特性。在当前基于云的解决方案中,Amazon 的 Alexa Voice Service (AVS) 已成为占主导地位的语音助手,为利用 Amazon 云资源进行语音识别和自然语言处理提供了“交钥匙”式整套解决方案。
然而,对于开发人员而言,AVS 的性能要求和设计复杂性经证实是重大的入门障碍,让他们很难着手开发面向互联家居和物联网 (IoT) 的基于小型微处理器的设备。NXP Semiconductors 专门针对资源受限的设备设计了一款 Amazon AVS 产品套件,旨在为定制应用提供一种直接置入式解决方案和参考设计。
本文介绍开发人员如何使用 NXP 提供的即用型解决方案来快速实现“内置 Alexa”设计。
什么是 AVS?
自从十年前问世以来,语音助手技术发展迅速,带动了智能音箱市场的增长。市场分析人士估计,该市场已经覆盖了美国三分之一的人口。在众多竞争解决方案中,Amazon Echo 智能音箱已取得主导地位,其依托 Amazon Web Services (AWS) 的成功提供基于云的资源,来支持第三方 Echo 应用或 Skills(技能)。
运用 Alexa Skills Kit (ASK) 和相关应用编程接口 (API),开发人员可以利用 Echo 智能音箱快速扩大的安装基数,为其连接的设备添加某种程度的语音控制。通过这种办法,“Alexa 配套”的智能电视或恒温器之类的互联产品,可以响应用户语音请求以及从 Alexa 云收到的相关指令(图 1)。下图简要概述了 AVS 及其潜力。
图 1:通过构建 Alexa 应用或 Skills,开发人员可以让互联产品透过 Amazon Echo 产品与用户的语音命令进行交互。(图片来源:Amazon Web Services)
内置 Alexa 设计
与“Alexa 配套”的产品相比,“内置 Alexa”的智能产品在支持 Alexa 语音的设备和 AWS 资源之间实现了更加无缝流畅的低延迟接口。这些产品将 AVS 直接集成到互联设备设计中。通过将 AVS 与 AWS IoT Core 平台结合使用,开发人员可以实现复杂的物联网应用,使用户能够对支持 Alexa 的产品使用语音命令,既可控制互联设备,也可从这些设备接收语音响应(图 2)。
图 2:支持 Alexa 的设备为用户提供语音接口来控制设备(上图),或从通过 AWS IoT Core 连接到 Amazon Web Services 资源的物联网设备(下图)接收通知。(图片来源:Amazon Web Services)
但在过去,支持 Alexa 的设备是这种物联网应用的核心,其设计需要开发人员自己进行大量的工作。要使用基于云的 Alexa 服务,设备需要运行多个 AVS 服务库,从而检测唤醒词,与 Alexa 云通信,并处理所支持功能的指令;其中这些库通过在 Android 或 Linux 平台上运行的 AVS 设备软件开发套件 (SDK) 来提供(图 3)。
图 3:此图显示了 AVS Device SDK 的组件及其数据流动方式。(图片来源:Amazon Web Services)
为了支持这些服务库,支持 Alexa 的设备设计通常需要高性能的应用处理器和至少 50 MB 的内存,才能满足 AVS 处理需求。此外,这些设计常常会采用数字信号处理器 (DSP) 来执行复杂的算法,以便从嘈杂的环境中提取语音音频,并支持语音助手设备必需的远场语音功能。最终,为了构建一款支持 Alexa 的有效设备,其系统要求通常远远超出了实际物联网设备的成本和复杂性水平。
不过,Amazon 通过发布适用于 AWS IoT Core 的 AVS 集成服务,大大降低了实现内置 Alexa 产品所需的处理器工作负荷和内存使用量。借助此服务,计算和内存密集型任务将从支持 Alexa 的设备转移到云中相关联的虚拟设备(图 4)。
图 4:AVS for AWS IoT Core 将内存和处理密集型任务转移到云中,从而支持在资源受限的物联网设备上实现 Alexa 语音助手功能。(图片来源:Amazon Web Services)
物理设备的处理任务经减少后可提供更多基本服务,例如安全消息传递、往返 Alexa 的可靠音频数据传输、任务管理、在设备内以及使用 Alexa 发送事件通知。物理设备与 Alexa 之间的数据、命令、通知的传输通过高效 MQTT(MQ 遥测传输)消息传递进行,并采用 MQTT 发布-订阅协议中的一些保留主题。最后,配套移动应用与 Alexa 云进行交互,完成设备注册,并让用户与支持 Alexa 的设备进行任何其他需要的交互。
通过将繁重的处理转移到云端,AVS for AWS IoT Core 支持嵌入式系统开发人员利用更熟悉的平台来创建内置 Alexa 产品。开发人员可以使用在实时操作系统 (RTOS) 软件上运行且内存少于 1 MB 的更适中微控制器来实现这些设计,而不是在 Linux 或 Android 上运行且内存为 50 MB 的应用处理器。事实上,与在本地运行全套 AVS 服务的设计相比,采用 AVS for AWS IoT Core 构建的 Alexa 设计可将所需物料减少 50%。
尽管 AVS for AWS IoT Core 支持更具成本效益的运行时平台,但要实现一款经过认证的内置 Alexa 产品,仍是一项复杂的任务。对于刚接触 AVS 和 IoT Core 的开发人员,可能需要相当长一段时间的学习才能掌握 AWS 对安全性、通信、帐户管理、用户体验 (UX) 设计等方面的要求。无论对 AWS 生态系统的熟悉程度如何,所有 Alexa 产品开发人员都必须确保设计满足一套冗长的规范和要求,否则将无法获得 Amazon Alexa 认证。
NXP 基于微控制器的 Alexa 解决方案提供一种“交钥匙”式整套系统解决方案,完全实现了 Amazon AVS for AWS IoT Core 的设备端硬件和软件要求。
基于微控制器的 Alexa 解决方案
NXP 的 SLN-ALEXA-IOT AVS 套件围绕 NXP i.MX RT106A 微控制器构建,提供立即可用的 AWS 连接、AVS 认证的远场音频算法、回声消除、Alexa 唤醒词功能以及应用代码。该套件的 i.MX RT106A 微控制器基于 Arm Cortex-M7 内核,属于 NXP i.MX RT106x 跨界处理器系列,专门针对物联网边缘计算而设计。RT106A 面向嵌入式语音应用而打造,在 NXP i.MX RT1060 跨界处理器系列的基础架构之上增加了特殊功能,该架构包含全套外设接口、丰富的内部存储器并广泛支持外部存储器选项(图 5)。
图 5:NXP i.MX RT1060 跨界处理器系列集成了 Arm Cortex-M7 微控制器内核与全套外设接口、存储器及其他功能,满足物联网设备的典型需求。(图片来源:NXP)
凭借集成功能,i.MX RT106A 微控制器仅需很少几个附加元器件,就能提供实现 AWS IoT Core AVS 所需的硬件基础。NXP 的 SLN-ALEXA-IOT 套件将 i.MX RT106A 微控制器与 256 Mb 闪存、Murata Electronics 的 LBEE5KL1DX Wi-Fi/蓝牙收发器模块、Diodes 的 AP2202K-3.3TRG1 降压转换器集成在一个系统模块中(图 6)。
图 6:NXP 的 SLN-ALEXA-IOT AVS 套件系统模块的设计利用简单的硬件接口,将 NXP i.MX RT106A 微控制器与外部闪存和无线收发器集成在一起。(图片来源:NXP)
作为对该系统模块的补充,SLN-ALEXA-IOT 套件中的语音板提供三个 Knowles SPH0641LM4H-1 脉冲密度调制 (PDM) MEMS 麦克风、一个 PUI Audio AS01808AO 扬声器和一个 NXP TFA9894D D 类音频放大器。此外,语音板提供了一个 USB C 型连接器,用于为套件供电以及从个人计算机运行 Shell 控制台,并提供了用于以太网、串行外设、i.MX RT106A 微控制器通用输入/输出 (GPIO) 的接头。最后,该板含有用于基本控制输入的开关,以及用于视觉反馈的 LED;这些 LED 使用不同的 LED 颜色和开/关循环模式,符合 Amazon AVS UX Attention System 的要求。
通过系统模块和语音板,SLN-ALEXA-IOT 硬件为 AVS for AWS IoT Core 软件的设备端处理提供了完整的平台。但是,如前所述,支持 Alexa 的物联网设备设计不仅取决于硬件,同样取决于优化的软件。若利用 Amazon 的 AVS for AWS IoT API 从头开始开发该软件,可能会使项目严重拖期,因为开发人员需要完成构建所需数据对象和实现相关协议的全过程。在此过程中,为了争取“内置 Alexa”认证,开发人员须努力遵守 AVS UX Attention System、AWS 安全实践以及设计中其他涉及用户与 Alexa 服务交互的各个方面要求,这可能会导致进一步延迟。NXP 利用基于 Amazon FreeRTOS 的综合运行时语音控制软件环境解决了这些问题,该环境构建在一个软件驱动层之上,支持芯片内执行 (XIP) 闪存、连接性和其他硬件组件(图 7)。
图 7:NXP 语音控制系统环境基于 Amazon FreeRTOS 构建,提供广泛的中间件服务组合,包括用于机器学习推理和音频前端处理的固件例程。(图片来源:NXP)
该软件环境的语音处理功能基础是 NXP 的 Intelligent Toolbox 固件,其为所有音频任务提供优化的功能,其中包括机器学习 (ML) 推理引擎和 ML 音频前端,可用于对音频信号进行调节与优化。其他中间件服务支持安全连接、AWS 通信和音频功能。在此综合服务层之上,用于 AWS IoT Core、入网及其他应用控制功能的软件会协调两阶段引导程序的启动,并支持基于 AWS IoT OTA 服务和 Amazon FreeRTOS OTA 客户端构建的空中 (OTA) 更新。
利用在此环境上运行的出厂安装软件,开发人员可以立即启动带有完整 Alexa 应用的 SLN-ALEXA-IOT 硬件套件,该应用可使用 NXP 的 AWS IoT 演示帐户。NXP 说明文档提供了详细的攻略,说明了启动套件、提供 Wi-Fi 凭证以及使用演示帐户完成 AWS 设备身份验证的全过程。作为此过程的一部分,开发人员利用软件分发包中包含的 Android 移动应用与该套件和 AWS 交互,而该分发包可使用每个 SLN-ALEXA-IOT 套件随附的激活码从 NXP 网站获得。经过一些简单的步骤,开发人员便可立即通过 Echo 智能音箱提供的同类 Alexa 语音交互指令,开始与该套件进行互动。
为了快速开发具备 Alexa 能力的产品原型,SLN-ALEXA-IOT 套件和出厂安装的软件提供了现成的平台。同时,该套件的硬件和软件可作为快速开发平台来创建基于 i.MX RT106A 微控制器的定制 Alexa 设计。
定制开发
基于 i.MX RT106A 的 Alexa 解决方案的软件可通过 NXP MCU Alexa Voice IoT SDK 来利用 NXP 语音控制运行时环境的能力;该 SDK 是软件分发包的一部分,产品激活后即可使用。该 SDK 设计为 NXP 基于 Eclipse 的 MCUXpresso 集成开发环境 (IDE) 的附加组件,集合了样例应用、驱动程序和中间件的完整源代码,以及用于专用固件功能(例如 NXP Intelligent Toolbox,ML 推理引擎和 ML 音频前端)的二进制分发的头文件。
若需要快速部署支持 Alexa 的产品,开发人员原则上只需加以少量修改,即可使用完整的 Alexa 演示应用。在最简单的情况下,开发人员只需利用自己的安全凭证将应用重新定位到自己的 AWS 帐户,即可完成修改。NXP 提供了关于如何完成此过程的分步说明。
对于定制开发,软件分发包中的样例应用提供了可执行范例,其中说明如何使用 NXP MCU Alexa Voice IoT SDK。开发人员不是直接扎进完整 Alexa 演示应用,而是可以探索样例应用,以便能够更加专注于特定能力,包括音频前端、Wi-Fi 和蓝牙连接、引导加载等。例如,音频前端样例应用说明了使用 Amazon FreeRTOS 任务执行唤醒词检测的基本设计模式。
在音频前端样例应用中,主例程演示了开发人员如何初始化硬件和软件子系统,再利用 FreeRTOS xTaskCreate 函数启动主应用任务 (appTask) 和控制台 Shell 任务 (sln_shell_task),然后将控制权释放给 FreeRTOS 调度程序(清单 1)。(注意:仅当 FreeRTOS 调度程序缺少足够的内存时,对启动该调度程序的 vTaskStartScheduler 调用才会返回。)
复制 void main(void) { /* Enable additional fault handlers */ SCB->SHCSR |= (SCB_SHCSR_BUSFAULTENA_Msk | /*SCB_SHCSR_USGFAULTENA_Msk |*/ SCB_SHCSR_MEMFAULTENA_Msk); /* Init board hardware.*/ BOARD_ConfigMPU(); BOARD_InitBootPins(); BOARD_BootClockRUN(); ...RGB_LED_Init(); RGB_LED_SetColor(LED_COLOR_GREEN); sln_shell_init(); xTaskCreate(appTask, "APP_Task", 512, NULL, configMAX_PRIORITIES - 1, &appTaskHandle); xTaskCreate(sln_shell_task, "Shell_Task", 1024, NULL, tskIDLE_PRIORITY + 1, NULL); /* Run RTOS */ vTaskStartScheduler(); ...}
清单 1:NXP MCU Alexa Voice IoT SDK 发行版中包含一个音频前端应用样例,演示了基本初始化要求以及主应用任务和控制台 Shell 任务的 FreeRTOS 任务创建。(代码来源:NXP)
初始化音频子系统之后,主应用任务 appTask 进而启动一对 FreeRTOS 任务。一个任务运行处理音频输入的服务例程 audio_processing_task,而另一个任务处理麦克风 PDM 输出到脉冲编码调制 (PCM) 的转换。经过其他内务处理后,appTask 进入一个无限循环,等待 RTOS 通知已检测到唤醒词(清单 2)。
复制 void appTask(void *arg) { ...// Create audio processing task if (xTaskCreate(audio_processing_task, "Audio_processing_task", 1536U, NULL, audio_processing_task_PRIORITY, &xAudioProcessingTaskHandle) != pdPASS) ...// Create pdm to pcm task if (xTaskCreate(pdm_to_pcm_task, "pdm_to_pcm_task", 1024U, NULL, pdm_to_pcm_task_PRIORITY, &xPdmToPcmTaskHandle) != pdPASS) ...RGB_LED_SetColor(LED_COLOR_OFF); SLN_AMP_WriteDefault(); uint32_t taskNotification = 0; while (1) { xTaskNotifyWait(0xffffffffU, 0xffffffffU, &taskNotification, portMAX_DELAY); switch (taskNotification) { case kWakeWordDetected: { RGB_LED_SetColor(LED_COLOR_BLUE); vTaskDelay(100); RGB_LED_SetColor(LED_COLOR_OFF); break; } default: break; } taskNotification = 0; } }
清单 2:在音频前端应用样例中,主应用任务 appTask 启动任务以进行音频处理和麦克风数据转换,然后等待 FreeRTOS 通知 (taskNotification) 已检测到唤醒词 (kWakeWordDetected)。(代码来源:NXP)
此样例应用中的音频处理任务进而初始化唤醒词固件函数,并初始化唤醒词检测参数,然后也进入一个无限循环,等待麦克风数据转换任务提供 FreeRTOS 通知:处理好的麦克风数据已经可用。接到通知后,音频处理任务调用 Intelligent Toolbox 固件函数,以利用 ML 推理引擎处理音频数据并执行唤醒词检测(清单 3)。
复制 void audio_processing_task(void *pvParameters) { ...SLN_AMAZON_WAKE_Initialize(); SLN_AMAZON_WAKE_SetWakeupDetectedParams(&wakeWordActive, &wwLen); while (1) { // Suspend waiting to be activated when receiving PDM mic data after Decimation xTaskNotifyWait(0U, ULONG_MAX, &taskNotification, portMAX_DELAY); ...// Process microphone streams int16_t *pcmIn = (int16_t *)((*s_micInputStream)[pingPongIdx]); SLN_Voice_Process_Audio(g_externallyAllocatedMem, pcmIn, &s_ampInputStream[pingPongAmpIdx * PCM_SINGLE_CH_SMPL_COUNT], &cleanAudioBuff, NULL, NULL); // Pass output of AFE to wake word SLN_AMAZON_WAKE_ProcessWakeWord(cleanAudioBuff, 320); taskNotification &= ~currentEvent; if (wakeWordActive) { wakeWordActive = 0U; // Notify App Task Wake Word Detected xTaskNotify(s_appTask, kWakeWordDetected, eSetBits); } } }
清单 3:在音频前端应用样例中,音频处理任务初始化固件唤醒词引擎,等待 FreeRTOS 通知麦克风数据已经可用,最后调用 NXP Intelligent Toolbox 固件模拟前端 (SLN_Voice_Process_Audio) 和 ML 推理引擎 (SLN_AMAZON_WAKE_ProcessWakeWord) 进行唤醒词检测。(代码来源:NXP)
检测到唤醒词之后,音频处理任务发出 FreeRTOS 任务通知,以将该事件告知主应用任务 appTask。收到该通知后,appTask 会立即使蓝光 LED 闪烁(同样参见清单 2)。
完整的 Alexa 样例应用依赖与简单音频前端应用相同的模式,但大幅扩展了该基本代码库以支持完整的 Alexa 功能。例如,在 Alexa 应用样例中,当 ML 推理引擎检测到唤醒词之后,音频处理任务会发出一系列与 Alexa 处理序列中每个阶段相关的 FreeRTOS 通知(清单 4)。
复制 void audio_processing_task(void *pvParameters) { ...SLN_AMAZON_WAKE_Initialize(); SLN_AMAZON_WAKE_SetWakeupDetectedParams(&u8WakeWordActive, &wwLen); while (1) { // Suspend waiting to be activated when receiving PDM mic data after Decimation xTaskNotifyWait(0U, ULONG_MAX, &taskNotification, portMAX_DELAY); ...int16_t *pcmIn = (int16_t *)((*s_micInputStream)[pingPongIdx]); SLN_Voice_Process_Audio(g_w8ExternallyAllocatedMem, pcmIn, &s_ampInputStream[pingPongAmpIdx * PCM_SINGLE_CH_SMPL_COUNT], &pu8CleanAudioBuff, NULL, NULL); SLN_AMAZON_WAKE_ProcessWakeWord((int16_t*)pu8CleanAudioBuff, 320); taskNotification &= ~currentEvent; // If devices is muted, then skip over state machine if (s_micMuteMode) { if (u8WakeWordActive) { u8WakeWordActive = 0U; } memset(pu8CleanAudioBuff, 0x00, AUDIO_QUEUE_ITEM_LEN_BYTES); } if (u8WakeWordActive) { configPRINTF(("Wake word detected locally\r\n")); } // Execute intended state switch (s_audioProcessingState) { case kIdle: /* add clean buff to cloud wake word ring buffer */ continuous_utterance_samples_add(pu8CleanAudioBuff, PCM_SINGLE_CH_SMPL_COUNT * PCM_SAMPLE_SIZE_BYTES); if (u8WakeWordActive) { continuous_utterance_buffer_set(&cloud_buffer, &cloud_buffer_len, wwLen); u8WakeWordActive = 0U; wwLen = 0; // Notify App Task Wake Word Detected xTaskNotify(s_appTask, kWakeWordDetected, eSetBits); // App Task will now determine if we begin recording/publishing data } break; ...case kWakeWordDetected: audio_processing_reset_mic_capture_buffers(); // Notify App_Task to indicate recording xTaskNotify(s_appTask, kMicRecording, eSetBits); if (s_audioProcessingState != kMicRecording) { s_audioProcessingState = kMicCloudWakeVerifier; } configPRINTF(("[audio processing] Mic Recording Start.\r\n")); // Roll into next state case kMicCloudWakeVerifier: case kMicRecording: micRecordingLen = AUDIO_QUEUE_ITEM_LEN_BYTES; if (u8WakeWordActive) { u8WakeWordActive = 0U; } // Push data into buffer for consumption by AIS task status = audio_processing_push_mic_data(&pu8CleanAudioBuff, &micRecordingLen); ...} }
清单 4:在完整的 Alexa 应用中,音频处理任务会使用额外的代码来增强音频前端应用中执行的处理步骤,以管理 Alexa 序列中的后续音频处理阶段。(代码来源:NXP)
在检测到本地 ML 唤醒词之后,完整 Alexa 应用的音频处理任务按照上文所述通知主应用任务。此外,现在它必须管理音频处理状态,确保麦克风保持开启以捕获完整音频输入,然后送到 Alexa 云端进行语音处理,同时不丢失包含本地检测到的唤醒词的原始数据流。完整数据流传送到 Alexa 云端进行唤醒词验证以及进一步的语音处理。
在该处理序列的每个阶段,音频处理任务都会向主应用任务发出相应的 FreeRTOS 通知。同音频处理任务一样,完整 Alexa 应用扩展了音频前端应用中以更简单格式呈现的主应用任务模式。在这里,完整 Alexa 应用的主应用任务 appTask 既生成要传输到 Alexa 云的事件,也生成根据 Amazon AVS UX Attention System 要求管理套件 LED 的事件。例如,当检测到唤醒词之后麦克风保持开启时,音频处理任务会通知主应用任务,后者设置适当的 UX 注意状态(深绿色 LED 指示器)(参见清单 5 中的黄色突出显示部分和清单 4 中相应的突出显示部分)。
复制 void appTask(void *arg) { ...// Create audio processing task if (xTaskCreate(audio_processing_task, "Audio_proc_task", 1536U, NULL, audio_processing_task_PRIORITY, &xAudioProcessingTaskHandle) != pdPASS) ...// Create pdm to pcm task if (xTaskCreate(pdm_to_pcm_task, "pdm_to_pcm_task", 512U, NULL, pdm_to_pcm_task_PRIORITY, &xPdmToPcmTaskHandle) != pdPASS) ...while(1) { xTaskNotifyWait( ULONG_MAX, ULONG_MAX, &taskNotification, portMAX_DELAY ); if (kIdle & taskNotification) { // Set UX attention state ux_attention_set_state(uxIdle); taskNotification &= ~kIdle; } if (kWakeWordDetected & taskNotification) { if (reconnection_task_get_state() == kStartState) { if (!AIS_CheckState(&aisHandle, AIS_TASK_STATE_MICROPHONE)) { // Set UX attention state ux_attention_set_state(uxListeningStart); ...// Begin sending speech micOpen.wwStart = aisHandle.micStream.audio.audioData.offset + 16000; micOpen.wwEnd = aisHandle.micStream.audio.audioData.offset + audio_processing_get_wake_word_end(); micOpen.initiator = AIS_INITIATOR_WAKEWORD; AIS_EventMicrophoneOpened(&aisHandle, &micOpen); // We are now recording audio_processing_set_state(kWakeWordDetected); } } else { ux_attention_set_state(uxDisconnected); audio_processing_set_state(kReconnect); } taskNotification &= ~kWakeWordDetected; } ...if (kMicRecording & taskNotification) { // Set UX attention state and check if mute is active // so we don't confuse the user if (audio_processing_get_mic_mute()) { ux_attention_set_state(uxMicOntoOff); } else { ux_attention_set_state(uxListeningActive); } taskNotification &= ~kMicRecording; } ...
清单 5:在完整的 Alexa 应用中,主应用任务掌控 Alexa 处理序列,包括按照 Alexa 认证要求控制 LED 灯。(代码来源:NXP)
同样,完整 Alexa 应用中的主例程扩展了音频前端应用中以更简单方式演示的模式。在这种情况下,主应用还会创建其他 FreeRTOS 任务来执行更具体的初始化程序,以及处理套件按钮和支持 OTA 更新的任务。
以这些样例应用为基础,开发人员可以信心十足地在自己的 i.MX RT106A 设计中,利用 NXP MCU Alexa Voice IoT SDK 实现“内置 Alexa”功能。由于该执行平台充分利用了 AVS for AWS IoT Core,因此以日益复杂的物联网应用为基础,开发人员能够更广泛地在低成本且资源受限的设备中部署支持 Alexa 的解决方案。
总结
语音助手功能推动 Echo 智能音箱快速增长,而 Amazon Alexa Voice Service 则使开发人员能够实现这一功能。过去,产品要获得梦寐以求的“内置 Alexa”认证,必须使用具有大量本地内存和高性能处理能力的执行平台。NXP 的一款套件采用 AVS for AWS IoT Core 构建,为使用微控制器和相关软件执行环境实现“内置 Alexa”功能提供了一种直接置入式解决方案。
免责声明:各个作者和/或论坛参与者在本网站发表的观点、看法和意见不代表 DigiKey 的观点、看法和意见,也不代表 DigiKey 官方政策。