sloop一个嵌入式裸机框架

嵌入式ARM 2025-03-28 10:01

sloop开源项目仓库链接(复制到浏览器打开)

https://github.com/sloop-open/sloop
开源许可证 MIT
sloop是一个嵌入式裸机框架,提供一套API,方便管理多种任务,比如超时任务/周期任务/并行任务/互斥任务等。
有 sys_wait 和 sys_wait_bare 这两个非阻塞等待API,支持挂起当前互斥任务,但不阻塞并行任务。

任务采用动态注册机制,有以下优势:

1. 可以在运行时方便地启用和停止任务,停止后没有副作用。

2. 可以替代部分静态调用,简化文件之间的调用耦合。

3. 可以替代部分依赖标志量进行同步的操作,有效降低标志的使用数量,增加代码的可读性。

01


目录结构说明:

/project

├── Bin/

├── Libraries/

│   ├── CMSIS

│   └── STM32F2xx_StdPeriph_Driver

├── MDK-ARM/

├── user/

│   ├── app

│   │   ├── config

│   │   │   ├── bl_config.h

│   │   │   ├── com_config.h

│   │   │   ├── gpio_config.c

│   │   │   ├── gpio_config.h

│   │   │   └── stm32f2xx_conf.h

│   │   ├── module

│   │   ├── tasks

│   │   │   ├── task_baseInit.c

│   │   │   ├── task_demo.c

│   │   │   └── task_idle.c

│   │   ├── common.h

│   │   ├── main.c

│   │   └── main.h

│   ├── sloop

│   │   ├── kernel

│   │   │   ├── sloop.c

│   │   │   ├── behavior_log.h

│   │   │   └── console.c

│   │   ├── mcu_interface

│   │   │   ├── stm32f2xx_it.c

│   │   │   └── stm32f2xx_it.h

│   │   ├── RTT

│   │   ├── sloop.h

│   │   └── bl_common.h

│   ├── service

│   │   ├── app_service_pack

│   │   ├── mcu_service_pack

│   │   └── service_api.h

└── readme.md



# 可执行文件目录

# MCU 库文件

# CMSIS

# ST标准外设库

# MDK 工程文件

# 用户文件

=== 应用层文件 ===

# 用户配置

# sloop 配置文件

# 串口和can 配置文件

# GPIO 配置文件

# GPIO 对外API和别名

# ST 外设库配置(不要变更)

# 整机功能模块,比如伺服电机、编码器

# 任务存放文件夹

# 原始任务

# 演示任务

# 空闲任务

# 应用层公共包含

# 程序入口 main,在此弱定义任务

# 在此声明任务

=== sloop 源码(不要变更)===

# 内核

# sloop 内核源代码

# 行为日志宏

# 控制台源代码

# BL移植时,MCU 接口代码

# mcu 中断头文件(不要变更)

# mcu 中断源文件(不要变更)

# 日志支持模块,SEGGER RTT

# sloop 用户 API

# sloop 用户 宏 API,主要是日志

=== 为应用层提供服务(不要变更)===

# 面向应用层的服务包,与 MCU 无关,

# 基于MCU的服务包,完全依赖 MCU,

# 服务包面向应用层,提供给用户的API

# 项目说明文档 和 更新日志






























建议在驱动中实现RQHandler,不需要汇总到这里





完全可移植

对其他MCU平台不可移植


<<向右滑动查看更多内容


02


一些设计建议:

1. 开发中要不断思考该业务是不是主要业务,如果是主要业务需要暴露在可以快速直观看到的地方。
2. 业务不应该是混乱分散的,而是有结构的,主次分明的。
3. 尽量不要使用运行时动态连接(函数指针),因为这种方式会破坏静态分析特性。只有在必要的时候才采用,比如抽象业务调用(任务调用)。
4. 用静态调用的方式,不仅具有良好的静态分析性(可以直接跳转),而且运行时的效率也要高,还避免了NULL指针问题。
5. 要控制函数调用深度,在满足设计需求情况下越浅越好,一般不要超过6层。
6. 每一层调用都会消耗栈空间,控制栈深度对于栈溢出风险控制和运行时减少栈入栈出提高运行效率十分有益。
7. 函数名应具有局部辨识度,而且不应太长,不要超过32个字符。能表达核心功能即可,不要太过追求名称的统一(这反而会破坏函数名称的辨识度)。
8. 业务配置和业务的执行loop,应该放在一个任务文件或模块文件下。
9. 按键响应这些会直接导致业务跳转的地方(可以叫做业务路由),业务路由需要集中管理和暴露,不能分散,否则将极不利于业务流的分析。
10. 尽量不要使用标志量来进行模块间的交互,建议采用函数封装操作接口替代标志量。因为往往函数的意图比标志量清晰。
11. 如果抽象层次过高,开发者可能需要花费较多时间去理解每一层的具体实现,尤其是当功能较简单时,过度的抽象可能适得其反。
12. 尽量避免使用extern关键字,如果可能应当完全禁止使用extern。用函数来作为模块之间的交互接口,而不是全局变量。
13. 如果是同一文件中函数之间的交互,可以使用标志量,更轻量。因为在同一文件,容易定位,不太会引起混乱。
关于中断处理的最佳实践:
1. sloop主循环可以看成一个单线程,称为主线程。
2. 中断可以理解为“硬件触发的超高优先级的短暂线程”。
3. 中断适合快速处理事件,而主线程适合持续执行任务。
4. 中断里只做“最小、最关键”的事情,比如读取传感器、清除中断标志位。
5. 中断必须快速执行完成。
6. 复杂逻辑交给主线程处理,推荐使用sys_task_once()把中断触发的业务逻辑下放到主线程处理。
7. 避免中断嵌套,否则可能导致系统崩溃或不可预测的延迟,所以NVIC配置成了不可抢占。
8. 中断是异步处理,应该尽快处理完成,切回主线程继续同步处理各项事务。
以下是常见的非法内存操作,可导致不可预测的行为:

1. 未初始化的变量

{
    int x;

    /* x 未初始化,输出不可预测的值 */
    printf("%d", x);
}

2. 对常量进行修改

char* str = "Hello";

/* 错误,字符串常量不可修改 */
str[0] = 'h';

3. 数组越界写入

int arr[5] = {1, 2, 3, 4, 5};

/* 超出数组范围,越界写入 */
arr[10] = 100;

/* 可能导致其他模块或函数工作异常 */

4. 空函数指针调用

pfunc func = NULL;

/* 未定义行为,通常会导致崩溃 */
func();

5. 未处理的空指针解引用

int* ptr = NULL;

/* 空指针解引用,程序崩溃或行为不确定 */
*ptr = 10;

6. 缓冲区溢出(Buffer Overflow)

char buffer[10];

/* 超出缓冲区的大小 */
strcpy(buffer, "This is a very long string");

/* 可能导致其他模块或函数工作异常 */

char buffer[10];

/* 不安全,可能溢出 */
sprintf(buffer, "This is a string");

7. 内存泄漏(Memory Leak)

int* ptr = malloc(sizeof(int));

/* 没有调用 free(ptr),导致内存泄漏 */

8. 递归深度过深导致栈溢出

void recursive_function() {

    /* 没有终止条件,导致栈溢出 */
    recursive_function();
}

安全性与内存管理的关系:
C语言中的内存管理责任落在开发者身上,编译器和操作系统对内存的管理并不像在高级语言(如Java或Python)中那么自动化。
因此,内存管理错误(如访问非法内存、越界、空指针、内存泄漏等)往往是导致程序崩溃或安全漏洞的根本原因。
预防非法内存操作的方法:
  • 初始化指针:始终将指针初始化为NULL或指向有效内存区域,避免使用未初始化的指针。
  • 检查指针有效性:在解引用指针之前,始终检查它是否为NULL,避免空指针解引用。
  • 边界检查:确保对数组和缓冲区的访问不会超出其边界,可以使用sizeof或明确的边界值进行检查。
  • 使用安全的库函数:避免使用易受缓冲区溢出攻击影响的函数(如strcpy()、gets()等),使用更安全的替代函数(如strncpy()、fgets()等)。


03


系统控制台,可以在RTT终端执行预设命令,比如输入reboot执行重启,输入m、M或menu出菜单。
RTT设置:

input->"end of line"->none

input->"echo input"->all enable
控制台内置命令汇总:
功能命令
简写数字调用参数
c1:  重启rebootr/R0
c2:  查询版本versionv/V1
c3:  查询当前任务数据taskt/T2命令示例:"task" 打印一次,"task on" 10Hz打印,"task off" 关闭10Hz打印
c4:  查询 cpu 负载cpuc/C3命令示例:"cpu" 打印一次,"cpu on" 10Hz打印,"cpu off" 关闭10Hz打印
c5:  串口发送uart命令示例:ASCLL 模式:"uart6 hello",HEX 模式:"uart6 -hex 68 65 6C 6C 6F"
c6:  CAN发送can
命令示例:ASCLL 模式:"can1 -id 1 hello",HEX 模式:"can1 -id 1 -hex 68 65 6C 6C 6F"
c7:  GPIO输出和 gpio输入回显开关gpio
命令示例:命令示例:"gpio pin_beep H", "gpio input on" or "gpio input off"


命令 -h: 可查看命令使用举例,比如uart -h
使用注意:
1. 超时任务和周期任务 以回调函数名称作为ID,故同一时刻,同一个回调函数不支持开启多种超时或者周期任务。
开启多个,最新的会覆盖旧的。同一个回调即开启超时又开启周期,是允许的。
2. 重置超时任务,只需重新调用 sys_timeout_start。超时任务到达后,会自动释放任务,没有副作用。关闭后,可以重新设置超时时间。
3. 所有需要在主线程轮询的任务,必须通过 sys_task_start 注册调用(不允许在 main 函数 while(1) 下添加其他函数),这样才能保证 sys_wait 非阻塞等待功能正常。
4. sys_wait 和 sys_wait_bare 只能在互斥任务中调用,使用次数不限,不允许嵌套调用(嵌套日志会报错)。
不建议在互斥任务的驱动中和互斥任务的子函数中调用,容易出现嵌套。保证不嵌套的情况下可以使用。
5. sys_wait 和 sys_wait_bare 调用会阻塞当前任务,但不影响其他并行任务执行。相当于挂起当前任务。
可以用sys_wait_break中断等待,中断后返回1,建议应用层直接返回,不再执行等待后的业务。
可以用sys_wait_continue忽略等待,返回0,继续执行等待后的业务。
6. sys_wait推荐使用方法

等待前的业务,进入 wait 后开始阻塞

if(sys_wait(10))

    return;

等待完成后的业务

7. 建议不要使用 sys_delay,特别是周期调用,会大大降低系统性能。sys_delay_us <100us ,可以安全调用。

8. 在互斥任务顶层,可以使用 sys_wait ,达到 sys_delay 的相同效果。

9. 互斥任务是主要的业务执行场景,并行任务是辅助服务。

10. 在所有任务操作中,调用stop后,任务被释放,没有副作用。

11. NVIC 分组已经配置为 16 级响应,不支持抢占,他处不应再调用 NVIC_PriorityGroupConfig。

12. 配置外设中断时,预优先级恒为0,子优先级默认设为宏 PRIO_DEFAULT,如遇到响应延迟,再调整。

中断优先级分配表
SysTick_IRQnPRIO_HIGHEST 0
外设中断PRIO_DEFAULT 5
最低优先级 PRIO_LOWEST 15
main 主线程16(相当于)


13. 新增互斥任务需要在 main.h 声明,在 main.c 中弱定义,在用户创建的 task 文件中实现。
14. 在 bl_config.h 中可以开启看门狗,默认不启用。
15. 在 bl_config.h 中开启行为日志功能,默认启用。
开启行为日志后,会对系统 API 进行打印增强。即在调用系统 API 时会有相应日志输出。
这对分析系统工作流程会有帮助。
16. 互斥任务有三个阶段:
a1. 初始化阶段(_INIT 和 _FREE)
a2. 运行阶段 _RUN;之后
a3. 运行终止(_FREE; 和 _RUN;)
17._INIT _FREE和_RUN必须实现,为空没关系。因为任务跳转依赖它。
18. systick和tim7两个外设,内核已占用,应用层不要再使用。

19. sloop不适用运行时间长的任务,比如做连续FFT,时间超过1ms。

如果是这种任务建议用状态机拆分或者直接拆分成更小的任务。拆分后,小任务的执行周期应小于10us。

20. 推荐使用V5版本编译器,速度更快。编译优化等级,推荐使用 -O2。

04


更新日志:

2025-3-11

feat:控制台新增GPIO输出命令

feat:控制台新增gpio输入回显开关

2025-3-10

feat:精简GPIO API

2025-3-3

feat:全新的gpio配置模板

optimiz:移除系统API:sys_wait_for 和 sys_delay_nonblock

optimiz:简化demo逻辑

feat:readme.txt 加入mdk工程

2025-2-27

feat:readme里增加一些设计建议

feat:新增常见的内存非法操作提示

2025-2-26

feat:uart1~6都验证通过,控制台提供uart发送支持

2025-2-19

feat:hardfault增加栈解析,抛出疑似出错代码的位置(即地址)

2025-2-13

feat:readme新增目录结构说明

2025-2-8

feat:新增任务周期统计,控制台 task on 命令可查看。

2025-2-7

feat:使用注意 添加 关于中断处理的最佳实践。

feat:新增us级延时 sys_delay_us 和 sys_get_us, 通过tim7 精确定时的,但不产生中断。

2025-2-2

optimiz:修改打印日志api 名称,比如 sys_printf_func 修改为 sys_prt_withFunc。

feat:命令增加 -h 查看命令使用举例,比如 uart -h。

2025-1-27

feat:通讯口串口和can配置集成在 com_config.h。service_api.h 汇总了服务层api。

2025-1-24

feat:控制台新增并行任务和周期任务查询,开启行为日志才能生效。

feat:控制台串口和can支持发送16进制。命令格式 uart -hex 30 31 ……,不带 -hex 默认发ASCLL码。

2025-1-23

feat:can支持 FIFO

2025-1-20

feat:控制台新增查询mcu负载命令。

feat:移除 API sys_cycle_flag_start。

feat:软定时任务不再跑在ms中断,改到主线程loop中。有助于降低栈空间,减少栈入栈出,提升系统性能和稳定性。

feat:中断改为16级响应优先级,不再支持抢占,有助于降低栈空间,减少栈入栈出,提升系统性能和稳定性。

也不会再有死锁问题。但要求中断处理要干净利索,处理实时数据,快速退出。

2025-1-16

feat:串口接收 DMA + FIFO OK

feat:base_init 改成任务 task_baseInit。即始祖任务。

2025-1-15

feat:串口发送 DMA + FIFO OK

feat:重构互斥任务,原静态调用改为动态调用。

feat:新增 _FREE 和 _RUN,方便在任务结束时,释放资源。比如周期任务。

2025-1-14

feat:串口支持DMA收发

feat:控制台新增查询当前任务命令task。互斥任务需实现INIT,才支持查询。

2025-1-13

feat:新增idle空闲任务,互斥任务没事可做可停留在idle。

feat:新增 task_end 互斥任务回收函数。

它会在跳转到其他任务前,释放一些在当前任务中开启的资源,比如周期任务,所以你不需要在每处 sys_goto 前做释放操作。

弱定义,根据需求实现,可以不实现。

feat:在周期任务基础上新增多次任务,可指定执行次数和间隔时间。可用于蜂鸣器多次鸣叫、串口多次定时重发。

feat:新增 sys_wait_bare 非阻塞裸等待,直到 break or continue。无需传入等待条件。适用多条件。

相当于挂起,外部通过 sys_wait_break 或 sys_wait_continue 打断。

feat:新增 sys_is_waiting,可以查询等待状态。

feat:控制台新增查询版本命令version ,可以通过 sys_set_version 设置版本。

2025-1-10

feat:新增蜂鸣器驱动,支持多次鸣叫

feat:新增运行灯驱动

2025-1-9

新增参数保存驱动和演示,默认以Flash为存储介质,可配置为EEP(EEP有32字节限制)。

2025-1-6

新增系统控制台,可以在RTT终端执行预设命令,比如输入reboot执行重启。输入m出菜单。

支持输入参数,如test -p 6.88

控制台可用于初期在线调试硬件,在线调试运动等。

2025-1-4

新增单次任务API sys_task_once,只执行一次,迟滞到loop里执行。可用于中断中复杂逻辑下放执行。

2024-12-31

新增可配置启用的看门狗,超时时间1s,默认不启用。

新增行为日志,可在 bl_config.h 开启,利于分析业务工作流。

日志新增时间戳[day h:m:s.ms]

2024-12-30

新增系统心跳,在 terminal1 窗口打印,可用于判断死机与否。

2024-12-25

精简互斥任务

新增错误日志,打印源码位置 sys_error

新增变量打印宏 sys_prt_var

2024-12-20

V1.0

sloop开源项目仓库链接(复制到浏览器打开)

https://github.com/sloop-open/sloop

开源许可证 MIT


嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论 (0)
  • REACH和RoHS欧盟两项重要的环保法规有什么区别?适用范围有哪些?如何办理?REACH和RoHS是欧盟两项重要的环保法规,主要区别如下:一、核心定义与目标RoHS全称为《关于限制在电子电器设备中使用某些有害成分的指令》,旨在限制电子电器产品中的铅(Pb)、汞(Hg)、镉(Cd)、六价铬(Cr6+)、多溴联苯(PBBs)和多溴二苯醚(PBDEs)共6种物质,通过限制特定材料使用保障健康和环境安全REACH全称为《化学品的注册、评估、授权和限制》,覆盖欧盟市场所有化学品(食品和药品除外),通过登
    张工13144450251 2025-03-31 21:18 20浏览
  •        在“软件定义汽车”的时代浪潮下,车载软件的重要性日益凸显,软件在整车成本中的比重逐步攀升,已成为汽车智能化、网联化、电动化发展的核心驱动力。车载软件的质量直接关系到车辆的安全性、可靠性以及用户体验,因此,构建一套科学、严谨、高效的车载软件研发流程,确保软件质量的稳定性和可控性,已成为行业共识和迫切需求。       作为汽车电子系统领域的杰出企业,经纬恒润深刻理解车载软件研发的复杂性和挑战性,致力于为O
    经纬恒润 2025-03-31 16:48 18浏览
  • 在智能语音交互设备开发中,系统响应速度直接影响用户体验。WT588F系列语音芯片凭借其灵活的架构设计,在响应效率方面表现出色。本文将深入解析该芯片从接收指令到音频输出的全过程,并揭示不同工作模式下的时间性能差异。一、核心处理流程与时序分解1.1 典型指令执行路径指令接收 → 协议解析 → 存储寻址 → 数据读取 → 数模转换 → 音频输出1.2 关键阶段时间分布(典型值)处理阶段PWM模式耗时DAC模式耗时外挂Flash模式耗时指令解析2-3ms2-3ms3-5ms存储寻址1ms1ms5-10m
    广州唯创电子 2025-03-31 09:26 167浏览
  • 引言在语音芯片设计中,输出电路的设计直接影响音频质量与系统稳定性。WT588系列语音芯片(如WT588F02B、WT588F02A/04A/08A等),因其高集成度与灵活性被广泛应用于智能设备。然而,不同型号在硬件设计上存在关键差异,尤其是DAC加功放输出电路的配置要求。本文将从硬件架构、电路设计要点及选型建议三方面,解析WT588F02B与F02A/04A/08A的核心区别,帮助开发者高效完成产品设计。一、核心硬件差异对比WT588F02B与F02A/04A/08A系列芯片均支持PWM直推喇叭
    广州唯创电子 2025-04-01 08:53 41浏览
  • 引言随着物联网和智能设备的快速发展,语音交互技术逐渐成为提升用户体验的核心功能之一。在此背景下,WT588E02B-8S语音芯片,凭借其创新的远程更新(OTA)功能、灵活定制能力及高集成度设计,成为智能设备语音方案的优选。本文将从技术特性、远程更新机制及典型应用场景三方面,解析该芯片的技术优势与实际应用价值。一、WT588E02B-8S语音芯片的核心技术特性高性能硬件架构WT588E02B-8S采用16位DSP内核,内部振荡频率达32MHz,支持16位PWM/DAC输出,可直接驱动8Ω/0.5W
    广州唯创电子 2025-04-01 08:38 25浏览
  • 在不久前发布的《技术实战 | OK3588-C开发板上部署DeepSeek-R1大模型的完整指南》一文中,小编为大家介绍了DeepSeek-R1在飞凌嵌入式OK3588-C开发板上的移植部署、效果展示以及性能评测,本篇文章不仅将继续为大家带来关于DeepSeek-R1的干货知识,还会深入探讨多种平台的移植方式,并介绍更为丰富的交互方式,帮助大家更好地应用大语言模型。1、移植过程1.1 使用RKLLM-Toolkit部署至NPURKLLM-Toolkit是瑞芯微为大语言模型(LLM)专门开发的转换
    飞凌嵌入式 2025-03-31 11:22 28浏览
  • 一、温度计不准的原因温度计不准可能由多种原因导致,如温度计本身的质量问题、使用环境的变化、长时间未进行校准等。为了确保温度计的准确性,需要定期进行校准。二、校准前准备工作在进行温度计校准之前,需要做好以下准备工作:1. 选择合适的校准方法和设备,根据温度计的型号和使用需求来确定。2. 确保校准环境稳定,避免外部因素对校准结果产生影响。3. 熟悉温度计的使用说明书和校准流程,以便正确操作。三、温度计校准方法温度计校准方法一般分为以下几步:1. 将温度计放置在
    锦正茂科技 2025-03-31 10:27 12浏览
  • 提到“质量”这两个字,我们不会忘记那些奠定基础的大师们:休哈特、戴明、朱兰、克劳士比、费根堡姆、石川馨、田口玄一……正是他们的思想和实践,构筑了现代质量管理的核心体系,也深远影响了无数企业和管理者。今天,就让我们一同致敬这些质量管理的先驱!(最近流行『吉卜力风格』AI插图,我们也来玩玩用『吉卜力风格』重绘质量大师画象)1. 休哈特:统计质量控制的奠基者沃尔特·A·休哈特,美国工程师、统计学家,被誉为“统计质量控制之父”。1924年,他提出世界上第一张控制图,并于1931年出版《产品制造质量的经济
    优思学院 2025-04-01 14:02 35浏览
  • 在环保与经济挑战交织的当下,企业如何在提升绩效的同时,也为地球尽一份力?普渡大学理工学院教授 查德·劳克斯(Chad Laux),和来自 Maryville 大学、俄亥俄州立大学及 Trine 大学的三位学者,联合撰写了《精益可持续性:迈向循环经济之路(Lean Sustainability: Creating a Sustainable Future through Lean Thinking)》一书,为这一问题提供了深刻的答案。这本书也荣获了 国际精益六西格玛研究所(IL
    优思学院 2025-03-31 11:15 18浏览
  • 升职这件事,说到底不是单纯靠“干得多”或者“喊得响”。你可能也看过不少人,能力一般,甚至没你努力,却升得飞快;而你,日复一日地拼命干活,升职这两个字却始终离你有点远。这种“不公平”的感觉,其实在很多职场人心里都曾经出现过。但你有没有想过,问题可能就藏在一些你“没当回事”的小细节里?今天,我们就来聊聊你升职总是比别人慢,可能是因为这三个被你忽略的小细节。第一:你做得多,但说得少你可能是那种“默默付出型”的员工。项目来了接着干,困难来了顶上去,别人不愿意做的事情你都做了。但问题是,这些事情你做了,却
    优思学院 2025-03-31 14:58 26浏览
  • 据先科电子官方信息,其产品包装标签将于2024年5月1日进行全面升级。作为电子元器件行业资讯平台,大鱼芯城为您梳理本次变更的核心内容及影响:一、标签变更核心要点标签整合与环保优化变更前:卷盘、内盒及外箱需分别粘贴2张标签(含独立环保标识)。变更后:环保标识(RoHS/HAF/PbF)整合至单张标签,减少重复贴标流程。标签尺寸调整卷盘/内盒标签:尺寸由5030mm升级至**8040mm**,信息展示更清晰。外箱标签:尺寸统一为8040mm(原7040mm),提升一致性。关键信息新增新增LOT批次编
    大鱼芯城 2025-04-01 15:02 48浏览
  • 北京贞光科技有限公司作为紫光同芯产品的官方代理商,为客户提供车规安全芯片的硬件、软件SDK销售及专业技术服务,并且可以安排技术人员现场支持客户的选型和定制需求。在全球汽车电子市场竞争日益激烈的背景下,中国芯片厂商正通过与国际领先企业的深度合作,加速融入全球技术生态体系。近日,紫光同芯与德国HighTec达成的战略合作标志着国产高端车规芯片在国际化道路上迈出了关键一步,为中国汽车电子产业的发展注入了新的活力。全栈技术融合:打造国际化开发平台紫光同芯与HighTec共同宣布,HighTec汽车级编译
    贞光科技 2025-03-31 14:44 28浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦