MPLAB Harmony框架实战:从驱动抽象到复杂嵌入式系统开发

news2026/5/15 19:18:56
1. 项目概述为什么我们需要 Harmony如果你在嵌入式开发领域摸爬滚打超过五年尤其是深度使用过 Microchip 的 PIC32 系列 MCU那你一定对“从零开始搭驱动”这件事深恶痛绝。我还记得十年前为了在 PIC32MX 上跑通一个带 USB 和 TCP/IP 的简单应用我花了整整两周时间翻阅几十份数据手册和应用笔记手动配置寄存器、调试中断优先级、处理内存冲突。那种感觉就像是用一把瑞士军刀去造一辆汽车工具虽多但每一步都充满未知和风险。“Microchip Minutes - MPLAB® Harmony 专辑”这个项目就是针对这种“造轮子”的痛点而生的。它不是一个简单的教程合集而是一套系统性的、基于 Microchip 官方 MPLAB® Harmony 框架的实战经验总结。Harmony 是什么简单说它是 Microchip 为自家 32 位 PIC® 和 SAM 微控制器提供的一套统一的、模块化的软件框架。它的核心价值在于将底层硬件抽象化把 USB、TCP/IP、文件系统、图形界面等复杂的外设驱动和中间件封装成一个个可配置、可复用的“乐高积木”。这个专辑的目标非常明确帮助开发者尤其是从 8/16 位 MCU 过渡到 32 位复杂应用的工程师快速跨越 Harmony 框架的学习曲线将开发重心从“驱动调试”转移到“应用实现”上。它适合那些已经熟悉 C 语言和基本嵌入式概念但面对 Harmony 丰富的配置选项和层次化架构感到无从下手的开发者。通过这个专辑你将不再需要从浩瀚的文档海洋中盲目搜寻而是能获得一条清晰的、由实战经验铺就的路径直达项目成功。2. Harmony 框架核心架构深度解析要玩转 Harmony死记硬背配置步骤是没用的必须理解其设计哲学和架构。这就像开车只知道踩油门和刹车永远成不了老司机你得懂发动机、变速箱和底盘是如何协同工作的。2.1 三层架构驱动、系统服务与应用Harmony 框架最核心的设计是清晰的三层架构每一层都有明确的职责边界这是实现模块化和可移植性的基础。第一层硬件抽象层与驱动这是最底层直接与 MCU 的硬件外设对话。Harmony 的驱动Drivers已经帮你完成了最繁琐的工作根据数据手册配置时钟、初始化寄存器、实现中断服务例程。例如你需要使用 SPI 通信不需要再去查 SCK、SDO、SDI 对应的寄存器位该如何设置只需要在配置工具里选择 SPI2 外设设置主从模式、时钟极性和相位、波特率即可。驱动层提供了标准化的 API如DRV_SPI_Initialize,DRV_SPI_Transfer让你的代码与具体硬件型号解耦。这意味着今天你的代码在 PIC32MZ 上运行明天换到 SAM E70只需要重新配置底层驱动应用层代码几乎不用改动。第二层系统服务与中间件这是 Harmony 的“肌肉”层提供了构建复杂应用所需的核心功能模块。它建立在稳定的驱动层之上包括系统服务如时钟管理、延时、调试信息输出SysLog、任务调度基于 RTOS 或裸机。通信协议栈TCP/IP 网络协议栈包括 DHCP、DNS、HTTP Server/Client、USB 协议栈HID、CDC、MSD 等。文件系统支持 FAT16/FAT32用于 SD 卡或内部 Flash 存储管理。图形库为带显示器的应用提供图形界面支持。这一层的模块通常更复杂但 Harmony 通过配置工具和丰富的示例极大地降低了集成难度。比如你想让设备通过 WiFi 接入网络并作为一个 Web 服务器你不需要去啃 TCP/IP 协议 RFC 文档只需要在图形化配置工具中勾选 “TCP/IP Stack” 和 “HTTP Net Server”并正确关联底层的 MAC 驱动如 MRF24WG WiFi 驱动或 LAN8720 以太网 PHY 驱动即可。第三层应用层这是你大展拳脚的舞台。基于下层提供的稳定 API你可以专注于业务逻辑的实现。应用层通过回调函数、事件驱动或直接调用 API 的方式与下层交互。Harmony 鼓励事件驱动的编程模型这能更好地适应多任务和实时性要求。例如当 TCP/IP 栈收到一个新的 HTTP 客户端连接请求时它会触发一个事件你的应用层代码只需要编写处理这个事件的回调函数即可。注意很多新手容易犯的错误是“跨层调用”例如在应用层直接调用底层驱动的寄存器操作函数。这破坏了架构的封装性会导致代码难以维护和移植。务必严格遵守分层原则只使用当前层及下一层提供的官方 API。2.2 MPLAB® Harmony Configurator 的实战心法MHC 是 Harmony 的“大脑”和“指挥中心”一个基于 Eclipse 的图形化配置工具。它远不止是一个代码生成器更是项目架构的可视化设计器。配置流程的精髓创建项目与选择器件这是所有工作的起点。务必根据项目需求性能、外设、成本精准选择 MCU 型号。一个常见的坑是项目中期发现 UART 串口数量不够或 Flash 空间不足。启用与配置驱动在 “Project Graph” 视图中从右侧工具箱拖拽所需的外设驱动到画布。关键步骤在于配置依赖关系。例如你要用 SPI 驱动一个外部 Flash 芯片如 W25Q128除了配置 SPI 本身还必须正确配置该 SPI 通道所使用的引脚通过 “Pin Settings”以及可能需要的 DMA 通道如果涉及大数据量传输。集成系统服务与中间件拖拽中间件模块如 TCP/IP Stack到画布后必须用“连接线”将其与底层驱动如以太网 MAC 驱动正确连接。MHC 会自动检查依赖关系如果连接错误或缺失会有明显的错误提示。生成代码点击 “Generate Code” 按钮。这一步的神奇之处在于MHC 不仅生成initialization.c、interrupts.c等板级支持文件还会根据你的配置自动生成一个结构清晰的项目源代码骨架其中包含app.c和app.h供你编写应用逻辑。避坑指南MHC 配置的常见“雷区”时钟配置混乱这是导致系统无法启动或外设工作异常的首要原因。务必在 “Clock Diagram” 视图中清晰地规划核心时钟、外设总线时钟的来源和分频比。一个稳妥的方法是先使用 MHC 推荐的默认时钟配置让系统跑起来再根据实际需求微调。引脚冲突未察觉当项目复杂时多个外设可能复用同一个引脚。MHC 的 “Pin Settings” 视图会用颜色高亮冲突。必须在硬件设计阶段就和原理图工程师沟通或在配置时仔细检查避免软件配置与硬件连接不符。生成代码后手动修改源文件这是大忌如果你在 MHC 生成的system_init.c等文件中手动添加了代码下次重新生成代码时这些修改会被覆盖。正确的做法是将自定义的初始化代码写在app.c的APP_Initialize函数中或将自定义驱动代码放在独立的、不会被 MHC 覆盖的文件里。3. 从零到一构建一个 Harmony 基础项目实战理论说得再多不如亲手做一遍。让我们以一个最经典的需求为例“使用 PIC32MZ EF 系列 MCU通过 UART 串口每秒打印一次 ‘Hello Harmony’ 到电脑终端同时让一个 LED 以 0.5Hz 的频率闪烁。”这个项目虽小但涵盖了时钟、GPIO、UART 驱动、系统延时等 Harmony 核心概念。3.1 项目创建与驱动配置详解首先在 MPLAB® X IDE 中选择 “File - New Project”选择 “32-bit MPLAB® Harmony Project”。给项目起名例如HelloHarmony_LED_UART。关键步骤一时钟树配置在 MHC 中切换到 “Clock Diagram” 标签。对于 PIC32MZ EF我们通常使用外部晶振作为时钟源。假设板载一颗 24MHz 的晶振。选择POSC作为系统时钟源。配置 PLL 输入分频、倍频因子和后分频以得到期望的系统时钟。例如目标系统时钟为 200MHz。计算过程24MHz / 2 (输入分频) 12MHz12MHz * 50 (倍频) 600MHz600MHz / 3 (后分频) 200MHz。这个计算过程需要在配置时手动输入或选择。检查PB2外设总线时钟通常为系统时钟的一半即 100MHz这是许多外设如 UART的时钟源。确保 UART 所需的波特率可以被此外设时钟正确分频。关键步骤二外设驱动配置回到 “Project Graph” 视图。配置 LED 对应的 GPIO从工具箱找到 “GPIO Driver”拖入画布。在右侧属性窗口中将其重命名为LED。在 “Pin Settings” 中选择具体的引脚例如RE0方向设置为 “Output”初始输出电平设置为 “Low”。配置 UART 驱动拖入 “UART Driver”。重命名为DEBUG_UART。在 “Pin Settings” 中分配 TX 和 RX 引脚例如RF12为 TXRF13为 RX。在驱动属性中设置波特率如 115200、数据位、停止位、校验位。这里有一个重要技巧在 “Driver Mode” 中对于简单的轮询发送可以选择 “Non-Blocking”但如果后续需要接收数据强烈建议从开始就选择 “Asynchronous” 异步模式并启用中断这为项目扩展留出了空间。3.2 应用逻辑编写与系统集成生成代码后打开app.c文件。Harmony 已经为我们生成了基本的应用骨架包括APP_Initialize和APP_Tasks函数。// 在 app.c 的全局变量区域附近定义必要的变量 static uint32_t ledToggleTime 0; static uint32_t uartPrintTime 0; void APP_Tasks ( void ) { // 检查系统定时器这是一个由 Harmony 系统服务维护的毫秒级计数器 uint32_t currentTime SYS_TIME_MillisecondCountGet(); // 任务1: 控制 LED 闪烁 (500ms 周期) if ((currentTime - ledToggleTime) 500) { ledToggleTime currentTime; // 使用 Harmony GPIO API 翻转 LED 状态 GPIO_PinToggle(LED_CHANNEL); // LED_CHANNEL 是在 MHC 中配置时定义的宏 } // 任务2: 每秒通过 UART 发送一次数据 if ((currentTime - uartPrintTime) 1000) { uartPrintTime currentTime; // 使用 Harmony UART API 发送字符串 DRV_USART_WriteBuffer(DEBUG_UART_HANDLE, (void*)Hello Harmony\r\n, strlen(Hello Harmony\r\n)); } // 保持系统运行处理底层驱动和中间件的后台任务如 UART 发送队列 SYS_Tasks(); }代码解析与注意事项SYS_TIME_MillisecondCountGet()这是 Harmony 系统服务提供的一个轻量级软件定时器比硬件定时器更节省资源适合这种非精确的延时任务。GPIO_PinToggle这是一个宏直接操作 GPIO 寄存器效率极高。它的定义来源于 MHC 根据你的配置自动生成的头文件。DRV_USART_WriteBuffer这是 UART 驱动的标准 API。DEBUG_UART_HANDLE是驱动实例句柄也由 MHC 生成。这里使用的是非阻塞写入函数调用后会立即返回数据会在后台发送。如果发送缓冲区满该函数会返回错误实际项目中需要添加错误处理。SYS_Tasks()这个调用至关重要它负责执行所有底层驱动和中间件的状态机任务。你必须在你应用的主任务循环中定期调用它否则像 UART 发送、TCP/IP 协议处理等后台操作都将停滞。4. 进阶实战集成 TCP/IP 与 USB 复合设备单一外设的项目只是热身。Harmony 的真正威力体现在多外设、多任务的复杂系统集成中。我们升级需求在之前项目基础上增加以太网功能使设备能响应 Ping 请求并作为一个 USB 复合设备同时是虚拟串口 CDC 和 U 盘 MSD与电脑交互。4.1 TCP/IP 协议栈的集成与配置这是一个从“裸机”思维转向“协议栈”思维的关键步骤。添加 TCP/IP 栈和以太网驱动在 MHC 的 “Project Graph” 中拖入 “TCP/IP Stack” 和对应的 “ETH MAC Driver”例如对于 LAN8740 PHY 芯片使用 “GMAC” 驱动。建立连接用连接线将 “TCP/IP Stack” 的 “MAC” 接口与 “ETH MAC Driver” 的 “MAC” 接口相连。MHC 会自动添加必要的依赖如 “TCP/IP Commands” 模块用于调试命令。配置网络参数在 “TCP/IP Stack” 的属性中配置 IP 地址获取方式静态 IP 或 DHCP。对于测试通常先设置静态 IP如192.168.1.100。同时启用 “ICMP” 模块以支持 Ping 功能。生成代码与适配生成代码后你需要在app.c的APP_Initialize中调用TCPIP_STACK_Init来初始化协议栈。协议栈的日常维护如处理 ARP 请求、维护 TCP 连接已经在SYS_Tasks()中自动处理。此时编译下载程序你的设备就应该能响应来自同一局域网的 Ping 命令了。实操心得网络不通的排查顺序第一检查硬件连接和 PHY 芯片的指示灯第二在 MHC 中确认 MAC 驱动引脚配置与原理图一致第三在代码中打印 MAC 地址确认其唯一性第四使用 Wireshark 抓包查看设备是否发出了 ARP 请求或响应。4.2 USB 复合设备CDCMSD的实现USB 开发历来是嵌入式中的难点Harmony 的 USB 协议栈将其标准化。配置 USB 协议栈拖入 “USB Device Stack”。在属性中选择 “Device Mode” 为 “CDC MSD Composite Device”。配置 CDC 功能这会自动添加一个 “USB Device CDC” 实例。你可以将其重命名为USB_CDC_DEBUG并将其 “Read/Write Queue Size” 适当调大以提升数据传输性能。配置 MSD 功能这会自动添加一个 “USB Device MSD” 实例。你需要将其与一个存储介质驱动关联。例如如果使用 SPI 接口的 Flash 芯片作为 U 盘存储你需要先配置好 “SPI Flash Driver” 和 “SPI Driver”然后在 MSD 实例的属性中选择 “Media Driver” 为那个 SPI Flash 驱动实例。处理 USB 事件USB 是典型的事件驱动模型。你需要在app.c中编写 USB 事件处理回调函数。例如当 USB 连接建立或断开时系统会触发USB_DEVICE_EVENT_CONFIGURED或USB_DEVICE_EVENT_DECONFIGURED事件。你可以在回调函数中设置标志位以通知应用层 USB 的状态变化。数据通路连接一个巧妙的做法是将 USB CDC 虚拟串口作为系统的另一个调试输出通道。你可以在应用层实现一个简单的日志函数根据条件选择是通过 UART 还是 USB CDC 发送数据。// 示例一个简单的双通道打印函数 void my_printf(const char *format, ...) { char buffer[128]; va_list args; va_start(args, format); vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); // 通过硬件 UART 发送 DRV_USART_WriteBuffer(DEBUG_UART_HANDLE, buffer, strlen(buffer)); // 如果 USB CDC 已配置也通过它发送 if (usbCdcIsConfigured) { USB_DEVICE_CDC_Write(USB_CDC_DEBUG_HANDLE, cdcWriteHandle, buffer, strlen(buffer), USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE); } }5. 调试技巧与常见问题排查实录即使配置再仔细调试仍是嵌入式开发的主旋律。基于 Harmony 的项目调试有其特定的方法和常见陷阱。5.1 高效调试手段SysLog 与调试终端在项目初期不要急于连接仿真器单步调试优先建立可靠的日志输出系统。启用 SysLog 服务在 MHC 中添加 “System Service - SysLog” 模块。它提供不同级别的日志输出DEBUG, INFO, ERROR 等。你可以在代码中通过SYS_LOG_DEBUG、SYS_LOG_ERROR等宏打印信息。SysLog 的优势在于可以方便地重定向输出目标UART, USB CDC, 内存缓冲区等并且可以在运行时通过编译开关全局关闭调试信息不影响性能。利用 MPLAB® Data Visualizer这是 Microchip 提供的一个强大工具。当你的调试信息通过 UART 或 USB CDC 输出时Data Visualizer 可以作为一个图形化终端接收并显示。更重要的是它支持绘制实时波形图。你可以将程序中的某些变量如传感器数据、任务执行时间以特定格式输出Data Visualizer 能自动解析并绘图非常直观。硬件调试器如 ICD4的进阶用法除了设置断点更要善用“实时变量查看”和“跟踪”功能。Harmony 的许多状态如驱动状态机、协议栈内部变量是以结构体形式存在的在调试窗口中添加这些变量的监视可以动态观察系统运行状态。5.2 常见问题排查速查表下表是我在多个 Harmony 项目中遇到的典型问题及解决思路堪称“血泪经验”的总结问题现象可能原因排查步骤与解决方案系统无法启动卡在启动代码1. 时钟配置错误最常见2. 堆栈空间不足3. 中断向量表地址错误1. 检查 MHC 中 “Clock Diagram” 配置确认锁相环锁定。用示波器测量主时钟输出引脚。2. 在 MPLAB® X 的 “Project Properties - XC32 Linker” 中增加堆栈和堆的大小。3. 确认链接器脚本是否正确特别是对于有 Bootloader 的项目。外设如 UART不工作1. 引脚配置冲突或错误2. 外设时钟未使能或频率不对3. 驱动初始化顺序错误1. 在 MHC “Pin Settings” 中双重检查引脚分配并用万用表测量引脚电平。2. 在 “Clock Diagram” 中检查该外设总线时钟是否使能计算波特率分频比是否超出范围。3. 确保在SYS_Initialize中外设驱动的初始化被正确调用。查看生成的initialization.c文件。TCP/IP 网络 Ping 不通1. 以太网 PHY 芯片未正确复位或初始化2. MAC 地址无效全0或全F3. IP 地址冲突或子网掩码错误4. 防火墙或交换机阻止1. 检查 PHY 的复位引脚时序在代码中确保复位完成后再初始化 MAC 驱动。2. 在代码中打印或通过调试器查看 MAC 地址确保其唯一性。3. 确认设备 IP 与电脑 IP 在同一网段且子网掩码正确。4. 尝试关闭电脑防火墙或将设备直连电脑。USB 枚举失败1. USB 引脚DP/DM接错2. USB 时钟源精度不够需 0.25% 以内3. 描述符配置错误4. 电源供电不足1. 核对原理图DP 应接上拉电阻。2. 对于全速 USB时钟精度要求很高确保使用高精度晶振或时钟源。3. 使用 USB 分析仪如 Beagle USB抓取枚举过程数据包对比描述符。4. 测量 USB 口的 5V 电压是否稳定设备功耗是否过大。程序运行一段时间后死机1. 堆栈溢出2. 中断嵌套或优先级配置不当3. 内存泄漏频繁动态分配4. 看门狗未喂狗1. 在调试器中查看堆栈指针是否接近边界。2. 检查 Harmony 配置的中断优先级避免在低优先级中断中阻塞过久。3. 尽量避免在嵌入式实时系统中使用malloc/free使用静态或池分配。4. 如果启用了看门狗确保在应用主循环或定时中断中定期清空。5.3 性能优化与内存管理当项目功能越来越复杂就需要关注性能和资源。优化编译选项在 MPLAB® X 的编译器选项中选择 “-O2” 或 “-Os” 优化等级以获得更小或更快的代码。对于速度关键的函数可以使用__attribute__((optimize(“O3”)))进行局部优化。合理使用 DMA对于 UART、SPI、I2C 等外设的大数据量传输务必在 MHC 中启用 DMA。这能将 CPU 从繁重的数据搬运工作中解放出来显著提升系统响应能力和整体吞吐量。配置 DMA 时注意设置正确的数据宽度、地址递增模式和中断回调。精细化管理内存Harmony 的许多模块如 TCP/IP 栈、USB 栈在初始化时会动态分配内存池。你需要在 MHC 中仔细配置这些池的大小。分配过大浪费 RAM过小则会导致运行时分配失败。一个实用的方法是在开发初期设置较大的值待功能稳定后通过调试信息观察实际使用峰值再逐步调整至最优值。任务划分与SYS_Tasks()调用在裸机环境下APP_Tasks函数是你的主循环。如果其中有耗时很长的操作如复杂的计算、等待某个慢速外设会阻塞SYS_Tasks()的调用导致整个系统“卡住”。解决方案是将长任务拆分成多个状态用状态机的方式在多次循环中执行完或者如果条件允许引入一个轻量级的 RTOS如 FreeRTOSHarmony 也支持集成将不同的任务放在不同的 RTOS 线程中管理。走过从点亮一个 LED 到构建一个同时具备网络、USB、文件系统的复杂节点的完整路径我最大的体会是MPLAB® Harmony 与其说是一个软件库不如说是一套经过验证的嵌入式软件工程方法论。它强迫你思考架构、模块化和接口这远比写出几行能动的代码重要得多。初期学习配置工具和框架概念确实需要投入时间但一旦掌握其带来的开发效率提升和代码质量的保证是巨大的。当你不再需要为底层驱动的稳定性熬夜调试当你能够像搭积木一样快速组合出产品原型时你就会明白这份投入是多么值得。最后一个小建议多跑官方例程但不要只停留在“跑通”要尝试去修改它、打破它再修复它这个过程才是理解 Harmony 精髓的最快途径。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2615821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…