发动态
图文
列表
置顶
【元器件规范共建召集令】诚邀行业专家,定义行业规范新基准
当你在电子元器件选型时,是否因参数定义模糊反复试错?当你推进研发项目时,是否因标准不统一延误进度?如今,有一个能改变行业现状、为电子产业发展注入新动能的机会 —— 加入立创商城电子元器件规范共建项目,与更多行业专家携手,打造科学、完善、权威的元器件参数规范体系!立创商城深耕电子元器件电商领域多年,深知统一精准的参数规范对行业上下游的重要性。我们正启动一项开创性工程,现面向全国电子元器件行业规范制定人、电子行业从业者、电子专业教育从业者、资深领域电子爱好者等群体招募 20-50 名细分领域专家,涵盖接口芯片、时钟和定时、射频无线、传感器等 9 大核心方向,邀你成为这场 “规范革命” 的 “执笔人”。1、你将参与的核心领域(涵盖9大方向)接口芯片USB、PCIe、CAN芯片等接口芯片的设计关注核心参数范围划定及其参数名词解释时钟和定时晶振、定时器、时钟发生器等震荡器的设计关注核心参数范围划定及其参数名词解释射频无线RF芯片、天线模块、无线收发器等无线射频相关器件的的设计关注核心参数范围划定及其参数名词解释传感器温度、压力、光电等传感器的设计关注核心参数范围划定及其参数名词解释功能模块电源管理、信号调理模块等电子模块的设计关注核心参数范围划定及其参数名词解释物联网/通信模块5G、WiFi、蓝牙模块等无线通讯模块的设计关注核心参数范围划定及其参数名词解释单片机/微控制器ST、TI、STC等单片机器件的设计关注核心参数范围划定及其参数名词解释逻辑器件和数据转换ADC/DAC、逻辑门等与信号转换和数据转换相关的设计关注核心参数范围划定及其参数名词解释显示屏器件OLED、LCD等显示屏的设计关注核心参数范围划定及其参数名词解释 2、你的角色:从技术实践者到标准制定者评审与优化:针对公司内部团队起草的规范初稿(如参数定义、填写规范、案例模板),以专业视角审核逻辑严谨性,提出修改建议(例如隔离电压、CMTI等参数的单位换算、优先级规则);深度参与:基于实操经验,为芯片引脚定义、数据速率计算、温度范围界定等参数提供行业实践案例,确保规范兼具理论准确性与工程可行性;成果共创:与跨领域专家协作,构建类似“电子元器件维基百科”的公开规范网站,让技术标准真正服务行业生态。3、我们为你提供的四大价值回报「行业署名权」:每一份经你评审修改的规范,均将在最终版本中明确标注你的姓名与单位,成为个人技术生涯的权威背书;「品牌曝光度」:规范公开时,参与评审与编撰的专家名单将同步公示,通过公司官方渠道(行业媒体、技术社区)定向推送,提升行业影响力;「知识共享平台」:加入电子元器件规范维基网站建设,你的技术见解将被全球工程师查阅引用,成为领域内的“隐形标准制定者”;「多样激励体系」:任务制,每次任务均有丰厚报酬奖励,根据审核规范复杂度与贡献度可获取,包括且不限于京东E卡/采购晶/优惠券/实物奖励等,多劳多得激励形式:1、积分制每次任务,每人均可获得积分,根据每人贡献程度获得对应积分贡献程度人数获得积分皇冠125黄金315白银610青铜105 2、积分可兑换礼品积分数兑换礼品价值550E卡或50采购晶50元10100元E卡或100元采购晶100元20200元E卡或200元采购晶200元50500元E卡或500元采购晶500元1001000元E卡或1000元采购晶1000元2002000元E卡或2000元采购晶2000元 4、为什么工程师值得加入?技术价值升华:从“用标准”到“定标准”,让你的经验成为行业参照坐标; 资源链接机遇:与芯片原厂、方案商专家深度交流,拓展技术人脉圈; 职业发展加分:参与行业级规范制定的经历,是技术管理岗晋升的硬核背书。5、报名方式如果您在上述领域拥有多年以上研发/设计经验,或主导过元器件选型与参数验证项目,欢迎将个人简历(附技术专长说明)发送至:,邮件主题注明“【规范专家报名】+领域方向”。我们将在3个工作日内与您联系,共商规范共建蓝图。 电子元器件的每一个参数,都承载着工程师的智慧。现在,你就有机会成为定义行业规范的 “少数派”,让全球工程师使用你参与制定的标准。这不仅是一次技术实践,更是一段能为行业留下深刻印记、为职业增添高光的宝贵经历。立创商城期待与你携手,重塑元器件参数规范行业标杆,让你的技术印记,刻进行业未来! 注:“本次共建采用灵活协作模式,单次任务预计耗时2~4小时,全程线上进行,不影响日常工作。”
【元器件规范共建召集令】诚邀行业专家,定义行业规范新基准
立创商城
一、产品概述MR300C是一款专为工业及特种应用设计的WiFi图像传输模块,其核心功能是通过采集USB接口摄像头数据并编码成HTTP协议的视频流,默认推送到8080端口。安卓、iOS或电脑设备可通过浏览器或VLC Media Player播放器在局域网内直接查看视频流。同时,模块的串口UART1支持与TCP client端进行数据透传,默认作为TCP server端,IP为10.10.10.1,端口为20140,串口波特率默认115200。该模块体积小巧(65×45×18mm),支持无线WiFi和有线网口双模式看图,具备低功耗、高兼容性、易集成等特点,广泛适用于工业内窥镜、机器人视觉、汽修检测、美容器材等领域。------二、核心技术规格与特性1. 视频输入与输出• 摄像头兼容性:支持USB UVC免驱摄像头,输出格式必须为MJPEG。• 分辨率支持:最高支持200万像素(1920×1080@30fps)。• 视频流协议:默认通过HTTP协议推送至8080端口,支持WEB浏览器或VLC播放器直接访问。• 查看方式: ◦ 连接WiFi热点查看视频; ◦ 连接有线网口查看视频; ◦ 支持TTL串口透传(UART1)。2. 网络与通信能力• 无线规格: ◦ 速率:300Mbps(2T2R); ◦ 传输距离:空旷环境约30米;• 有线接口:RJ45以太网口,支持有线网络接入。• 串口透传: ◦ UART1作为TCP Server,IP:10.10.10.1,端口:20140; ◦ 电平标准:3.3V TTL,可直接对接MCU; ◦ 波特率:默认115200(可配置)。3. 物理与电气参数• 尺寸:65 × 45 × 18 mm;• 供电电压:DC 5V;• 功耗:平均0.3A,最大1A;• 接口类型:USB、RJ45、TTL串口、天线接口(SMA);• 天线配置:双外置天线(2T2R),提升信号稳定性。4. 定制化与扩展• 原厂直销,支持功能定制;• 适用于多种工业及商业场景,如内窥镜、高拍仪、演讲稿制作仪、汽修设备等。------三、应用场景详解MR300C凭借其高兼容性和稳定传输能力,在以下场景中表现优异:1. 工业WiFi内窥镜• 通过UVC摄像头采集内部图像,经WiFi传输至平板或手机,实现远程无损检测;• 支持实时视频流查看,便于在狭窄或危险区域作业。2. 工业机器人视觉• 作为机器人“眼睛”,将摄像头画面实时传输至控制端;• 配合串口透传,实现图像+控制指令双向通信。3. 汽修与美容器材• 用于汽车发动机舱、管道内部等复杂结构的可视化检查;• 美容仪器中用于皮肤检测、治疗效果预览等。4. 高拍仪与文档拍摄• 支持1080P高清拍摄,通过WiFi直连电脑或手机,快速扫描文档、稿件;• 无需安装驱动,即插即用。------四、使用指南与配置建议1. 硬件连接• 将USB UVC摄像头插入模块USB口;• 若使用有线网络,接入RJ45网口;• 若使用WiFi,模块将自动广播热点(或通过路由器接入);• 串口UART1可连接MCU,用于数据透传或控制。2. 视频流访问• 无线模式:连接模块WiFi热点,打开浏览器输入 http://10.10.10.1:8080 即可查看;• 有线模式:电脑设置静态IP(如10.10.10.2),访问 http://10.10.10.1:8080;• VLC播放器:打开VLC → “网络串流” → 输入 http://10.10.10.1:8080。3. 串口透传配置• 默认串口参数:115200波特率,8位数据位,1位停止位,无校验;• MCU端作为TCP Client,连接IP:10.10.10.1,端口:20140;• 支持双向数据透传,可用于发送控制指令或接收状态反馈。------五、选型建议与注意事项选型建议:• 若需无线图传 + 串口控制,MR300C是理想选择;• 若对分辨率要求不高(如720P),可考虑更低成本方案;• 若需户外远距离传输,建议外接高增益天线或选用工业级路由器配合。注意事项:• 摄像头必须满足UVC免驱 + MJPEG输出,否则无法识别;• 默认IP为10.10.10.1,若网络中已有冲突,需修改模块IP;• 供电需稳定,建议使用5V/1A以上电源适配器;• 模块工作温度范围未明确标注,工业应用建议控制在0~60℃。------六、总结MR300C工业级WiFi图传模块以其紧凑的体积、强大的兼容性、灵活的连接方式和稳定的性能,成为工业视觉、远程检测、智能设备等领域的理想解决方案。无论是作为独立图传终端,还是作为嵌入式系统的一部分,它都能提供高效、可靠的图像传输服务。关键词:WiFi图传、UVC摄像头、MR300C、工业内窥镜、串口透传、HTTP视频流、VLC播放、TTL串口、300Mbps WiFi------原厂直销,支持定制 —— 如需批量采购或功能定制,可直接联系厂家获取技术支持与报价。
工业级WiFi图传模块MR300C技术解析与应用指南
开源硬件平台
每周一,我都会刷一遍GitHub Trending,看看这一周又有什么新东西。这一周的关键词就一个:Claude Code生态。从mattpocock/skills到free-claude-code,从GitNexus到Beads,整个GitHub Trending几乎被Claude Code相关的项目承包了。今天就给大家梳理一下这周最值得关注的几个项目。1. mattpocock/skills(23.5K⭐)—— Claude Code实战技能库这是本周Star增长最快的项目之一,由Vercel前员工mattpocock维护。这个项目的核心价值是:他把自己在实际项目中使用Claude Code的经验整理成了一套"技能脚本"。包含的内容很实用:Git操作:自动生成commit信息、智能处理merge冲突代码审查:自动review代码、生成改进建议测试生成:根据代码自动生成单元测试文档撰写:自动生成README和技术文档这些脚本不是"玩具",而是可以直接用到生产环境的实战工具。对于刚上手Claude Code的开发者来说,这套技能库能帮你快速建立正确的工作流。>>>顺嘴提一句,技术大厂,前后端-测试机会,全国一线及双一线城市均有坑位,待遇和稳定性还不错,感兴趣看看。2. Alishahryar1/free-claude-code(13.5K⭐)—— 免费的Claude Code方案本周涨势最猛的项目之一,一天涨了7000+ Star。这个项目解决了一个很现实的问题:Claude Code要钱,Copilot也涨价了,有没有免费的替代方案?它提供了一套在终端、VSCode、甚至Discord里使用Claude Code的方案,完全免费。适合人群:学生党、个人开发者、想尝鲜但不想花钱的程序员。不过要注意,免费方案可能有稳定性风险,生产环境还是建议用官方版本。3. abhigyanpatwari/GitNexus(30K⭐)—— 浏览器里的代码知识图谱这个项目的创新点很有意思:不需要服务器、不需要安装任何软件,直接在浏览器里生成整个代码库的知识图谱。你只需要拖一个GitHub仓库进去,它就会自动分析代码结构、依赖关系、函数调用链……然后给你生成一张交互式的知识图谱。对于接手老项目的开发者来说,这个工具简直是神器。你不再需要花几天时间读代码,只需要看看这张图,就能快速理解整个项目的结构。4. gastownhall/beads(新增项目)—— 给AI Agent装"记忆"这是本周新上榜的项目,关注度很高。核心功能:解决AI Agent的"金鱼记忆"问题。用过Claude Code的朋友应该知道,它每次对话都是从零开始,不记得之前聊过什么。Beads通过在代码仓库中插入结构化的"记忆文件",让Claude Code能够跨会话记住重要的上下文。比如你定义了一个API版本同步规则,下次对话时Claude Code就能自动应用这个规则。这个思路很有意思,为AI Agent的长期记忆提供了新的解决方案。总结这一周的GitHub Trending,释放了一个很明确的信号:Claude Code生态正在快速成熟。从技能库到免费方案,从知识图谱到长期记忆,开发者们正在围绕Claude Code构建完整的工具链。如果你还没开始用Claude Code,建议从mattpocock/skills开始,先学习正确的工作流。如果你已经在用Claude Code,那GitNexus和Beads这两个项目值得你花时间研究。AI编程工具的时代已经来了,你准备好了吗?
GitHub Trending周报:Claude Code生态大爆发,这些项目值得收藏
开源硬件平台
 在前面介绍利用百度智能云实现MQTT设备创建并且获取设备信息后,我们介绍了如何使用C++实现一个简单的MQTT服务器,可以实现发送与接收MQTT消息的功能。 这期我们介绍如何使用Ardunio IDE实现ESP32上云。 步骤也非常简单: 导入MQTT相关库 配置MQTT连接信息 连接MQTT 注册响应回调函数 实现响应回调函数 ESP32 是一款低成本、低功耗的微控制器,集成了 Wi-Fi 和蓝牙。 它是 ESP8266 的后继产品,ESP8266 也是一款低成本 Wi-Fi 微芯片,尽管功能非常有限。它是一个集成天线和射频巴伦、功率放大器、低噪声放大器、滤波器和电源管理模块。整个解决方案占用的印刷电路板面积最少。该板采用台积电40nm低功耗技术的2.4GHz双模Wi-Fi和蓝牙芯片,功率和射频性能最佳,安全可靠,可扩展到各种应用。 首先,打开Ardunio IDE,导入相关MQTT库(关于如何安装Ardunio 以及ESP32库的下载不做介绍请自行搜索) 在IDE右侧,输入MQTT,选择MQTT进行安装,此时我们就可以导入WiFI以及服务器连接库(WiFi不需要进行安装) 接着我们配置Wifi连接密码以及MQTT连接信息。const char* ssid = "1cm"; const char* password = "a1234555"; const char* mqtt_server = "altnlnn.iot.gz.baidubce.com"; const int mqtt_port = 1883; const char* mqtt_user = "thingidp@altnlnn|ESP32|0|MD5"; const char* mqtt_password = "9aeec4289c816ecfdb0de7ed3b164bf6"; const char* mqtt_topic = "TEST"; 配置好MQTT及Wifi信息后,我们在setup函数中配置启动信息,连接到Wifi之后,ESP32会自动尝试连接MQTT服务器,连接完成后进入循环函数,执行我们的主循环。void setup() { Serial.begin(115200); WiFi.begin(ssid, password);//连接Wifi while (WiFi.status() != WL_CONNECTED) { delay(1000);//等待WIfi连接成功 } client.setServer(mqtt_server, mqtt_port);//连接MQTT服务器 client.setCallback(callback);//注册接收回调函数 while (!client.connected()) {//等待连接成功 if (client.connect("ESP32Client", mqtt_user, mqtt_password )) { client.subscribe(mqtt_topic);//订阅需要的主题 } else { Serial.println("Failed to connect to MQTT Broker"); delay(5000); } } } 主循环的内容非常简单,主要是检查MQTT连接是否正常以及向云端发送心跳报文和处理消息。 void loop() { if (!client.connected()) { reconnect();//检查MQTT是否连接断开,如果连接超时,则尝试重新连接 } client.loop();//MQTT发送响应报文(还活着) } 在相应回调函数中,我们判断接收的字符是否为LED_ON,如果接收到的字符等于LED_ON的话,我们则让ESP32板载LED灯亮起。void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message received in topic: "); Serial.println(topic); Serial.print("Message:"); char * ss = (char*)payload; if(strcmp(ss,"LED_ON")==1) { LED_ON(); } }
ESP32物联网教程之MQTT
嘉立创PCB
CosyOS是一款来自中国的开源实时操作系统,从经典的8051内核,到流行的Arm Cortex-M内核,均可实现全局不关总中断、零中断延迟,适用于对系统实时性及中断响应速度有较高要求的场合。开源免费采用Apache2.0开源许可协议,完全开源且免费自主可控完全自主可控的纯国产RTOS,代码自主率:100%完全确定任务就绪表采用二级位图,任务调度时间完全确定安全关键多项安全关键技术相加持,确保系统运行坚如磐石一、高实时内核零中断延迟全局不关总中断、零中断延迟设计,从系统层面保证了用户中断的实时响应,效果等同于裸机。任务就绪表任务就绪表,采用零/一/二级位图,算法时间复杂度O(1),不同优先级抢占式调度时间完全确定。CosyOS时间轮CosyOS时间轮,专为嵌入式场景量身打造,平均时间复杂度O(1),确保大量软件定时器的高效计时。三维链表三维链表(任务链表、阻塞链表、定时器链表),可显著的减少操作链表,服务的执行速度更快。快速启动上电即启动,开机即运行;毫秒级启动,开机零等待。疾速响应无论是中断还是任务,都能做到按优先级实时抢占、疾速响应。二、轻松玩转CosyOS-III Cube(升级安装程序)协作开发者快速完成系统部署,轻松将裸机工程升级为CosyOS工程。支持 Keil C51、C251、MDK-Arm,IAR-EWARM 等工程文件类型。图形化配置(for Keil编译器)CosyOS的配置文件,全面支持图形化配置,具体包括 系统配置、MCU配置、启动文件配置等。CosyOS-III Taskmgr(任务管理器)实时监控各任务的运行,协助开发者及时发现设计中存在的潜在问题。由极致优化的C语言代码倾心打造而成,功能完善且性能卓越。界面风格简约时尚,唯美中不觉空洞,平淡中不失典雅。三、安全关键多项安全关键技术相加持,确保系统运行稳定可靠、坚如磐石。服务Space隔离、Safe run-time、优先级deep继承、任务栈监控。四、多平台兼容现支持 8051、80251、Cortex-M 等主流芯片架构,Keil C51、C251、MDK-Arm(AC5、AC6),IAR-EWARM,GCC-ARM 等主流编译器。未来会陆续加入对 Cortex-R/A、RISC-V、MIPS、龙芯 等主流和国产芯片架构的支持。感兴趣的坛友,可百度 CosyOS 获取更多详细信息,包括 官方网站、Gitee 开源仓库等。
零中断延迟的RTOS/CosyOS
硬创社
你是否也好奇,人形机器人为何能从早期蹒跚学步,短短几年就进化到如今流畅完成跳舞、武术、奔跑等高难度动作?其实,人形机器人想要实现媲美人体的稳定行走、灵活操控、长时续航,稳定、高效、小型化的电源系统是关键。只不过行业普遍面临布局面积受限,散热温升高等难题,直接影响整机可靠性与量产成本。而针对这些,沃芯半导体已有成熟可行的电源解决方案。扫码预约直播4月29日,沃芯半导体×立创商城专场直播,就将为你带来一站式人形机器人电源解决方案解析,帮你轻松突破设计瓶颈!直播过程中,还有超值礼品派送,2000元现金红包、开发板、绿联充电宝、雷柏无线蓝牙鼠标,看看你最心水哪个,来直播间就有机会获得~  直播主题用芯设计人形机器人电源解决方案直播时间4月29日(周三19:30)直播嘉宾沃芯FAE现场应用工程师 胡吉鑫 直播亮点抢先看拆解人形机器人三级降压整机电源架构,覆盖48V转12V、5V、3.3V、1.8V、1.2V等链路;灵巧手多路精密供电难点解析,讲清小空间、微电流、低功耗设计要点;沃芯磁集成电源芯片实战选型,教你快速匹配人形机器人驱动、主控、传感各模块电源。 关于沃芯半导体深圳市沃芯半导体技术有限公司(iModule)成立于2020年,公司致力于探究新一代高功率密度磁集成电源芯片,集芯片设计、研发、销售和服务于一身。产品覆盖不同电压和电流等级,主要面向通信,工业,医疗等应用领域。 现在预约直播,抢先锁定技术干货与豪华福利,助你解决供电难题,加速机器人量产!
【送开发板】“能跑半马”的机器人,离不开这个关键设计
立创商城
一边是英伟达万亿订单排到2027年,一边却是智谱、Claude等国内外AI厂商接连涨价,而这都指向同一个原因:随着AI技术的快速迭代,算力需求呈现指数级增长,与之相伴的是功耗的急剧攀升。当AI算力每18个月翻番,GPU功耗也实现跨越式增长,专为千瓦级机架设计的传统48V/54V供电架构已无法适配当前高功率需求。智谱CEO张鹏就曾表示,“旧算力基础设施的瓶颈已经开始暴露,这个瓶颈不在算力规模,而是在更底层的架构”。这也对数据中心与电源设计的未来提出了严峻考验。如果你也觉得AI时代电源设计效率、密度、散热全是痛点,那么4月28日19:30,立创商城×罗姆半导体(ROHM)联合直播你一定不能错过!看罗姆怎么把AI服务器电源最前沿、最硬核的技术全盘拆解,告诉你什么是电子工程师需要了解的下一个设计风口。直播全程还有福利狂撒,2000元现金红包、惠普蓝牙音响、雷柏无线蓝牙鼠标等实物礼品开送!扫码预约直播,文末还有采购晶赠送活动 直播主题ROHM面向AI服务器市场的战略直播时间4月28日(周二)19:30直播嘉宾Musk何(功率器件FAE) 亮点抢先看掌握800VDC/±400VDC行业标准、GPU功耗升级、机架架构变革,看懂下一代数据中心供电方向;获取20~33kW大功率电源拓扑设计、SiC/GaN 选型、LLC/PFC 参数、仿真效率,工程师可直接参考设计;解锁罗姆×英伟达/台达合作方案参考、第5代SiC/GaN性能对比,一站式解决设计难题。此外,相信大家也已经知道,为了向国内工程师们提供更加精准有效的内容服务,立创商城已与罗姆就「ROHM官方技术论坛」合作正式签署协议。(点击查看详细注册流程) 现在还有注册赠礼活动:2026年4月28日24点前,完成ROHM官方技术论坛注册并填写问卷的用户,经罗姆原厂核查注册成功后,每位注册成功用户将可获赠20采购晶!不用抽奖,注册即得!注:采购晶可用于抵扣一定比例现货商品金额,以及兑换采购晶专区礼品。https://esh.rohm.com.cn<点击前往注册> 注册成功后,扫码填写邮箱、客编信息别忘了提前预约,锁定4月28日立创×罗姆联合直播,开播不错过,干货不落下,看罗姆硬核方案帮你抢占AI服务器电源设计先机!
都在涨价,AI快用不起了!电子行业靠什么拯救算力?
立创商城
#立创·泰山派RK3566开发板# TSPI RK3566 RNDIS/ADB 与 Buildroot NFS 本文档记录了解决 NFS 挂载失败及 USB Gadget 冲突,最终实现 ADB 与 RNDIS 复合设备完美共存的核心流程与代码补丁。为提高可读性,按系统层级重构了原理说明与具体补丁的映射关系。 title: TSPI RK3566 USB Gadget (RNDIS/ADB) 与 NFS 修复复盘 tags: [sdk, rk3566, tspi, usb-gadget, rndis, adb, nfs] desc: 泰山派 RK3566 NFS 挂载与 RNDIS/ADB 复合设备共存修复笔记。 update: 2026-04-26 title: TSPI RK3566 USB Gadget (RNDIS/ADB) 与 NFS 修复复盘 tags: [sdk, rk3566, tspi, usb-gadget, rndis, adb, nfs] desc: 泰山派 RK3566 NFS 挂载与 RNDIS/ADB 复合设备共存修复笔记。 update: 2026-04-26 TSPI RK3566 RNDIS/ADB 与 Buildroot NFS 本文档记录了解决 NFS 挂载失败及 USB Gadget 冲突,最终实现 ADB 与 RNDIS 复合设备完美共存的核心流程与代码补丁。为提高可读性,按系统层级重构了原理说明与具体补丁的映射关系。 1. Kernel 层:RNDIS 支持与 UDC 硬件释放 1.1 开启 ConfigFS_ETH*,但不使用传统Gadget 痛点:内核传统网卡 Gadget,阻碍了动态 ConfigFS 接管 USB 控制器,这可能导致usb总线上的read event风暴。 方案:在内核配置 (./build.sh kconfig) 中彻底禁用 CONFIG_USB_ETH 及相关旧架构,开启 ConfigFS ECM/RNDIS。 补丁 (sdk/tspi-rk3566-sdk/kernel-6.1/arch/arm64/configs/rockchip_linux_defconfig): --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -502,9 +502,15 @@ CONFIG_USB_GADGET_VBUS_DRAW=500 CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_UEVENT=y CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y CONFIG_USB_CONFIGFS_MASS_STORAGE=y CONFIG_USB_CONFIGFS_F_FS=y CONFIG_USB_CONFIGFS_F_UVC=y +#CONFIG_USB_ETHisnotset+# CONFIG_USB_ETH_RNDIS is not set CONFIG_TYPEC_TCPM=y CONFIG_TYPEC_TCPCI=y CONFIG_TYPEC_HUSB311=y --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -502,9 +502,15 @@ CONFIG_USB_GADGET_VBUS_DRAW=500 CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_UEVENT=y CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y CONFIG_USB_CONFIGFS_MASS_STORAGE=y CONFIG_USB_CONFIGFS_F_FS=y CONFIG_USB_CONFIGFS_F_UVC=y +#CONFIG_USB_ETHisnotset+# CONFIG_USB_ETH_RNDIS is not set CONFIG_TYPEC_TCPM=y CONFIG_TYPEC_TCPCI=y CONFIG_TYPEC_HUSB311=y 1.2 屏蔽物理引脚干涉 痛点:底层设备树会监听 Type-C 物理状态,易误判为 Host 模式导致外设注册失败。(maybe) 方案:强制删除 extcon 属性,固定为从机 (peripheral) 模式。 补丁 (sdk/tspi-rk3566-sdk/kernel-6.1/arch/arm64/boot/dts/rockchip/tspi-rk3566-user-v10-linux.dts): --- a/arch/arm64/boot/dts/rockchip/tspi-rk3566-user-v10-linux.dts +++ b/arch/arm64/boot/dts/rockchip/tspi-rk3566-user-v10-linux.dts @@ -194,3 +194,10 @@ ir_key1 {                       <0xe6   KEY_0>;       }; }; + +//Force USB Type-C to act as peripheral (Gadget) for RNDIS/ADB +&usbdrd_dwc3 { +       dr_mode = "peripheral"; +       /delete-property/ extcon; +       status = "okay"; +}; --- a/arch/arm64/boot/dts/rockchip/tspi-rk3566-user-v10-linux.dts +++ b/arch/arm64/boot/dts/rockchip/tspi-rk3566-user-v10-linux.dts @@ -194,3 +194,10 @@ ir_key1 {                       <0xe6   KEY_0>;       }; }; + +//Force USB Type-C to act as peripheral (Gadget) for RNDIS/ADB +&usbdrd_dwc3 { +       dr_mode = "peripheral"; +       /delete-property/ extcon; +       status = "okay"; +}; 2. Buildroot 层:NFS 客户端支持 2.1 添加 NFS 组件解决挂载失败 痛点:RK3566 默认极简文件系统无 NFS 客户端,导致 mount -a 失败。 方案:开启 nfs-utils 和 NFS client(可取消 rpc.nfsd 节省空间),重新编译 rootfs.img。 补丁 (sdk/tspi-rk3566-sdk/buildroot/configs/rockchip_rk3566_defconfig): --- a/configs/rockchip_rk3566_defconfig +++ b/configs/rockchip_rk3566_defconfig @@ -22,6 +22,9 @@ #include "gui/weston.config" BR2_PACKAGE_IPERF3=y BR2_PACKAGE_MINICOM=y +BR2_PACKAGE_NFS_UTILS=y +BR2_PACKAGE_NFS_UTILS_NFSV4=y +# BR2_PACKAGE_NFS_UTILS_RPC_NFSD is not set BR2_PACKAGE_OPENSSH=y BR2_PACKAGE_QUECTEL_CM=y BR2_PACKAGE_TINYALSA=y --- a/configs/rockchip_rk3566_defconfig +++ b/configs/rockchip_rk3566_defconfig @@ -22,6 +22,9 @@ #include "gui/weston.config" BR2_PACKAGE_IPERF3=y BR2_PACKAGE_MINICOM=y +BR2_PACKAGE_NFS_UTILS=y +BR2_PACKAGE_NFS_UTILS_NFSV4=y +# BR2_PACKAGE_NFS_UTILS_RPC_NFSD is not set BR2_PACKAGE_OPENSSH=y BR2_PACKAGE_QUECTEL_CM=y BR2_PACKAGE_TINYALSA=y 3. Shell层:ADB-RNDIS 兼容与网络自启 3.1 规避 USB 脚本正则解析陷阱 痛点:官方 /usr/bin/usb-gadget 脚本对配置文件解析存在正则缺陷,遇到 =on 等赋值会截断异常。 方案:配置文件中严禁使用 =on,仅保留宏名本身。 写入文件 (/etc/.usb_config): usb_adb_en usb_rndis_en usb_adb_en usb_rndis_en 3.2 RNDIS 自动分配 IP 与路由配置 痛点:RNDIS 虚拟网卡 usb0 生成后默认无网络配置。 方案:编写 usb-gadget 启动后置钩子脚本,自动配置 IP 并打通 Windows 网络共享 (ICS) 的 192.168.137.x 网段路由及 DNS。 写入文件 (/etc/usb-gadget.d/rndis.sh): #!/bin/sh rndis_post_start_hook() {    while ! ifconfig usb0 >/dev/null 2>&1; do        sleep .1    done   ifconfig usb0 192.168.137.2 netmask 255.255.255.0 up   route add default gw 192.168.137.1    echo "nameserver 8.8.8.8" > /etc/resolv.conf    echo "nameserver 114.114.114.114" >> /etc/resolv.conf } #!/bin/sh rndis_post_start_hook() {    while ! ifconfig usb0 >/dev/null 2>&1; do        sleep .1    done   ifconfig usb0 192.168.137.2 netmask 255.255.255.0 up   route add default gw 192.168.137.1    echo "nameserver 8.8.8.8" > /etc/resolv.conf    echo "nameserver 114.114.114.114" >> /etc/resolv.conf } 4. Host (宿主机) 端配置:ADB 识别 4.1 添加 Vendor ID (VID) 白名单 痛点:由于泰山派作为复合设备时的 Vendor ID 为 0x2207 (Rockchip),某些情况下宿主机的 ADB 进程无法自动识别该非标/第三方设备的 USB 接口,导致 adb devices 找不到设备。 方案:在宿主机的用户目录下创建/修改 .android/adb_usb.ini 文件,强制 ADB 进程扫描该 VID。 写入文件 (Windows: C:\Users\<Name>\.android\adb_usb.ini / Linux/WSL: ~/.android/adb_usb.ini): 0x2207 0x2207 生效命令:配置完成后在宿主机终端执行 adb kill-server 与 adb start-server。 4.2 Windows 设备管理器状态验证 在 Windows “设备管理器” -> “设备属性” -> “详细信息” -> “硬件 Id” 中,该复合设备的接口通常显示为: USB\VID_2207&PID_0013&REV_0310&MI_02 USB\VID_2207&PID_0013&MI_02 USB\VID_2207&PID_0013&REV_0310&MI_02 USB\VID_2207&PID_0013&MI_02 注:PID_0013 是 Rockchip 为 RNDIS+ADB 组合分配的 Product ID,MI_02 代表这是复合设备中的对应接口(通常代表 ADB 接口)。 5. 结果验证 烧录并启动后,通过电脑端连接 Type-C 接口: 多路网络:开发板通过 usb0 顺畅连接外网,本地宿主机可通过局域网 IP (192.168.137.2) 进行 NFS 和 SSH 连接。 复合 Gadget:设备成功变身复合设备,支持 USB 物理底层 adb shell 及网络端 adb connect 192.168.137.2:5555 并行使用。 WSL2 搭建NFS Server + 开发板配置NFS Client 完整流程总结 全程基于****WSL2 Ubuntu/Debian(NFS服务端)+ 嵌入式Linux开发板(NFS客户端),核心解决WSL2专属坑点(insecure参数、IP解析、权限映射),步骤极简可落地,按顺序执行即可实现开发板挂载WSL的NFS共享目录(读写正常)。 一、WSL2 端:NFS Server 配置(核心步骤) 前提准备 确认WSL为****WSL2:wsl -l -v,若为WSL1执行 wsl --set-version 发行版名 2升级; 记录WSL2内网IP(开发板挂载用):ip a show eth0 → 取 inet后IP(如 192.168.31.110); 确保WSL与开发板****同一内网(连同一个路由器,IP段一致如 192.168.31.x)。 步骤1:安装NFS服务端依赖 sudo apt update && sudo apt install -y nfs-kernel-server rpcbind 步骤2:创建NFS共享目录(避坑:仅在WSL自身文件系统创建) 禁止建在**/mnt/c/d**(Windows挂载目录,权限失效),建议在 /home/下创建: # 示例目录:/home/pi/imx/mount,可自定义 sudo mkdir -p /home/pi/imx/mount # 赋予全权限(双重校验:NFS配置+Linux本地权限) sudo chmod -R 777 /home/pi/imx/mount sudo chown -R $(whoami):$(whoami) /home/pi/imx/mount 步骤3:配置NFS共享规则(/etc/exports,WSL必配 insecure) 直接覆盖写入(避免格式错误,3种客户端规则任选其一,推荐局域网网段): #格式:共享目录客户端IP/网段(核心参数,无空格!)# 选项1:允许整个局域网(推荐,开发板/虚拟机通用) sudo echo "/home/pi/imx/mount 192.168.31.0/24(rw,sync,no_root_squash,no_subtree_check,insecure)" > /etc/exports # 选项2:允许单个开发板IP(最安全,如开发板IP192.168.31.100) # sudo echo "/home/pi/imx/mount 192.168.31.100(rw,sync,no_root_squash,no_subtree_check,insecure)" > /etc/exports #选项3:允许所有设备(测试用,简单)# sudo echo "/home/pi/imx/mount *(rw,sync,no_root_squash,no_subtree_check,insecure)" > /etc/exports 核心参数必选原因(WSL+开发板专属) rw:读写权限;sync:数据同步写入(防丢失); no_root_squash:开发板root挂载拥有WSL目录root权限(嵌入式必配,避 Permission denied); no_subtree_check:关闭子目录检查,提升性能; insecure:WSL2核心坑点,允许非特权端口访问(不加直接挂载失败)。 步骤4:加载配置+启动NFS服务(确保规则生效) # 清除旧规则→加载新规则→启动服务→设置开机自启 sudo exportfs -au && sudo exportfs -r sudo service rpcbind start && sudo service nfs-kernel-server start sudo update-rc.d rpcbind enable && sudo update-rc.d nfs-kernel-server enable 步骤5:开放WSL防火墙端口(NFS必备111/2049) # 开放TCP+UDP端口,或直接关闭防火墙(测试用) sudo ufw allow 111/tcp && sudo ufw allow 111/udp sudo ufw allow 2049/tcp && sudo ufw allow 2049/udp sudo ufw reload #测试用快捷方式:临时关闭防火墙# sudo ufw disable 步骤6:验证WSL NFS服务是否正常(3条命令必过) # 1. 查看生效的共享规则(有输出即正常) sudo exportfs -v # 2. 本地查询共享列表(有目录输出即正常) showmount -e 127.0.0.1 # 3. 检查服务状态(显示active即正常) sudo service nfs-kernel-server status && sudo service rpcbind status 二、开发板端:NFS Client 挂载配置(极简步骤) 前提准备 开发板联网并与WSL同一内网,记录开发板IP(可选); 确认开发板已安装NFS客户端工具(嵌入式Linux一般自带,无则手动装)。 步骤1:安装NFS客户端依赖(无则执行,如OpenWrt/纯版Linux) # Debian/Ubuntu系开发板 sudo apt install -y nfs-common # 嵌入式Linux(如RT-Thread/OpenWrt) opkg install nfs-utils-client # 龙芯/IMX等原厂系统(一般自带,无需安装) 步骤2:创建开发板本地挂载点(可自定义,如/mnt/nfs 或 /mnt ) sudo mkdir -p /mnt/nfs  # 推荐单独创建,避免覆盖原有/mnt内容 步骤3:NFS挂载核心命令(指定NFSv3,嵌入式兼容性最好) # 格式:sudo mount -t nfs -o 客户端参数 WSL2IP:WSL共享目录 开发板挂载点 mount -t nfs -o rw,sync,vers=3,nolock 192.168.31.110:/home/pi/imx/mount /mnt ​ mount -t nfs -o nolock,vers=3 192.168.31.110:/home/pi/imx/mount /mnt 客户端参数说明 vers=3:指定NFSv3版本(WSL的NFSv4偶尔有兼容问题,v3最稳定); nolock:嵌入式Linux推荐,关闭文件锁(避免部分开发板锁机制报错); rw,sync:与服务端保持一致,强化读写/同步。 步骤4:验证挂载是否成功(读写测试+查看挂载状态) # 1. 查看挂载状态(有WSL IP和共享目录即正常) df -h # 2. 开发板写入测试(创建文件,WSL端可同步看到即成功) sudo touch /mnt/nfs/test_from_board.txt sudo echo "开发板挂载NFS成功" > /mnt/nfs/test_from_board.txt # 3. WSL端验证(回到WSL执行,能看到文件内容即读写正常) cat /home/pi/imx/mount/test_from_board.txt 可选:在 fstab自动挂载 # 编辑fstab,添加挂载规则 sudo vim /etc/fstab # 写入以下内容(WSL2IP+共享目录+开发板挂载点,按实际修改) 192.168.31.110:/home/pi/imx/mount /mnt/nfs nfs rw,sync,vers=3,nolock 0 0 # 生效配置(无报错即正常) sudo mount -a ⚠️ 注意:若WSL2重启后IP变化,需更新 /etc/fstab中的WSL IP(WSL2静态IP可自行配置,解决IP变动问题)。 开发板卸载NFS目录(如需) #正常卸载sudoumount/mnt/nfs# 强制卸载(挂载卡死时用) sudo umount -lf /mnt/nfs 三、核心避坑点(WSL+开发板NFS挂载高频问题) WSL版本:必须WSL2,WSL1不支持网络转发和NFS核心功能; 共享目录位置:禁止在 /mnt/c/d创建,仅在WSL /home/下创建(权限生效); 参数格式:/etc/exports中参数无任何空格,中文括号/逗号会导致解析失败; IP合法性:客户端规则不能写 192.168.31.xxx占位符,用合法格式(网段/具体IP/*); 双重权限校验:不仅要NFS配置 rw,还要给WSL共享目录加 777Linux本地权限; WSL IP变动:WSL2重启后IP会变,需重新记录并更新开发板挂载命令/fstab。 四、故障快速排查(按顺序查,99%问题可解决) 现象1:开发板 showmount -e WSLIP → 提示 No route to host 排查:WSL与开发板是否同一内网?WSL防火墙是否开放111/2049端口?WSL的rpcbind/nfs-server是否启动? 解决:重启路由器/重新连网;WSL执行 sudo ufw disable(临时关防火墙);重启NFS服务 sudo service nfs-kernel-server restart。 现象2:开发板挂载 → 提示 Permission denied 排查:WSL的 /etc/exports是否加 insecure和 no_root_squash?共享目录是否 777权限?客户端是否用 sudo挂载? 解决:重新配置 /etc/exports并加载;给目录加 chmod 777;开发板挂载命令加 sudo。 现象3:WSL执行 sudo exportfs -v → 无输出/解析失败 排查:/etc/exports格式是否错误?客户端IP/网段是否合法?共享目录是否存在? 解决:重新用 echo覆盖写入合法配置;检查目录是否创建;客户端规则用 192.168.31.0/24或 *。 现象4:开发板挂载成功但能读不能写 排查:WSL共享目录Linux本地权限是否不足?/etc/exports是否误写 ro? 解决:执行 chmod -R 777 共享目录;检查 /etc/exports确保是 rw而非 ro,重新加载配置。
泰山派RNDIS/ADB共存与NFS文件系统
立创开发板
在计算机编程的世界中,C++是一门备受推崇的编程语言,它的强大之处之一就是支持面向对象编程(Object-Oriented Programming,OOP)。在C++中,类和对象是面向对象编程的核心概念,它们为程序员提供了一种结构化的方式来组织和管理代码。1. 类(Class):抽象的蓝图在C++中,类是一种用户定义的数据类型,用于封装数据和方法。可以将类看作是对象的抽象蓝图,其中包含了描述对象属性和行为的成员变量和成员函数。通过定义类,程序员可以创建自己的数据类型,从而更好地组织和管理代码。 例如我们可以把人作为一个对象,他有基本的属性:性别、身高、年龄等等 也有基本的行为:吃饭、睡觉、学习、玩游戏等等。1.1 类的基本结构一个简单的类通常包含以下几个要素:class MyClass { private: // 成员变量(属性) int myInt; double myDouble; public: // 构造函数 MyClass() { myInt = 0; myDouble = 0.0; } // 成员函数(方法) void setValues(int i, double d) { myInt = i; myDouble = d; }     ~MyClass() { } }; class + 类名 的方法创建我们的类。 类中的变量可以称作成员,他们有一些访问属性:Protect:保护,private:私密,public:公开 故名思意除了public其他的变量都不可以在类外被访问。 类中有两种特殊的函数 与类名相同的名称被称作构造函数,我们在创建类的同时会调用构造函数! 同样的还有一个特殊的函数:析构函数,和析构函数差不多,但是需要多一个~符号,这个函数会在类被释放的时候调用。1.2 类的实例化通过定义类,我们可以创建类的实例,也称为对象。对象是类的具体实体,可以调用类中定义的方法,访问和修改成员变量。int main() { // 创建类的实例 MyClass myObject; // 调用成员函数     myObject.setValues(42, 3.14); return 0; } 2. 对象(Object):实体化的具体实例对象是类的实例,是具体存在的数据单元。在C++中,通过创建对象,我们可以利用类定义的结构来存储和操作数据。2.1 对象的特性对象具有以下几个重要的特性:封装性(Encapsulation): 类的内部实现对外部是不可见的,只有通过公共接口(成员函数)才能访问类的属性和方法,确保了数据的安全性和代码的模块化。继承性(Inheritance): 类可以通过继承从其他类中获取属性和方法,实现代码的重用和扩展。多态性(Polymorphism): 不同的类可以具有相同的接口,但表现出不同的行为,提高了代码的灵活性和可维护性。2.2 对象的生命周期对象的生命周期从创建到销毁,包括对象的构造、使用和析构阶段。在C++中,构造函数和析构函数负责对象的初始化和清理工作。int main() { // 创建对象,调用构造函数 MyClass obj; // 对象在main函数结束时销毁,调用析构函数 return 0; C++中的类和对象为程序提供了一种灵活而强大的编程范式,使得代码更易理解、维护和扩展。通过合理利用类和对象,程序员可以更好地组织和管理代码,提高代码的可读性和可维护性。
C++中的类和对象:面向对象编程的基石
嘉立创PCB
随着我国无线通信和物联网技术的发展,WiFi已普及到我们的生活每一个角落。无线WiFi设备已经被带到太空,实现神舟十二号载人飞船空间站“移动WiFi”智能生活空间。为了更方便的应用与生产,WiFi也逐渐形成了模块化的形式。作为WiFi模块厂家方案商,和你一起了解高性价比无线路由方案的WiFi模块。WiFi模块是将串口或TTL电平转为符合WiFi无线网络通信标准的嵌入式模块,WiFi模块可以直接利用WiFi联入互联网,是实现无线智能家居,M2M等物联网应用的重要组成部分。现在我们聊的是WiFi模块中既可用于广域网也可以用于局域网的无线路由器方案WiFi模块,以RMS7628N模块为例。   RMS7628N无线路由器方案WiFi模块就是基于通用串行接口符合网络标准的嵌入式WiFi模块,内置TCP/IP协议栈,可实现串口,以太网,无线网(WiFi)接口之间的相互连接。是新一代802.11n Wi-Fi AP/路由器系统单芯片解决方案(SoC)。为智能家庭内的数据、语音和影像应用程序提供高数据传输率,而且耗电量低。MT7628和MT7620一样具有2T2R 300M wifi速率,接口丰富,但是它比MT7620功耗更低、芯片成本更低,专门针对物联网应用推出3个串口、PWM输出等特点,可谓是MT7620的升级产品。无线路由方案WiFi模块体积小、功耗低、发热量小,wifi、网口传输性能稳定。运行openwrt(linux)系统,可长期稳定运行。模块外围电路非常简单,仅需加上3.3V DC电源,即可让系统启动,并可通过WIFI控制。    RMS7628N无线路由方案WiFi模块可用于有线转WiFi、4G转WiFi、吸顶AP、4G路由器、无线音箱、无线存储扩容、无线图传、数据透传、智能家居、IP camera、遥控拍摄飞行器、远程视频监控系统等
物联网智能工控网关 高性价比的无线路由方案的WiFi模块RMS7628N
开源硬件平台
#嘉立创EDA#敬爱的嘉立创EDA产品与研发团队:你们好! 我是一名陪伴嘉立创EDA走过多年的忠实用户,也是一名坚定的EDA国产替代信仰者。从用EasyEDA标准版画第一块核心板,到如今创业做工业硬件研发全程以专业版为核心工具,我亲眼见证了咱们的国产EDA从“浏览器里的轻量化工具”,成长为打破海外巨头垄断、打通“设计-制造”全链路、真正实现硬件研发普惠化的行业标杆。 我始终坚信,咱们的核心竞争力,从来不是对海外EDA工具的简单复刻,而是走出了一条“云原生+制造闭环+低门槛普惠”的中国特色EDA之路。永久免费的授权模式、开箱即用的百万级国产器件库、与生产端无缝衔接的DFM体系、原生的多人协同能力,这些都是Altium、Cadence等海外厂商永远无法给中国硬件开发者的核心价值。也正因如此,我始终把嘉立创EDA作为首选工具,向身边的学生、创客、中小企业同行反复推荐,我真心希望咱们的国产EDA,能真正站到全球EDA行业的顶端。 但作为一名深度用户,我也不得不直面困扰我和身边同行多年的核心瓶颈——**性能短板,正在成为咱们向下普惠、向上突破的最大障碍**。我见过太多学生用宿舍的低配置笔记本,画一个仅几十器件的两层板,就出现画布缩放、元件拖动的肉眼可见卡顿,哪怕关掉所有实时功能也无法获得流畅体验,最后只能无奈转向盗版AD。 我深知,团队这些年从未停止过性能优化的努力:从Canvas到WebGL再到WebGPU的渲染引擎三代迭代,从增量铺铜到多线程DRC的算法优化,从V2到V3版本对工程格式、原理图引擎的全面重构,每一个版本的更新日志里,都能看到你们为解决性能痛点付出的心血。但我也必须坦诚地说:**当前Electron+Web的原生架构,从底层就给咱们的性能天花板划定了边界,局部的优化迭代,已经很难抹平与海外原生架构EDA的代际差距,更难从根源解决“低配置电脑哪怕画小PCB也卡顿”的基础体验问题**。 经过调研与深度思考,我想给团队提一个建设性建议:《基于国产Cocos Creator 3D引擎,重构咱们EDA软件的渲染与交互内核》。这个提议绝非一时兴起的空想,它既能完整保留咱们当前所有的核心产品优势,更能从底层架构上彻底突破性能瓶颈,实现对海外EDA厂商的弯道超车。以下是我完整的论证与分析,恳请团队能耐心看完。 一、基于Cocos引擎重构EDA,具备100%的技术可行性 Cocos绝非只能做游戏的娱乐向引擎,它已经是经过工业级场景验证、完全自主可控、性能与成熟度拉满的国产跨平台3D渲染引擎,其核心能力与EDA软件的底层需求高度契合,可行性已经过全维度验证:1. 渲染能力完全覆盖EDA全场景核心需求 EDA软件的核心交互载体,是**高精度2D矢量布线画布**与**工业级3D装配预览**,这两项需求恰好是Cocos引擎的核心优势,成熟度远超咱们自研的渲染引擎。 在2D布线场景,Cocos底层GFX图形框架原生支持WebGPU、Vulkan、Metal、OpenGL等全平台图形API,内置成熟的Signed Distance Fields(SDF)矢量渲染管线,可实现任意缩放级别下的线条无损、无锯齿渲染,与PCB设计“纳米级坐标精度、无限缩放无失真”的核心要求完全契合。同时它原生支持分层渲染、视口裁剪、GPU实例化、静态批处理等优化技术,我们可以针对EDA场景定制专属渲染管线:将布线层、飞线层、DRC标记层、铺铜层拆分为独立渲染单元,仅重绘变更的图层与视口内的图元,从根源解决当前画布缩放、平移卡顿的核心痛点。在3D可视化场景,Cocos引擎已经落地了车载智能座舱、ADAS 3D可视化等对精度、稳定性要求极高的工业场景,其原生支持PBR物理渲染、百万级多边形模型实时渲染、STEP/IGES标准3D模型导入、实时碰撞检测,完全满足PCB 3D预览、机电协同装配、干涉校验的全流程需求。更重要的是,这套渲染管线经过了全球20亿终端用户的验证,在显卡适配、性能优化、显存管理上的成熟度,远超EDA厂商自研方案。 2. 架构设计从底层解决当前所有核心性能瓶颈 当前咱们的核心卡顿根源,是Electron+JS单线程架构的原生缺陷,而Cocos的架构设计从底层就规避了这些问题。一方面,Cocos采用**C++底层内核+TypeScript上层API**的混合架构,底层渲染、场景管理、物理计算均由C++实现,原生支持**渲染线程、逻辑线程、物理线程、计算线程完全分离**。这套架构可以彻底解决咱们的核心卡顿痛点:将DRC规则校验、铺铜计算、交互式布线算法、仿真分析等算力密集型任务,完全剥离到独立的计算线程执行,无论计算负载多高,都不会阻塞UI主线程的画布交互,彻底告别“一计算就卡死”的顽疾。另一方面,Cocos拥有极致轻量的运行时,空工程原生客户端内存占用仅**<100MB**,冷启动时间<3秒,对比当前Electron架构空工程1-2GB的内存占用、10秒以上的启动时间,基础资源开销降低了90%以上。哪怕是4GB内存、双核CPU、入门级核显的低配置电脑,也能流畅运行小型PCB设计,真正实现咱们“让所有人都能轻松做硬件”的普惠初心。3. 跨平台能力完美匹配咱们的产品核心定位 Cocos的核心定位就是“高效、轻量、跨平台、全功能3D开发引擎”,原生支持Windows、macOS、Linux、Web、HarmonyOS Next、Android、iOS等几乎所有主流平台,一套代码可实现多端一键编译。 这套跨平台能力,既能完整保留咱们“Web端免安装、打开浏览器即可设计”的核心优势,又能通过原生编译彻底摆脱Electron架构的内存泄漏、高资源占用问题;同时借助Cocos Runtime能力,可实现PCB工程的轻量化分享——无需安装完整软件,点击链接即可打开工程完成查看、批注、校验,完美适配云协同、轻量化交付的工业场景;更重要的是,它原生适配所有国产操作系统与芯片平台,完全符合国产EDA的自主可控战略。 4. 完全自主可控的开源生态,无任何技术封锁风险 Cocos引擎采用MIT开源协议,底层核心模块完全开源,无海外技术封锁风险,我们可以根据EDA需求对引擎进行深度定制改造,这是Unity、Unreal等海外引擎永远无法比拟的优势,也完全契合咱们国产EDA的国产化核心要求。同时,Cocos拥有全球170万注册开发者,国内移动游戏市场份额达40%,生态内有大量成熟的物理引擎、网络协同模块、UI框架、插件工具,我们无需从零开发EDA的配套能力,研发成本与周期可降低50%以上,能把更多精力投入到EDA核心算法、制造闭环的优化上。5. 行业已有成熟的技术验证先例 学术界与工业界早已验证了游戏引擎用于EDA开发的可行性:学术界已有基于游戏引擎面向数据设计(DOD)理念构建的开源PCB物理设计库,大幅提升了超大工程的处理性能;工业界已有基于Unreal Engine构建的数字电路仿真系统、PCB 3D可视化平台,实现了沉浸式电路设计、实时信号流可视化、3D装配校验等功能;而Cocos引擎更是已经在车载HMI、工业数字孪生、智能装备可视化等领域实现大规模量产落地,其实时渲染、高精度交互、工业级稳定性均已通过市场验证,完全满足EDA软件的工业级要求。二、基于Cocos引擎重构,将带来碾压级的性能优势 这套架构重构,绝非简单的技术栈替换,而是能从根源上解决当前所有性能痛点,在全维度实现对现有架构、甚至海外主流EDA的性能超越,核心优势集中在五大维度:1. 基础运行开销实现数量级下降,彻底解决低配置设备适配难题 重构后,咱们的软件空工程内存占用将从1-2GB降至100MB以内,冷启动时间从8-15秒缩短至3秒以内,基础资源开销仅为当前架构的1/10。对于低配置电脑,哪怕是几十器件的小型PCB,当前架构也会因基础开销过高触发内存交换、CPU满载,而重构后的架构仅占用极少系统资源,可实现全程流畅交互,从根源解决“小PCB也明显卡顿、低配置电脑完全无法使用”的用户痛点,真正把硬件研发的普惠门槛降到最低。2. 渲染性能实现代际提升,彻底告别画布交互卡顿 重构后,10万焊盘级别的PCB工程,画布缩放、平移、元件拖动可稳定60FPS满帧运行,流畅度是当前架构的2-3倍,甚至超过Altium Designer。基于SDF的矢量渲染方案,PCB走线、焊盘在任意放大倍数下都清晰锐利,无锯齿失真,同时渲染性能不会因缩放而下降;全板飞线、DRC违规标记、网络高亮等叠加元素,可通过独立渲染层实现,不会阻塞主线程,也不会影响基础画布的交互流畅度,我们再也不用为了流畅度,被迫关闭实时DRC、隐藏飞线、关闭铺铜。3. 算力密集型场景实现架构突破,彻底解决编辑响应延迟 Cocos的多线程分离架构,让铺铜、DRC、布线算法等算力任务完全运行在独立线程,哪怕全板重铺、全量DRC校验,用户仍可正常操作画布,无任何卡顿;同时原生支持多核并行计算,可将全板DRC、铺铜三角化、等长匹配等任务拆分到多核CPU并行执行,计算速度比当前架构提升5-10倍;再加上原生支持的增量计算,仅重算设计变更的区域,而非全板重算,编辑后的响应速度比当前架构提升10倍以上,彻底告别大工程“动一下等几秒”的噩梦。4. 3D可视化与机电协同能力实现质的飞跃 重构后,包含数千个元器件的PCB 3D预览,可稳定60FPS旋转、缩放,流畅度远超当前架构与Altium;内置的Bullet工业级物理引擎,可实现实时3D碰撞检测、装配干涉校验,甚至模拟元器件插拔、散热风道、跌落测试,这些能力是海外大厂都不具备的差异化优势;同时原生支持几乎所有工业3D模型格式,导入解析速度比当前架构快数倍,显存占用降低50%以上,能让咱们的机电协同能力直接跻身行业顶尖水平。 5. 云协同与跨端体验实现全面升级 重构后的Web版EDA,页面加载时间<2秒,内存占用<200MB,对比当前网页版5秒以上的加载时间、1GB以上的内存占用,对低配置电脑、弱网环境的友好度大幅提升;原生支持的网络状态同步机制,结合OT算法实现多人实时协同,增量同步数据包更小,同步延迟更低,不会出现多人协同场景下的卡顿、冲突问题;同时原生客户端可完全离线运行,工程文件存储在本地,资源占用极低,对比当前Electron架构的离线模式,稳定性、性能、内存控制都有质的提升。 三、核心技术挑战与成熟落地方案 我深知,EDA软件的工业级属性,决定了架构重构绝非易事,我也针对大家可能顾虑的核心技术挑战,做了完整的解决方案论证,所有方案均有成熟的行业先例,不存在无法突破的技术壁垒: 第一,针对PCB设计的纳米级数学精度适配问题,我们可以采用**双精度业务内核 + 视口相对坐标渲染**的混合架构。底层EDA核心数据层全程采用double双精度浮点数,保证PCB设计的纳米级数学精度,所有电气规则校验、坐标计算均在该层完成,与渲染层完全解耦;渲染层仅处理当前视口内的相对坐标,将双精度的绝对坐标转换为单精度的视口相对坐标,再交给Cocos引擎渲染,这也是Altium等海外大厂沿用多年的成熟方案,完全不会有精度丢失的问题。 第二,针对统一数据模型与引擎节点系统的映射问题,我们可以构建**独立EDA核心数据层 + 引擎映射中间层**的解耦架构。完整保留咱们当前已经非常成熟的V3增量日志型数据模型作为整个软件的唯一可信数据源,与渲染引擎完全无关;仅做一层轻量的中间映射层,实现数据模型与Cocos场景节点的双向映射:数据层的变更实时同步到Cocos的渲染节点,用户在Cocos画布中的操作,通过中间层校验后回写到核心数据层,既保证了设计数据的一致性与严谨性,又完全不会动摇咱们多年积累的核心数据资产。 第三,针对EDA专用算法的集成与优化问题,我们可以将交互式布线、铺铜、DRC校验等核心算法,用C++/Rust独立编写,客户端编译为原生插件,Web端编译为WebAssembly(WASM),通过Cocos的原生扩展机制集成,获得接近原生的计算性能。算法执行与渲染完全解耦,所有算力任务均在独立的计算线程中运行,既保留咱们多年积累的算法优势,又能获得多核并行计算的性能提升,甚至可以复用Cocos内置的物理引擎,优化布线避障、3D碰撞检测等算法,降低自研成本。 第四,针对工业制造文件与第三方工具的兼容性问题,我们可以在底层核心数据层实现完整的导入/导出器体系,与渲染引擎完全解耦,不依赖Cocos的任何能力。所有Gerber导出、第三方工程文件导入导出、MCAD工具对接,均和当前的实现逻辑完全一致,无技术壁垒,完全不会影响咱们多年积累的兼容性优势。最后 敬爱的研发与产品团队,我写这封信,不是来挑刺吐槽的,是作为一名陪伴了你们多年的老用户,真心想和咱们团队站在一起,突破当前最大的发展瓶颈。 我从来没有因为功能缺失放弃过嘉立创EDA,却无数次因为卡顿、响应慢而焦虑;我从来没有因为海外大厂的功能更全而动摇过国产替代的信仰,却无数次因为身边同行因为性能问题放弃咱们的产品而惋惜。我真心不希望,咱们已经打通了最难的设计-制造闭环,已经打破了海外巨头的垄断,最后却被性能这个短板,拦住了走向全球顶尖的脚步。 更重要的是,用国产Cocos引擎,做国产EDA,是国产替代赛道上的强强联合,我们能打造出一套从渲染引擎到EDA工具、从设计到制造完全自主可控的硬件创新全链路,这不仅是产品体验的升级,更是中国工业软件发展史上的重要一步。 如果团队愿意考虑这个方向,我愿意无偿参与所有的内测、验证,把我这些年的深度使用体验、所有的痛点和需求,毫无保留地反馈给你们。 我始终相信,嘉立创EDA一定能成为全球顶尖的EDA工具,一定能让全球的硬件开发者,都用上咱们中国人做的EDA软件。这条路很难,但我会一直陪着你们走下去。此致敬礼一名嘉立创EDA的忠实用户国产EDA替代的坚定信仰者2026年4月24日
致嘉立创EDA产品与研发团队的一封信
嘉立创EDA
前面几期利用.NET MAUI我们开发了一个Android应用用来接收ESP32的图片数据以及制作了一个摇杆方便我们操控。 但是有一点,我们发送图片以及交流的IP都是固定的。 可是,IP地址会随着网络以及设备发生变换,那么我们怎么知道每次的IP地址呢。 本期我们将介绍ESP32如何开启AP模式来让手机进行连接并且获取所连接的设备的IP地址。 在ESP的AP模式下,设备像一个Wi-Fi网络中的路由器一样,允许其他设备通过Wi-Fi连接到它,从而建立本地网络。这种模式通常用于创建一个局域网(Local Area Network,LAN),其中ESP设备充当中心节点,其他设备可以通过该节点相互通信。 通过AP模式,ESP设备可以提供网络连接、数据传输和通信服务,使其他设备能够连接到互联网或者在局域网内进行数据交换。这对于构建物联网应用和连接智能设备非常有用。代码编写#includeesp_wifi.h#include <Wifi.h> 首先需要导入这两个库,分别用来连接WiFi和获取设备IP  WiFi.softAP(ssid, password);//AP模式开启Wifi ip = WiFi.softAPIP();//获取本机IP   Serial.println(ip);//打印IP   WiFi.onEvent(WiFiEvent);//创建一个事件用来监听事件 使用上述语句开启WiFi AP模式,ssid为Wifi的名字,password为Wifi的密码,注意这个密码至少八个字符!! 可以看到可以发现一个ESP32的Wifi.void WiFiEvent(WiFiEvent_t event) {   if(event == 13)   {    wifi_sta_list_t wifi_sta_list; tcpip_adapter_sta_list_t adapter_sta_list; memset(&wifi_sta_list, 0, sizeof(wifi_sta_list)); memset(&adapter_sta_list, 0, sizeof(adapter_sta_list)); esp_wifi_ap_get_sta_list(&wifi_sta_list); tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list); for (int i = 0; i < adapter_sta_list.num; i++) { tcpip_adapter_sta_info_t station = adapter_sta_list.sta[i]; Serial.print("station nr "); Serial.println(i + 1); Serial.print("MAC: "); for (int i = 0; i < 6; i++) { Serial.printf("%02X", station.mac[i]); if (i < 5) Serial.print(":"); } Serial.print("\nIP: "); ip4_addr_t ip_buf; memcpy((char *)&ip_buf, (char *)&station.ip, sizeof(ip4_addr)); String ipstr = ip4addr_ntoa(&(ip_buf)); Serial.println(ipstr); } } } 接着为Wifi添加事件回调。(这些设备包括:设备断开,设备连接,设备被分配到IP......) 当有Wifi事件触发时,我们打印连接设备的IP地址。 这里Wifi连接和赋予地址都会触发回调,我们只处理赋予IP地址的事件 wifi_sta_list_t 和 tcpip_adapter_sta_list_t 是结构体,用于存储STA(Station)列表的信息。 memset 函数用于将结构体初始化为零,以确保所有字段的初始值为零。 esp_wifi_ap_get_sta_list 用于获取与当前AP连接的STA列表,并将结果存储在 wifi_sta_list 中。 tcpip_adapter_get_sta_list 则用于将 wifi_sta_list 中的信息转换为 adapter_sta_list 结构体中。 接下来,通过循环遍历 adapter_sta_list 中的STA列表,逐个处理每个STA的信息。 最后是打印IP信息。 一个是本机地址,一个是我手机所连接的IP。String ipstr = ip4addr_ntoa(&(ip_buf)); if (ipstr== ("0.0.0.0")) { continue; } staIPAddresses[i] = ipstr; STANumber = i; Serial.println(ipstr); 我们比较一下,剔除掉自身的IP,然后保存所有设备的IP。if (ipstr== ("0.0.0.0")) { continue; } staIPAddresses[i] = ipstr; STANumber = i;
ESP32使用Arduino IDE开启Wifi AP模式并获取所连接设备地址
嘉立创PCB
一、方案背景在前端中经常会出现多接口并发的场景,而针对请求常规方式会一股脑发送给浏览器,浏览器中会对大量请求进行排队,但大量请求推送至浏览器就会占用内存,最后达到一定量级导致页面卡顿,甚至假死常规请求图如下二、解决思路针对此模式,我们可以创建如下序列,待发送请求池作为中间层,只作为载体,每次推送固定数量到浏览器,当浏览器主线程中存在接口执行完毕后,代表主线程中接口数量减少,在从待发送请求中取出新的接口放入主线程,从而实现控制主线程发送数量避免内存溢出创建待发送请求池控制最大并行请求数量指定接口缓存,如数据源,结合请求,响应拦截器进行处理流程图如下<<<顺手说一个:有新的技术大厂在→要人,前端/后端还有测试,一线城市及双一线城市几乎都有坑位,待遇稳定性都还成,感兴趣的可以瞅瞅~三、具体代码实现请求并发控制方案概述这是一个基于请求池(Request Pool)的并发控制方案,用于管理前端应用中的 HTTP 请求。通过双队列机制控制并发数量,避免同时发起过多请求导致的性能问题和浏览器限制。核心特性并发控制:限制同时执行的请求数量(默认 20 个)双队列设计:待执行队列(pendingQueue)+ 执行中队列(runningQueue)请求取消:支持取消单个或全部请求,基于 AbortController缓存支持:可配置的请求结果缓存机制内存优化:请求完成后自动清理引用,防止内存泄漏非阻塞调度:使用 setTimeout(0) 让出主线程,避免阻塞 UI防重复调度:通过 isProcessing 标志位避免重复调度架构设计1. 状态管理const poolState = { pendingQueue: [], // 待执行队列 runningQueue: [], // 执行中队列 cacheStore: new Map(), // 缓存存储 maxConcurrent: 20, // 最大并发数 maxPendingQueue: Infinity, // 待执行队列最大长度 isProcessing: false // 防止重复调度标志位 }; 2、核心机制防重复调度使用 isProcessing 标志位防止多次调用 scheduleExecute() 时重复创建定时器: const scheduleExecute = () => { if (poolState.isProcessing) return; // 已在处理中,直接返回 poolState.isProcessing = true; setTimeout(() => { processQueue(); poolState.isProcessing = false; // 处理完成,重置标志 }, 0); }; 批量处理每次调度时,根据可用槽位批量启动请求:const processQueue = () => { // 计算可用槽位 const slots = poolState.maxConcurrent - poolState.runningQueue.length; const count = Math.min(slots, poolState.pendingQueue.length); // 批量启动 for (let i = 0; i < count; i++) { const task = poolState.pendingQueue.shift(); if (task) { poolState.runningQueue.push(task); executeRequest(task); } } }; API 文档addRequest(config, axiosInstance)添加请求到队列参数:config (Object): axios 请求配置对象axiosInstance (Function): axios 实例返回:Promise: 请求的 Promise 对象示例:import axios from 'axios'; import { addRequest } from '@/utils/requestPool'; const config = { method: 'get', url: '/api/users', params: { page: 1 } }; addRequest(config, axios) .then(response => console.log(response.data)) .catch(error => console.error(error)); setMaxConcurrent(max)设置最大并发数参数:max (Number): 最大并发数示例:import { setMaxConcurrent } from '@/utils/requestPool'; // 设置最大并发数为 10 setMaxConcurrent(10); clearAllRequests()取消所有请求(包括待执行和执行中的请求)返回:Object: 取消的请求数量统计pending (Number): 待执行队列中取消的数量running (Number): 执行中队列中取消的数量示例:import { clearAllRequests } from '@/utils/requestPool'; const count = clearAllRequests(); console.log(`取消了 ${count.pending} 个待执行请求`); console.log(`取消了 ${count.running} 个执行中请求`); getPoolState()获取请求池当前状态(用于调试和监控)返回:Object: 请求池状态信息示例:import { getPoolState } from '@/utils/requestPool'; const state = getPoolState(); console.log('待执行:', state.pendingCount); console.log('执行中:', state.runningCount); console.log('缓存数:', state.cacheCount); getCacheKey(config)生成缓存键(预留功能)参数:config (Object): axios 配置对象,需包含 cacheParams 字段返回:String | null: 缓存键,如果未配置 cacheParams 则返回 nullgetCache(key) / setCache(key, data) / clearCache(key)缓存操作方法(预留功能)使用示例1. 基础集成 - Axios 拦截器在 axios 实例中集成请求池:// src/utils/request.js import axios from 'axios'; import { addRequest, clearAllRequests } from './requestPool'; const service = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 10000 }); // 请求拦截器 service.interceptors.request.use( config => { // 标记使用请求池 config.usePool = true; return config; }, error => Promise.reject(error) ); // 响应拦截器 service.interceptors.response.use( response => response.data, error => { console.error('请求失败:', error); return Promise.reject(error); } ); // 重写 axios 请求方法,使用请求池 const originalRequest = service.request.bind(service); service.request = function(config) { if (config.usePool !== false) { // 使用请求池 return addRequest(config, originalRequest); } // 不使用请求池,直接请求 return originalRequest(config); }; export default service; export { clearAllRequests }; 2. API 调用示例 // src/api/user.js import request from '@/utils/request'; // 获取用户列表 export const getUserList = (params) => { return request({ url: '/api/users', method: 'get', params }); }; // 获取用户详情 export const getUserDetail = (id) => { return request({ url: `/api/users/${id}`, method: 'get' }); }; // 创建用户 export const createUser = (data) => { return request({ url: '/api/users', method: 'post', data }); }; 3. 组件中使用<template> <div> <button @click="loadData">加载数据</button> <button @click="cancelAll">取消所有请求</button> <div>待执行: {{ poolState.pendingCount }}</div> <div>执行中: {{ poolState.runningCount }}</div> </div> </template> <script setup> import { ref, onMounted } from 'vue'; import { getUserList } from '@/api/user'; import { clearAllRequests, getPoolState } from '@/utils/requestPool'; const poolState = ref({ pendingCount: 0, runningCount: 0 }); // 更新请求池状态 const updatePoolState = () => { const state = getPoolState(); poolState.value = state; }; // 加载数据 const loadData = async () => { try { // 同时发起 50 个请求,但只有 20 个会并发执行 const promises = Array.from({ length: 50 }, (_, i) => getUserList({ page: i + 1 }) ); // 定时更新状态 const timer = setInterval(updatePoolState, 100); const results = await Promise.all(promises); clearInterval(timer); console.log('所有请求完成:', results.length); } catch (error) { console.error('请求失败:', error); } }; // 取消所有请求 const cancelAll = () => { const count = clearAllRequests(); console.log(`已取消 ${count.pending + count.running} 个请求`); updatePoolState(); }; onMounted(() => { updatePoolState(); }); </script> 4. 路由切换时取消请求// src/router/index.js import { createRouter, createWebHistory } from 'vue-router'; import { clearAllRequests } from '@/utils/requestPool'; const router = createRouter({ history: createWebHistory(), routes: [ // 路由配置... ] }); // 路由切换前取消所有请求 router.beforeEach((to, from, next) => { if (from.path !== '/') { const count = clearAllRequests(); console.log(`路由切换,取消了 ${count.pending + count.running} 个请求`); } next(); }); export default router; 5. 批量请求示例// 批量加载用户详情 async function loadUserDetails(userIds) { const promises = userIds.map(id => getUserDetail(id)); try { const results = await Promise.all(promises); console.log('加载完成:', results); return results; } catch (error) { console.error('批量加载失败:', error); throw error; } } // 使用示例 const userIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; loadUserDetails(userIds); 6. 动态调整并发数import { setMaxConcurrent, getPoolState } from '@/utils/requestPool'; // 根据网络状况动态调整 function adjustConcurrency() { const connection = navigator.connection; if (connection) { const effectiveType = connection.effectiveType; switch (effectiveType) { case 'slow-2g': case '2g': setMaxConcurrent(5); break; case '3g': setMaxConcurrent(10); break; case '4g': default: setMaxConcurrent(20); break; } console.log('网络类型:', effectiveType); console.log('当前并发数:', getPoolState().maxConcurrent); } } // 监听网络变化 if (navigator.connection) { navigator.connection.addEventListener('change', adjustConcurrency); } 7. 请求优先级(扩展示例)如果需要实现请求优先级,可以扩展 addRequest 方法:// 扩展版本 - 支持优先级 export const addRequestWithPriority = (config, axiosInstance, priority = 0) => { return new Promise((resolve, reject) => { const abortController = new AbortController(); const task = { config: { ...config, signal: abortController.signal }, resolve, reject, axiosInstance, abortController, priority // 添加优先级字段 }; // 根据优先级插入队列 const index = poolState.pendingQueue.findIndex(t => t.priority < priority); if (index === -1) { poolState.pendingQueue.push(task); } else { poolState.pendingQueue.splice(index, 0, task); } scheduleExecute(); }); }; // 使用示例 addRequestWithPriority(config, axios, 10); // 高优先级 addRequestWithPriority(config, axios, 0); // 普通优先级 性能优化要点1. 内存管理请求完成后自动清理任务对象的引用:task.config = null; task.resolve = null; task.reject = null; task.axiosInstance = null; task.abortController = null; 2. 非阻塞调度使用 setTimeout(0) 让出主线程:setTimeout(() => { processQueue(); poolState.isProcessing = false; }, 0); 3. 批量处理一次调度处理多个请求,减少调度次数:const count = Math.min(slots, poolState.pendingQueue.length); for (let i = 0; i < count; i++) { // 批量启动 } 注意事项并发数设置:默认 20 个,可根据实际情况调整请求取消:路由切换或组件卸载时记得取消请求错误处理:已取消的请求不会触发 reject,避免重复处理缓存功能:当前代码中已预留,可根据需要启用浏览器限制:不同浏览器对同域名并发请求有限制(通常 6-8 个),但通过请求池可以更好地控制——转载自:米西米西1
前端必看!接口并发方案
开源硬件平台
上期我们利用FFImageLoad实现了图片流的显示,之前也有一期简单介绍了一下利用SkiaSharp实现绘图。 本期我们来实现一个摇杆的实现。public class DrawAble {     private readonly Rocker view; public DrawAble(Rocker view) {         this.view = view; } private void Draw_Circle(SKSurface surface, SKRect bounds) { float centerX = bounds.MidX; float centerY = bounds.MidY; Midx = centerX; Midy = centerY; // 计算圆的半径(使用ChargingRingDrawable类中的rad属性) float radius = CirCleRad; // 使用SKPaint对象定义圆的样式(颜色、线条宽度等) using (SKPaint paint = new SKPaint()) { paint.Color = SKColors.Blue; paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 20; // 画圆 surface.Canvas.DrawCircle(centerX, centerY, radius, paint); }     } public void Draw(SKSurface surface, SKRect bounds) { surface.Canvas.Clear();         Draw_Circle(surface, bounds);//画圆轮廓     } } 首先定义两个类,一个是画板类,他必须有最基本的Draw函数用来给Sharp实现接口。 其构造函数传入我们的Rocker类,这个类我们在下面定义。 public partial class Rocker : SKCanvasView {         private readonly DrawAble drawable; public Rocker() {             this.EnableTouchEvents = true;// this.drawable = new ChargingRingDrawable(this);         } protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) { this.drawable.Draw(e.Surface, e.Info.Rect); this.InvalidateSurface(); } protected override void OnTouch(SKTouchEventArgs e) {             base.OnTouch(e);         } } } 接着定义一个类,命名为Rocker,这个类抽象自SKCanvasView(SkiaSharp的控件) 定义一个画板,构造的时候传入自身。 我们要保留两个处理函数,一个是OnPaintSurface,我们的控件刷新就会调用这个函数,还有一个是OnTouch函数,这个函数用来处理我们的触摸事件。private void Draw_Circle(SKSurface surface, SKRect bounds) {     float centerX = bounds.MidX;//获得画板中心 float centerY = bounds.MidY;     Midx = centerX;//用一个参数保存画板中心 Midy = centerY; // 计算圆的半径(使用ChargingRingDrawable类中的rad属性) float radius = CirCleRad; // 使用SKPaint对象定义圆的样式(颜色、线条宽度等) using (SKPaint paint = new SKPaint()) { paint.Color = SKColors.Blue; paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 20; // 画圆 surface.Canvas.DrawCircle(centerX, centerY, radius, paint); } } 在DrawAble类中有这样子一个函数,其作用是画一个基本的圆,我设置的大小是400像素。private void Draw_InsertCircle(SKCanvas canvas, SKPoint touchLocation, float radius) { // 控件的中心点 float centerX = Midx; float centerY = Midy; // 计算手的位置与圆的交点 SKPoint intersectionPoint = CalculateIntersectionPoint(centerX, centerY, 300, touchLocation); // 使用SKPaint对象定义圆的样式(颜色、线条宽度等) using (SKPaint paint = new SKPaint()) { paint.Color = SKColors.Red; paint.Style = SKPaintStyle.Fill; // 在交点位置绘制圆 canvas.DrawCircle(intersectionPoint.X, intersectionPoint.Y, radius, paint); LocationPoint = intersectionPoint; } } private SKPoint CalculateIntersectionPoint(float centerX, float centerY, float radius, SKPoint touchLocation) { // 计算手的位置与圆的交点 float dx = touchLocation.X - centerX; float dy = touchLocation.Y - centerY; float distance = (float)Math.Sqrt(dx * dx + dy * dy); // 如果距离超出阈值,将交点移动到圆上最近的点 if (distance > radius) { float scale = radius / distance; float intersectionX = centerX + dx * scale; float intersectionY = centerY + dy * scale; return new SKPoint(intersectionX, intersectionY); } // 如果距离未超出阈值,则返回手的位置作为交点 return touchLocation; } 接着画内部的摇杆内容,我们计算这个圆和控件中心的位置,设置一个阈值,保证我们画的圆在这个阈值之内,如果超过了阈值,就计算手的位置和圆的交点,再进行画圆。 实现这样子的效果。 接着,我们补全Rocker中触摸事件protected override void OnTouch(SKTouchEventArgs e) { base.OnTouch(e); switch (e.ActionType) { case SKTouchAction.Pressed: // 处理按下事件 break; case SKTouchAction.Moved: // 处理移动事件 SKPoint touchLocation = e.Location; drawable.InsertCirclePoint = touchLocation; OnPositionChanged(new SKPoint(drawable.LocationPoint.X-drawable.Midx,drawable.LocationPoint.Y-drawable.Midy)); break; case SKTouchAction.Released: SKPoint InsertCirclePoint = new SKPoint(drawable.Midx,drawable.Midy); drawable.InsertCirclePoint = InsertCirclePoint; // 使得画布无效,触发重绘 InvalidateSurface(); OnPositionChanged(new SKPoint(0,0)); break; case SKTouchAction.Cancelled: // 处理取消事件 break; } // 标记事件已处理 e.Handled = true; } 当移动时,将位置传给DrawAble中,DrawAble会根据手的位置绘制摇杆位置。 并且在放下的时候重新归位。 同时我们定义一个事件,向MainPage中传入位置信息。private void Rocker_PositionChanged(object sender, SKPoint newPosition) {    Label.Text = $"Position: ({newPosition.X}, {newPosition.Y})"; } MainPage中打印我们的位置信息。
.NET MAUI的Android WiFi图传开发(6)——利用SkiaSharp制作一个摇杆
嘉立创PCB
B站demo演示视频:我把传感器塞进网球避震器,测了一下发球速度【项目背景】网球发球训练缺乏即时量化反馈工具。现有方案(Zepp、Babolat Play等)体积大、数据维度有限,无法捕捉发力结构细节。做了一个避震器形态的传感器模块,目标是在不显著改变球拍挥重的前提下,采集发球过程中的关键力学参数。【迭代过程】V1(已废弃):- 直接用蓝牙模组内置MCU做开发,没有独立单片机- 想法是单IMU做完整动作轨迹重建- 实测结果:误差累计太大,加速度二次积分漂移无法在这个成本和体积下解决- 教训:没搞过固件就上蓝牙模组MCU开发,调试手段有限,效率极低V2(当前版本):- 砍掉了"全动作记录"需求,聚焦发球训练——单次重复动作,每次击球间可归零,回避积分漂移问题- 加了独立STM32单片机,开发调试效率大幅提升- 换了高量程陀螺仪——发球动作核心是旋转发力(内旋),陀螺仪数据能覆盖主要需求,不再依赖加速度积分【当前方案概述】MCU:STM32C011F6P6IMU:LSM6DSVTR蓝牙模组:PB-03f供电:软包锂电核心模块重量:5.2g(不含外壳,未做工程优化)算法输出指标:- 拍头速度(发球瞬间)- 掉拍头幅度- 发力速度- 手臂内旋发力占比【当前进展】V2硬件完成并验证- 算法和数据链路跑通- 与手机App的BLE通信稳定- 已完成多次球场实测验证,四项指标实时输出【下阶段目标】做工程样机,小型化、外壳优化、电池选型及充电设计。发工程样机给网球爱好者、教练、运动员测试,吸收反馈迭代产品功能。【期望交流】希望能与做过类似消费电子/穿戴设备的,有工程化经验的朋友交流。我的邮箱:nospoon@qq.com小红书(记录了开发的部分过程):there is no spoon#DIY设计#
DIY网球发球训练数据采集模块,希望能与感兴趣的朋友交流
开源硬件平台
社区数据
今日帖子
-
今日互动量
-
在线人数
-
帖子总量
-
用户总量
-
功能讨论
()
主题
打赏记录
服务时间:周一至周六 9::00-18:00 · 联系地址:中国·深圳(福田区商报路奥林匹克大厦27楼) · 媒体沟通:pr@jlc.com · 集团介绍
移动社区