STM32 BIN文件编程与应用:从代码到烧录的全过程
简介:STM32的BIN文件是嵌入式系统开发中的关键概念,涉及到微控制器编程的各个环节。本文将深入探讨STM32微控制器系列及其BIN文件的生成和应用,包括编译、链接、生成BIN文件的步骤,以及编程和固件更新的技术细节。通过理解并应用BIN文件,开发者可以更加高效地进行STM32相关的嵌入式项目开发。 
1. STM32微控制器概述
STM32微控制器是STMicroelectronics(意法半导体)推出的一款广泛使用的32位ARM Cortex-M系列微控制器。它们基于高性能的ARM Cortex-M0、M3、M4和M7核心,并具有多种功能强大的外设,适用于工业控制、医疗设备、消费电子和各种物联网应用。
1.1 STM32微控制器的特点
- 性能 : STM32基于Cortex-M系列处理器,提供不同性能等级,满足从低功耗应用到高性能需求。
- 丰富的外设 : 拥有多种集成外设,如ADC、DAC、定时器、通信接口(如I2C、SPI、USART),以及支持CAN、USB等高级通信协议。
- 节能模式 : STM32的低功耗模式非常适合于电池供电设备,可大幅降低功耗,延长设备运行时间。
1.2 STM32的应用领域
由于其广泛的性能范围和丰富的功能集,STM32微控制器在多个行业找到了应用,包括:
- 工业自动化 : 实现复杂的传感器数据采集、控制逻辑、电机控制等。
- 医疗设备 : 用于病人监护、诊断设备等。
- 智能建筑 : 用于HVAC控制、照明控制、安全系统等。
- 消费电子 : 家用电器、个人电子设备、健身器材等。
- 物联网 : 智能家居、智慧城市、环境监测等应用中,STM32以其高性价比和灵活性脱颖而出。
随着物联网的发展,STM32微控制器在连接性、安全性以及功耗管理方面的持续演进,使其在未来保持了持续的市场增长潜力。了解STM32微控制器的架构和开发环境对于设计和优化嵌入式系统至关重要。
2. BIN文件在嵌入式系统中的作用
2.1 BIN文件的定义与特点
2.1.1 BIN文件的格式解析
BIN文件通常是一种二进制文件格式,它包含可以直接加载到内存中的数据。在嵌入式系统领域,BIN文件常常用于存储可执行程序代码和数据,这些代码和数据经过编译和链接,被转化为机器可以理解的指令。BIN文件不包含任何头部信息,比如可执行文件常见的PE(Portable Executable)或ELF(Executable and Linkable Format)格式的头部,因此它们不能被操作系统直接识别和执行。
BIN文件通常通过编程器或调试器烧录到微控制器中执行。在STM32微控制器中,BIN文件可以看作是微控制器的固件,它包含了启动程序(Bootloader)、应用代码、常量数据和变量数据等。
flowchart LR
A[源代码] -->|编译| B[目标代码]
B -->|链接| C[可执行文件]
C -->|烧录工具处理| D[BIN文件]
D -->|烧录到微控制器| E[微控制器执行]
在上述流程中,我们首先将源代码(C/C++语言等)编译成目标代码(.o文件),然后通过链接器将各个目标文件和库文件链接成一个完整的可执行文件。最后,我们使用烧录工具将可执行文件转化成BIN格式,烧录到微控制器中执行。
2.1.2 BIN文件与可执行程序的关系
BIN文件与可执行程序是密切相关的,但它们在存储形式上有本质的区别。在桌面操作系统中,可执行程序通常包含了大量的元数据,例如入口点地址、文件头信息、节表、重定位信息等,以便于操作系统加载和执行程序。而BIN文件则省略了这些信息,只保留了机器语言指令和数据,需要通过其他方式(如Bootloader)加载到内存中执行。
在嵌入式开发中,BIN文件以其纯粹的二进制形式能够方便地烧录到设备的存储介质中,例如闪存(Flash)或只读存储器(ROM)。开发人员可以利用编程器直接烧录BIN文件,而不必担心操作系统的干扰,从而简化了嵌入式设备的启动和运行过程。
2.2 BIN文件在嵌入式开发中的角色
2.2.1 程序部署与执行流程
在嵌入式开发流程中,BIN文件扮演着程序部署的关键角色。一旦开发人员完成了软件的编码、编译和链接,就会得到一个BIN文件。这个文件将被部署到微控制器或嵌入式设备上,启动设备的运行。以下是程序部署与执行的一个典型流程:
- 开发环境构建 :安装并配置好交叉编译工具链和相应的IDE。
- 编写源代码 :使用C/C++等语言编写微控制器的程序代码。
- 编译和链接 :将源代码编译成机器代码并链接成一个可执行文件。
- 转换为BIN文件 :使用工具将可执行文件转换成BIN格式。
- 部署BIN文件 :通过编程器或调试器将BIN文件烧录到目标硬件的存储介质中。
- 启动与执行 :设备启动时,Bootloader从指定的存储区域加载BIN文件到RAM中执行。
graph LR
A[开发环境构建] --> B[编写源代码]
B --> C[编译和链接]
C --> D[转换为BIN文件]
D --> E[部署BIN文件]
E --> F[启动与执行]
在部署和执行流程中,BIN文件直接决定了微控制器能够执行的功能,因此它是嵌入式系统开发中的核心组件。
2.2.2 BIN文件与固件更新的关联
BIN文件的另一个重要作用是与固件更新相关联。在产品开发周期中,固件更新是一个常见的需求,用以修复bug或增加新功能。BIN文件可以通过不同的方式传输到设备上,进行更新操作。对于STM32微控制器,BIN文件的更新可以通过以下几种途径:
- JTAG/SWD接口 :使用JTAG或SWD接口通过ST-Link等调试器进行更新。
- 串行端口 :通过UART等串行端口进行BIN文件的上传和更新。
- OTA(Over-The-Air)更新 :通过无线网络下载新的BIN文件,并在设备上进行更新。
固件更新功能的实现通常涉及到Bootloader的设计和编程。Bootloader是微控制器上运行的一个小的引导程序,它在系统启动时先于应用代码执行,负责检查固件版本、执行更新过程或引导主程序执行。BIN文件的更新需要Bootloader正确解析和烧录新的 BIN 文件,同时保证更新过程中的稳定性和安全性。
graph LR
A[检查固件版本] -->|需要更新| B[Bootloader下载新BIN]
B --> C[验证新BIN文件]
C -->|验证成功| D[更新BIN文件]
C -->|验证失败| E[终止更新]
D --> F[重启设备并加载新固件]
在上述流程中,Bootloader起到了关键作用。在执行更新之前,Bootloader会验证新固件的合法性,然后在确认无误后更新BIN文件,并在更新完成后重启设备加载新固件。
总结而言,BIN文件在嵌入式系统中担当着不可或缺的角色,它既是程序部署的最终形态,又是固件更新过程中的关键元素。了解BIN文件的格式解析、程序部署与执行流程以及与固件更新的关联,对于任何想要深入嵌入式开发领域的工程师来说都是基础且至关重要的。
3. STM32开发过程中的编程模式
3.1 嵌入式C语言编程基础
3.1.1 C语言在嵌入式系统中的地位
C语言以其高效率和灵活性在嵌入式系统开发中占据了非常重要的地位。在STM32微控制器的开发中,C语言不仅允许开发者实现对硬件的精细控制,同时也提供了足够的抽象层,以支持模块化和可维护的代码开发。与汇编语言相比,C语言的代码更加易于阅读和维护,同时编译后的程序具有较好的执行效率。因此,掌握嵌入式C语言对于STM32开发至关重要。
3.1.2 STM32专用的C语言扩展
在标准C语言的基础上,针对STM32微控制器的特殊功能和硬件特性,ARM提供了专有的C语言扩展。这些扩展包括了对寄存器直接访问的指针类型、特殊功能寄存器的定义和访问方式,以及针对特定硬件结构的内置函数等。开发者可以利用这些扩展,编写更加简洁、高效且直接与硬件交互的代码。例如,通过使用指针直接访问寄存器,可以实现对中断管理器、外设配置寄存器等的直接控制。
3.2 编程模式的分类与应用
3.2.1 寄存器级编程
在嵌入式系统开发中,寄存器级编程是指直接通过读写硬件寄存器来控制硬件设备。这种编程模式通常用于性能要求极高或者需要精细控制硬件的场景。例如,在STM32中,通过操作GPIO(通用输入输出)寄存器来控制引脚的高低电平,或者配置串口的波特率等。
// 示例代码:寄存器级编程设置GPIO模式为输出
#define GPIOA_MODER_REG (*(volatile uint32_t *)0x48000000)
#define GPIOA_ODR_REG (*(volatile uint32_t *)0x48000014)
void GPIO_SetOutputMode(uint16_t PinNumber) {
uint32_t baseAddress = GPIOA_MODER_REG;
uint32_t shiftAmount = (PinNumber * 2);
uint32_t mask = ~(0x3 << shiftAmount);
uint32_t modeValue = (0x1 << shiftAmount);
baseAddress &= mask; // 清除对应位
baseAddress |= modeValue; // 设置为输出模式
GPIOA_MODER_REG = baseAddress; // 写入新值到寄存器
}
在上述代码中,我们通过定义寄存器的地址并操作它们来配置GPIO模式。每个寄存器地址都映射到特定的硬件功能。这种方式的编程需要对STM32的硬件架构有深入的理解,以及对性能要求非常高的场合。
3.2.2 库函数编程
库函数编程是指利用库函数来进行硬件操作的一种编程方式。STM32的库函数通常分为标准外设库和硬件抽象层(HAL)库。标准外设库提供了一组封装好的函数,用于简化硬件操作;而HAL库则提供了一种更高级别的编程抽象,隐藏了部分硬件细节,便于编写可移植性强的代码。
// 示例代码:库函数编程设置GPIO模式为输出
#include "stm32f1xx_hal.h"
void HAL_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置GPIOA的某个引脚为输出模式
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
库函数编程的优势在于,它通过抽象的方式简化了硬件操作的复杂性,使代码更加清晰,易于理解。同时,由于库函数通常会进行错误检查和边界条件处理,因此相对于直接操作寄存器,使用库函数会更安全。
3.2.3 HAL与LL库的应用选择
在STM32开发过程中,选择HAL库还是LL库进行编程是一个常见的问题。HAL库提供了一个硬件抽象层,使得开发者可以编写与硬件无关的代码,便于在不同STM32系列间移植。而LL库则提供了更为底层的直接硬件访问能力,适用于需要精细控制硬件,以及对性能要求更高的场景。
一般来说,如果项目对代码的移植性有较高要求,或者需要快速开发,可以优先考虑HAL库。反之,如果需要直接控制硬件以达到最佳性能,或者对代码大小有严格限制,那么LL库可能更合适。例如,如果你正在开发一个需要精确控制定时器的场合,LL库可能会提供更精确的定时器控制功能。
flowchart LR
A[开始STM32开发] -->|项目需求| B(HAL库选择)
A -->|硬件控制| C(LL库选择)
B --> D[编写与硬件无关的代码]
C --> E[编写与硬件紧密相关的代码]
D --> F[代码移植性好]
E --> G[代码执行效率高]
在决定使用HAL库还是LL库时,开发者需要根据项目的具体需求和场景做出选择。通常建议初学者从HAL库开始,逐步过渡到更底层的LL库。同时,考虑到开发效率和代码的可维护性,建议使用STM32CubeMX工具自动生成初始代码。
4. 从源代码到BIN文件的转换步骤
在嵌入式系统开发中,将源代码编译成BIN文件是完成软件部署的关键步骤。BIN文件是二进制文件,可以被嵌入式设备加载并执行。本章详细阐述了从编写源代码到生成BIN文件的全过程,包括IDE和编译工具的选择、编译链接过程以及最终BIN文件的生成。
4.1 源代码编写与编译环境搭建
源代码是实现嵌入式系统功能的基石。编写高效的源代码需要开发者具备扎实的C语言功底,并熟悉STM32的硬件特性。紧接着,正确搭建编译环境是确保编译过程顺利进行的前提。
4.1.1 选择合适的IDE和编译工具
在编写STM32源代码之前,选择一个合适的集成开发环境(IDE)和编译工具至关重要。常见的开发工具包括Keil MDK、IAR、STM32CubeIDE、Eclipse以及GCC编译器等。在本节中,我们将详细探讨如何根据项目需求选择合适的开发工具。
选择IDE时需要考虑以下因素:
- 易用性 :界面是否友好、是否容易上手。
- 功能完备性 :是否提供代码自动完成、调试、版本控制等功能。
- 硬件支持 :对目标硬件平台的支持程度,包括外设库、启动代码等。
- 性能 :编译速度以及内存消耗情况。
- 社区与支持 :社区活跃度和官方支持程度,能否得到及时的帮助。
例如,对于STM32系列微控制器,ST官方推荐使用STM32CubeIDE进行开发。它集成了GCC编译器,并提供了丰富的中间件和外设库,使得开发过程更为高效。
4.1.2 编写STM32源代码及调试
编写STM32的源代码,首先需要了解目标微控制器的架构和外设特性。STM32F系列、STM32G系列和STM32L系列等不同系列的微控制器,其内存大小、性能、外设种类等都不尽相同。在编写代码时,应当参考相应的参考手册和数据手册。
编写代码的几个关键步骤如下:
- 初始化代码 :编写系统时钟配置、外设初始化等启动代码。
- 主函数编写 :实现主循环,包含各种任务调度。
- 中断服务程序编写 :配置中断优先级、编写中断处理函数。
- 错误处理 :编写异常和错误处理代码,确保程序的鲁棒性。
在代码编写完成后,使用IDE的调试工具进行代码调试。调试过程中,可以设置断点,单步执行代码,检查变量状态和寄存器值。通过这种方式,可以有效定位程序中的逻辑错误或运行时问题。
4.2 编译链接生成BIN文件
在源代码编写和调试完成后,接下来进入编译链接阶段,该过程将源代码转换为机器可读的二进制代码,并生成BIN文件。
4.2.1 编译过程中的编译选项与优化
编译器提供了各种编译选项供开发者选择,以满足不同的项目需求。编译选项通常包括:
- 优化选项 :根据需要选择不同的优化级别,如
-O0(无优化)、-O1(小优化)、-O2(中优化)、-O3(大优化)等。 - 警告级别 :如
-Wall表示开启所有警告信息,帮助开发者发现潜在问题。 - 宏定义和编译指令 :如
-D用于定义宏,-I用于指定包含目录等。
在编译过程中,对代码进行优化是提高程序执行效率和减少二进制文件大小的重要手段。然而,过度优化可能会导致程序运行不稳定,因此要根据实际情况合理选择优化选项。
4.2.2 链接脚本的作用与编写
链接器的作用是将编译后生成的目标文件(.o或.obj)和库文件链接成最终可执行文件。链接脚本定义了内存布局,即各段代码和数据在内存中的存放位置。一个典型的STM32链接脚本示例如下:
MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
SECTIONS
{
.text : {
*(.text*) /* 代码段 */
} > FLASH
.data : {
*(.data*) /* 初始化数据段 */
} > RAM
.bss : {
*(.bss*) /* 非初始化数据段 */
} > RAM
}
该链接脚本定义了STM32的FLASH和RAM内存区域,以及代码段、数据段和未初始化数据段的分配。掌握链接脚本的编写对于控制最终生成的BIN文件尤为重要。
4.2.3 生成最终的BIN文件
在编写完源代码、设置好编译选项并配置好链接脚本后,就可以执行编译链接命令生成BIN文件了。在许多IDE中,此过程可以通过一键编译来完成。在命令行中,使用如下指令:
arm-none-eabi-gcc -O2 -Wall -g -mcpu=cortex-m3 -o main.elf main.c
arm-none-eabi-objcopy -O binary main.elf main.bin
上述命令中, arm-none-eabi-gcc 是编译器, -O2 表示中等优化级别, -o main.elf 指定输出文件名为 main.elf , main.c 是源文件。第二条命令的 arm-none-eabi-objcopy 将ELF格式的可执行文件转换为二进制格式的BIN文件。
在生成BIN文件之后,可以使用一些工具如 hexdump 对文件进行检查,确保内容无误:
hexdump -C main.bin
综上所述,从源代码到BIN文件的转换步骤,涉及到开发环境搭建、代码编写和调试、编译链接以及最终文件生成等环节。掌握这些技能对于STM32嵌入式开发至关重要。
5. 编程器和调试器烧录BIN文件的使用
5.1 烧录工具的选择与配置
烧录工具是将编译好的BIN文件烧写到STM32微控制器中不可或缺的步骤。烧录过程通常涉及编程器和调试器,它们能够与微控制器进行通信,完成代码的烧录和调试工作。
5.1.1 常见的烧录工具介绍
在嵌入式开发中,常用的烧录工具有ST-Link、J-Link、SWD、SWIM等,它们各有特点:
- ST-Link :ST公司开发的低成本烧录器,主要配合STM32微控制器使用,支持SWD接口,具有兼容性好、安装简单、速度较快等特点。
- J-Link :SEGGER公司推出的一款通用型烧录器,它支持多种微控制器,具备速度极快、稳定性高等特点,但价格相对较高。
- SWD (Serial Wire Debug):一种两线调试接口,用于STM32系列微控制器的调试与烧录。
- SWIM (Single Wire Interface Module):ST公司为STM8系列微控制器专门设计的单线调试接口。
5.1.2 烧录工具的硬件连接与软件配置
烧录工具的配置包括硬件连接和软件设置两部分:
硬件连接
硬件连接通常包括以下几个步骤:
1. 确定目标微控制器支持的调试接口类型。
2. 将编程器的调试接口与目标MCU的相应引脚连接起来。
3. 确保连接过程中保持连接稳定,避免接触不良。
以ST-Link为例,典型的连接方式如下:
- VCC:连接到目标微控制器的电源脚(通常是3.3V或5V)。
- GND:连接到目标微控制器的地线。
- SWDIO:连接到微控制器的SWD数据线。
- SWCLK:连接到微控制器的SWD时钟线。
- NRST:连接到微控制器的复位脚。
软件配置
软件配置包括安装烧录软件和驱动,以及在软件中选择正确的硬件设备和配置烧录参数:
- 安装并启动烧录软件(如ST-Link Utility或STM32CubeProgrammer)。
- 检查并安装与烧录器适配的驱动。
- 在软件中选择对应的烧录器设备。
- 根据需要选择编程操作,例如“擦除”、“编程”、“验证”等。
- 加载BIN文件到烧录软件中。
5.2 烧录过程的操作与注意事项
5.2.1 烧录前的准备工作
在执行烧录操作之前,需要进行一系列的准备工作确保烧录过程的顺利:
- 备份 BIN 文件 :确保你的BIN文件是最新的,并且已做好备份。
- 检查目标微控制器 :确保目标微控制器的电源设置正确,与编程器连接无误。
- 初始化开发环境 :确保开发环境(IDE或专用烧录工具)是最新版本,并且与所使用的硬件兼容。
- 设置正确的烧录参数 :根据微控制器的类型和需求设置正确的烧录参数,包括内存布局和烧录速度。
5.2.2 烧录过程中的常见问题及解决方法
烧录过程中可能会遇到各种问题,以下是一些常见问题及其解决方法:
问题1:连接失败
- 可能原因 :连接线损坏、驱动未正确安装、目标微控制器未正确供电、接口不匹配等。
- 解决方法 :检查连接线和电源,重新安装驱动程序,确保接口匹配,并且目标微控制器已上电。
问题2:烧录失败
- 可能原因 :BIN文件损坏、烧录速度过快导致通信错误、微控制器被锁定或保护。
- 解决方法 :重新生成BIN文件、降低烧录速度、检查微控制器是否有锁定位设置,并进行清除。
问题3:程序无法运行
- 可能原因 :代码中存在硬件访问冲突、程序编译时没有正确配置启动文件。
- 解决方法 :检查程序代码和编译设置,确保启动文件正确配置,并且与硬件匹配。
示例代码块
// 示例代码段,使用ST-Link进行烧录操作(伪代码)
int main(void) {
// 初始化系统时钟
SystemClock_Config();
// 初始化烧录器接口
STLink_Init();
// 擦除目标微控制器存储器
Erase涂抹();
// 将BIN文件内容烧录到微控制器
while ( Flash_Program() ) {
// 检测烧录状态,如果失败进行相应处理
// 例如,错误处理或重新启动烧录流程等
}
// 验证BIN文件内容
if ( Flash_Verify() == SUCCESS ) {
// 烧录成功,执行复位重启微控制器
ResetSystem();
} else {
// 烧录失败,进行错误处理
HandleError();
}
return 0;
}
上述代码演示了烧录操作的逻辑流程,但实际操作中需要具体的ST-Link API函数,以及对微控制器特定的编程和配置方法。
通过以上的介绍,您已经了解了如何选择和配置烧录工具,以及进行烧录操作时需要注意的事项。在下一章节,我们将介绍STM32的固件在线升级(OTA)机制,为远程维护和升级固件提供便利。
6. STM32固件更新与BIN文件的在线升级(OTA)
在现代嵌入式系统开发中,能够远程更新设备固件已成为一项重要功能。STM32微控制器支持在线升级(Over-The-Air, OTA),使得开发者能够远程部署新的固件,从而避免物理访问设备。本章将深入探讨OTA更新机制的原理、实现以及更新流程详解。
6.1 OTA更新机制的原理与实现
6.1.1 OTA的基本概念与优势
OTA更新是一种无线远程升级技术,可以远程将新的固件或软件传输到设备上进行更新。这种方式减少了现场维护的需要,降低了维护成本,并且提高了系统的灵活性和可靠性。
OTA更新的主要优势包括:
- 远程升级 :无需物理连接或现场访问设备即可更新固件。
- 即时更新 :开发人员可以迅速响应问题,快速部署修复和功能增强。
- 自动化部署 :更新过程可以自动化,简化了操作流程,降低了出错率。
- 成本效益 :省去了远程服务的费用和设备停机时间。
6.1.2 实现OTA更新的软硬件要求
为实现OTA更新,设备需要满足以下条件:
- 稳定的通信接口 :如以太网、Wi-Fi、蓝牙等。
- 足够的存储空间 :用于存放新固件的存储器,通常需要额外的闪存空间。
- 可靠的引导程序 :确保设备能够从新固件恢复到正常工作状态。
- 安全机制 :保障更新过程的安全性,如数字签名和加密。
6.2 OTA更新流程详解
6.2.1 OTA更新的步骤与流程
OTA更新过程可以分为以下几个步骤:
- 准备新固件 :开发人员生成新的固件并上传到远程服务器。
- 设备请求更新 :设备定期或在触发条件下向服务器请求固件更新。
- 服务器验证 :服务器验证设备请求,并提供固件下载。
- 设备下载新固件 :设备从服务器下载新固件并验证其完整性。
- 应用新固件 :设备安装新固件,并在必要时重启进入新的固件版本。
图6.1:OTA更新流程图
6.2.2 OTA更新中的安全问题与对策
OTA更新虽然方便,但引入了新的安全风险。以下是常见的安全问题及对策:
- 数据传输安全 :确保固件更新过程中数据传输的加密,可以使用HTTPS、TLS等协议来保证传输安全。
- 固件验证 :对固件进行数字签名,并在设备端验证签名,确保固件来源可信且未被篡改。
- 回退机制 :在新固件出现问题时,需要有一个回退机制,使设备能够重新启动到旧版本。
- 权限控制 :限制OTA更新的权限,只有授权的设备或用户才能触发更新过程。
OTA更新是提升STM32微控制器应用价值的重要技术手段。在下一章节,我们将探讨如何使用STM32CubeIDE和Keil uVision等开发工具来实现OTA更新,以及其他应用实践。
简介:STM32的BIN文件是嵌入式系统开发中的关键概念,涉及到微控制器编程的各个环节。本文将深入探讨STM32微控制器系列及其BIN文件的生成和应用,包括编译、链接、生成BIN文件的步骤,以及编程和固件更新的技术细节。通过理解并应用BIN文件,开发者可以更加高效地进行STM32相关的嵌入式项目开发。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐




所有评论(0)