MultiSerial:单UART多通道串行通信复用库

news2026/4/9 0:14:26
1. 项目概述MultiSerial 是一个面向嵌入式系统的多字节串行通信抽象库其核心设计目标是在单个物理串口UART/USART上安全、可靠地复用多个逻辑通信通道实现“一串口多路数据流”的工程需求。该库不依赖特定硬件平台或RTOS可运行于裸机Bare-Metal环境亦可无缝集成 FreeRTOS、Zephyr 等实时操作系统。其命名“MultiSerial”直指本质Multi表示多路复用能力Serial明确作用域为串行通信层而非应用层协议如 Modbus、CANopen。与常见的“多串口管理库”如 STM32 HAL 中的HAL_UART_Init多实例调用有本质区别MultiSerial 并非管理多个 UART 外设而是在单一 UART 外设的收发缓冲区之上构建一套轻量级的帧分隔、通道标识与数据路由机制。典型应用场景包括传感器融合节点同一 UART 连接温湿度传感器通道0、气压计通道1、加速度计通道2主控按需轮询各通道调试与日志双模共用将 UART 同时用于printf调试输出通道0和固件升级指令接收通道1避免硬件资源冲突低功耗设备唤醒通信MCU 深度睡眠时仅 UART 接收中断唤醒通过预定义通道ID快速识别唤醒源如红外遥控器ID3蓝牙模块ID5工业现场总线桥接作为 RS-485 总线上的从站响应不同主站地址映射为通道ID的读写请求。该库的设计哲学是“最小侵入、最大可控”不接管 UART 的底层初始化与中断服务不强制使用动态内存分配所有数据结构均支持静态声明所有关键操作如发送、接收、超时处理均由用户显式触发杜绝隐式调度与不可预测延迟完全符合 IEC 61508 SIL2 级别功能安全对确定性的要求。2. 核心架构与数据流模型2.1 分层架构设计MultiSerial 采用清晰的三层架构严格分离关注点层级名称职责用户可见性L0物理驱动层Physical DriverUART 初始化、寄存器配置、中断使能、HAL_UART_Receive_IT/HAL_UART_Transmit_IT调用✅ 用户必须实现L1多路复用引擎Multiplexing Engine帧同步、通道ID解析、缓冲区管理、CRC校验、超时检测✅ 提供完整APIL2应用接口层Application Interface通道注册、数据收发、事件回调、状态查询✅ 主要编程入口此分层确保了库的可移植性L0 层适配不同MCUSTM32F4/F7/H7、GD32、NXP Kinetis仅需重写 5~10 行驱动代码L1/L2 层源码完全通用。2.2 数据帧格式与通道标识机制MultiSerial 定义了一种紧凑、鲁棒的二进制帧格式摒弃 ASCII 协议如$GPGGA的解析开销与容错缺陷。标准帧结构如下单位字节字段长度值域说明SOH(Start of Header)10x01帧起始标记硬编码防误触发Channel ID10x00~0xFF逻辑通道标识符0x00保留为广播通道Payload Length10x00~0xFE有效载荷字节数不含CRC0xFF表示长度字段扩展PayloadN任意用户数据长度由上字段指定CRC-810x00~0xFFCRC8-ITU校验多项式x^8 x^2 x 1覆盖Channel ID至Payload全部字节关键设计考量SOH 强制校验接收端必须先检测0x01才启动帧解析避免因线路噪声导致的假同步Channel ID 置前在解析Payload Length前即获知目标通道可立即路由至对应缓冲区降低延迟CRC-8 覆盖范围不包含 SOH因其为固定值校验无意义包含 Channel ID 确保通道路由正确性长度字段限制0xFE上限254字节平衡单帧吞吐与内存占用超长数据需分片传输。2.3 缓冲区管理策略MultiSerial 采用双缓冲区Double Buffering 循环队列Circular Queue混合模型兼顾实时性与内存效率接收侧RX每个注册通道独占一个ms_rx_buffer_t结构体内含typedef struct { uint8_t *buffer; // 用户提供的RAM缓冲区首地址 uint16_t size; // 缓冲区总字节数建议 ≥256 volatile uint16_t head; // 下一个待写入位置由ISR更新 volatile uint16_t tail; // 下一个待读取位置由应用线程更新 uint8_t channel_id; // 关联通道ID uint8_t overflow_flag; // 溢出标志置位后需手动清零 } ms_rx_buffer_t;ISR 在收到完整帧后将Payload数据原子写入对应通道的缓冲区head递增应用层调用ms_receive()时从tail读取并递增。head tail表示空(head 1) % size tail表示满。发送侧TX全局共享一个ms_tx_buffer_t结构类似 RX 缓冲区但head由应用线程更新tail由HAL_UART_TxCpltCallback回调更新。发送函数ms_transmit()仅将数据拷贝至 TX 缓冲区并触发HAL_UART_Transmit_IT()绝不阻塞。此设计确保✅ ISR 执行时间恒定O(1)无动态内存分配✅ 应用线程与 ISR 间无锁访问仅操作独立变量✅ 溢出可检测、可恢复overflow_flag提供明确错误信号。3. API 接口详解与使用范式3.1 初始化与配置 APIms_init()void ms_init(const ms_config_t *config);参数config指向用户配置结构体关键字段字段类型必填说明uart_handleUART_HandleTypeDef*✅HAL UART 句柄已初始化rx_buffersms_rx_buffer_t*✅RX 缓冲区数组首地址rx_buffer_countuint8_t✅RX 缓冲区数量即支持的最大通道数tx_bufferms_tx_buffer_t*✅TX 缓冲区指针frame_timeout_msuint16_t⚠️帧超时毫秒数默认 100ms防粘包行为注册 UART 接收中断回调HAL_UART_RxCpltCallback初始化所有缓冲区指针与计数器不启动 UART 接收需用户显式调用HAL_UART_Receive_IT()。ms_register_channel()ms_status_t ms_register_channel(uint8_t channel_id, ms_rx_buffer_t *rx_buf);参数channel_id0~255rx_buf指向已分配的ms_rx_buffer_t实例返回值MS_OK成功MS_ERR_INVALID_CHANNELID 冲突MS_ERR_BUFFER_NULL缓冲区为空约束同一channel_id不可重复注册rx_buf-buffer必须为有效 RAM 地址且size 256。3.2 数据收发核心 APIms_transmit()ms_status_t ms_transmit(uint8_t channel_id, const uint8_t *data, uint16_t len);参数channel_id目标通道data待发数据首地址len字节数≤254行为构建帧头SOH Channel ID Len计算 CRC-8 并追加将完整帧拷贝至 TX 缓冲区若 UART 空闲触发HAL_UART_Transmit_IT()若 TX 缓冲区满返回MS_ERR_TX_BUFFER_FULL。注意len为纯载荷长度不含帧头/CRC库自动处理帧封装。ms_receive()int16_t ms_receive(uint8_t channel_id, uint8_t *data, uint16_t max_len);参数channel_id源通道data接收缓冲区max_len最大接收字节数返回值0实际接收字节数0对应通道缓冲区为空-1channel_id未注册-2data或max_len无效。关键特性非阻塞立即返回应用层需轮询或结合事件通知使用。3.3 状态查询与事件 APIms_get_rx_status()ms_rx_status_t ms_get_rx_status(uint8_t channel_id);返回结构体typedef struct { uint16_t available; // 当前可读字节数 uint16_t capacity; // 缓冲区总容量 uint8_t overflow; // 溢出标志1发生过溢出 uint8_t frame_error; // 帧校验失败次数自上次查询起 } ms_rx_status_t;ms_set_callback()void ms_set_callback(ms_callback_t callback);参数callback为函数指针typedef void (*ms_callback_t)(uint8_t channel_id, ms_event_t event);事件类型MS_EVENT_FRAME_RECEIVED新帧到达MS_EVENT_TX_COMPLETE发送完成MS_EVENT_RX_OVERFLOW接收溢出用途替代轮询实现事件驱动编程。例如void my_callback(uint8_t ch, ms_event_t ev) { if (ev MS_EVENT_FRAME_RECEIVED ch SENSOR_CH) { // 触发传感器数据处理任务 xTaskNotifyGive(sensor_task_handle); } }4. 典型工程实践与代码示例4.1 STM32 HAL 裸机环境集成以 STM32F407VG 为例步骤1硬件初始化用户代码// UART 初始化使用 CubeMX 生成或手写 UART_HandleTypeDef huart1; void MX_USART1_UART_Init(void) { huart1.Instance USART1; huart1.Init.BaudRate 115200; huart1.Init.WordLength UART_WORDLENGTH_8B; huart1.Init.StopBits UART_STOPBITS_1; huart1.Init.Parity UART_PARITY_NONE; huart1.Init.Mode UART_MODE_TX_RX; HAL_UART_Init(huart1); // 启动接收中断MultiSerial 依赖此 uint8_t dummy; HAL_UART_Receive_IT(huart1, dummy, 1); } // MultiSerial 配置 #define MAX_CHANNELS 4 ms_rx_buffer_t rx_buffers[MAX_CHANNELS]; uint8_t rx_buf_mem[MAX_CHANNELS][256]; // 每通道256字节RAM ms_tx_buffer_t tx_buffer; uint8_t tx_buf_mem[512]; // TX全局缓冲区 void multi_serial_setup(void) { // 初始化各RX缓冲区 for (int i 0; i MAX_CHANNELS; i) { rx_buffers[i].buffer rx_buf_mem[i]; rx_buffers[i].size sizeof(rx_buf_mem[i]); rx_buffers[i].channel_id i; rx_buffers[i].overflow_flag 0; } tx_buffer.buffer tx_buf_mem; tx_buffer.size sizeof(tx_buf_mem); ms_config_t config { .uart_handle huart1, .rx_buffers rx_buffers, .rx_buffer_count MAX_CHANNELS, .tx_buffer tx_buffer, .frame_timeout_ms 50 }; ms_init(config); // 注册通道 ms_register_channel(0, rx_buffers[0]); // 调试通道 ms_register_channel(1, rx_buffers[1]); // 传感器通道 ms_register_channel(2, rx_buffers[2]); // 升级通道 }步骤2UART 中断回调关键必须重定向// 重写 HAL 库的弱定义函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart huart1) { uint8_t byte; HAL_UART_Receive_IT(huart, byte, 1); // 继续接收下1字节 ms_process_byte(byte); // 将字节送入MultiSerial引擎 } }步骤3主循环中处理数据int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); multi_serial_setup(); while (1) { // 处理通道0调试的接收数据 if (ms_get_rx_status(0).available 0) { uint8_t debug_buf[64]; int16_t len ms_receive(0, debug_buf, sizeof(debug_buf)-1); if (len 0) { debug_buf[len] \0; printf(DEBUG: %s\r\n, debug_buf); // 或通过其他方式输出 } } // 向通道1传感器发送查询命令 static uint8_t query_cmd[] {0x01, 0x02}; // 读取寄存器0x02 if (HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin)) { ms_transmit(1, query_cmd, sizeof(query_cmd)); } HAL_Delay(10); } }4.2 FreeRTOS 环境下的任务化集成在 RTOS 中推荐将 MultiSerial 的收发逻辑封装为独立任务提升系统响应性// 创建专用接收任务 void serial_rx_task(void *pvParameters) { const TickType_t xDelay 1 / portTICK_PERIOD_MS; // 1ms周期 while (1) { // 检查所有注册通道是否有新数据 for (uint8_t ch 0; ch MAX_CHANNELS; ch) { if (ms_get_rx_status(ch).available 0) { // 动态分配足够空间FreeRTOS heap uint8_t *buf pvPortMalloc(ms_get_rx_status(ch).available); if (buf) { int16_t len ms_receive(ch, buf, ms_get_rx_status(ch).available); if (len 0) { // 发送至对应处理队列 switch (ch) { case 0: xQueueSend(debug_queue, buf, 0); break; case 1: xQueueSend(sensor_queue, buf, 0); break; } } else { vPortFree(buf); } } } } vTaskDelay(xDelay); } } // 创建发送任务可选用于批量发送 void serial_tx_task(void *pvParameters) { uint8_t tx_data[256]; while (1) { if (xQueueReceive(tx_command_queue, tx_data, portMAX_DELAY) pdTRUE) { // 解析tx_data中的channel_id和payload uint8_t ch_id tx_data[0]; uint16_t len tx_data[1]; ms_transmit(ch_id, tx_data[2], len); } } }5. 关键参数配置与性能调优指南5.1 缓冲区尺寸选择原则缓冲区类型推荐最小尺寸选择依据工程示例单通道 RX 缓冲区256字节覆盖 2~3 个最大帧254字节 payload 帧头/CRC温湿度传感器每秒上报1次每次64字节 → 256字节可缓存4帧全局 TX 缓冲区512字节支持并发发送多个通道数据避免发送阻塞同时向3个设备发送命令各64字节 1个大文件分片254字节→ 512字节安全余量帧超时 (frame_timeout_ms)50ms略大于最大帧传输时间115200bps下254字节约22ms设置50ms可有效区分帧间隔与线路故障警告RX 缓冲区过小将导致overflow_flag频繁置位丢失数据过大则浪费宝贵 RAM尤其在 Cortex-M0 设备上。5.2 中断优先级与实时性保障MultiSerial 对 UART 中断响应有严格要求中断优先级必须高于所有应用任务在 FreeRTOS 中configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY需设置为高优先级ISR 内严禁调用任何可能阻塞或调度的 HAL 函数如HAL_Delay,printfms_process_byte()执行时间必须恒定实测 ≤ 1.2μs 168MHz Cortex-M4确保在 115200bps 下不会丢字节最小位时间 ≈ 8.7μs。验证方法在HAL_UART_RxCpltCallback中置高 GPIOms_process_byte()结束时拉低用示波器测量脉宽。5.3 CRC-8 校验优化实现库提供两种 CRC-8 计算模式用户可按需选择查表法默认预计算 256 字节 CRC 表ms_calculate_crc8()时间复杂度 O(n)适合高速场景。static const uint8_t crc8_table[256] { 0x00, 0x07, 0x0E, 0x09, /* ... 256 entries ... */ }; uint8_t ms_calculate_crc8(const uint8_t *data, uint16_t len) { uint8_t crc 0; while (len--) { crc crc8_table[crc ^ *data]; } return crc; }位运算法节省ROM无查表内存开销但计算时间略长O(8n)适用于 ROM 紧张的 MCU如 STM32F0。6. 故障诊断与常见问题解决6.1 接收数据乱码/丢帧排查清单现象可能原因验证与解决方法完全无数据接收UART 接收中断未启用检查HAL_UART_Receive_IT()是否被调用用示波器确认 RX 引脚有信号接收数据长度恒为0ms_process_byte()未被调用在HAL_UART_RxCpltCallback中添加 LED 闪烁确认中断触发频繁RX_OVERFLOWRX 缓冲区过小 或 应用层读取太慢调用ms_get_rx_status(ch)检查available与capacity比值增加HAL_Delay()或改用任务处理CRC 校验失败率高线路干扰 或 波特率偏差用逻辑分析仪捕获原始波形检查起始位/停止位宽度校准 MCU 时钟源6.2 发送失败MS_ERR_TX_BUFFER_FULL应对策略此错误表明 TX 缓冲区已满根本原因是UART 发送速度跟不上应用层提交数据的速度。解决方案短期缓解在ms_transmit()返回错误后执行HAL_Delay(1)让 UART 发送部分数据长期优化提升 UART 波特率如从 115200 → 921600增大tx_buffer.size如从 512 → 1024在发送任务中加入流量控制当ms_get_tx_status().available 128时暂停向 TX 队列投递新数据。6.3 多通道数据混淆A通道数据出现在B通道缓冲区此为严重逻辑错误唯一可能原因是Channel ID字段在帧中被意外修改。排查步骤使用逻辑分析仪捕获原始 UART 波形导出十六进制数据流定位SOH (0x01)后的第一个字节确认其值是否为预期channel_id若该字节异常检查发送端ms_transmit()调用时传入的channel_id参数是否正确若发送端正确而接收端错误检查ms_process_byte()是否被其他中断打断需确认其为最高优先级。终极验证在ms_process_byte()开头添加断言assert(byte 0x01 || state WAITING_FOR_CHANNEL_ID);捕获非法字节。7. 与主流嵌入式生态的集成能力7.1 CMSIS-RTOS v2 兼容性MultiSerial 完全兼容 CMSIS-RTOS v2ARM Mbed OS、Keil RTX5无需修改源码。只需在ms_config_t中提供osMutexId_t类型的互斥锁句柄用于保护共享 TX 缓冲区库内部自动调用osMutexAcquire()/osMutexRelease()。7.2 Zephyr RTOS 集成示例在 Zephyr 中利用其k_msgq替代裸机缓冲区// 定义消息队列 K_MSGQ_DEFINE(sensor_msgq, sizeof(struct sensor_frame), 10, 4); // 在 MultiSerial 回调中投递消息 void zephyr_callback(uint8_t ch, ms_event_t ev) { if (ev MS_EVENT_FRAME_RECEIVED ch SENSOR_CH) { struct sensor_frame frame; frame.len ms_receive(ch, frame.data, sizeof(frame.data)); k_msgq_put(sensor_msgq, frame, K_NO_WAIT); } }7.3 与 LVGL 图形库协同在带显示屏的设备中MultiSerial 可作为 LVGL 的输入事件源// 将通道2触摸屏控制器数据映射为 LVGL 输入 void lvgl_indev_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { static uint8_t touch_buf[8]; int16_t len ms_receive(2, touch_buf, sizeof(touch_buf)); if (len 8) { >

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2497657.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…