当前位置: 首页 > news >正文

营销型网站 策划运营网站免认证域名

营销型网站 策划运营网站,免认证域名,网站套餐方案,备案网址柔性数组柔性数组是 C 语言(C99 标准及之后)中的一个特性,指结构体的最后一个成员是一个未知大小的数组,用于在结构体中动态分配连续的内存空间,以高效存储变长数据。它有三个关键点:①结构体最后一个成员是…

柔性数组

柔性数组是 C 语言(C99 标准及之后)中的一个特性,指结构体的最后一个成员是一个未知大小的数组,用于在结构体中动态分配连续的内存空间,以高效存储变长数据。

它有三个关键点:①结构体最后一个成员是大小未知的数组;

②结构体内必须包含其他成员;

③柔性数组不占结构体用空间本身的内存;

④实际使用时需要动态分配内存。

队列

在嵌入式开发中,队列(Queue) 是一种核心的数据结构,遵循 “先进先出(FIFO,First-In-First-Out)” 原则,主要用于解决任务间通信、数据缓冲、时序解耦等关键问题。由于嵌入式系统通常存在多任务(如 RTOS 环境)、资源受限、实时性要求高的特点,队列的作用尤为突出,具体可从以下 6 个核心场景展开:

1. 多任务 / 中断间的安全通信

嵌入式系统(尤其是带 RTOS 的系统,如 FreeRTOS、RT-Thread)中,任务与任务、任务与中断服务函数(ISR) 之间无法直接传递数据(易导致数据竞争、内存溢出),而队列是实现 “线程安全通信” 的标准方案。

  • 任务间通信:例如 “传感器采集任务” 采集到温湿度数据后,无需直接调用 “数据处理任务”,只需将数据放入队列,处理任务从队列中读取数据即可。这种方式避免了任务间的直接耦合,符合 RTOS 的 “任务解耦” 设计原则。

  • 中断与任务通信:中断服务函数(ISR)的执行时间必须极短(避免阻塞其他中断),因此 ISR 不能直接处理复杂数据(如解析串口数据、处理传感器协议)。此时 ISR 可将 “待处理数据” 快速放入队列,再由后台任务从队列中取出并处理(RTOS 通常提供xQueueSendFromISR等专用接口,确保中断上下文的安全性)。

示例:串口接收中断收到 1 字节数据后,立即将数据放入 “串口接收队列”,后台 “串口数据解析任务” 循环从队列中读取数据,拼接成完整的协议帧后再处理。

2. 数据缓冲与流量削峰

嵌入式系统中,数据产生速度与处理速度往往不匹配(如高速传感器、串口 / USB 等外设的数据流),若直接传递数据会导致 “数据丢失” 或 “处理任务过载”,队列可作为 “缓冲池” 平衡两者速度差。

  • 外设数据缓冲:例如 SPI 接口的加速度传感器每秒产生 1000 组数据(每组 4 字节),而 MCU 的 “数据存储任务” 因需写入 Flash,每秒仅能处理 200 组数据。此时用队列缓存传感器数据,可避免数据因处理不及时而丢失(队列深度需根据速度差设计,如设为 800,防止缓冲溢出)。

  • 突发流量处理:当外设(如以太网、CAN 总线)突发发送大量数据时,队列可临时 “囤积” 数据,让处理任务按自身节奏逐步处理,避免系统因瞬时高负载而崩溃(即 “削峰” 作用)。

3. 任务同步与时序解耦

嵌入式系统中,多个任务的执行时序可能存在依赖(如 “初始化任务” 完成后,“业务任务” 才能启动),或需避免 “快任务等待慢任务” 的低效场景,队列可实现灵活的任务同步。

  • 信号同步:队列可传递 “空数据”(仅作为同步信号),例如 “按键扫描任务” 检测到按键按下后,向队列发送一个 “触发信号”,“LED 控制任务” 从队列读取到信号后,执行 LED 闪烁操作(无需传递具体数据,仅需同步事件)。

  • 时序解耦:例如 “ADC 采样任务” 需每 10ms 采样一次,而 “数据上传任务” 需每 1 秒上传一次采样结果。若两者直接耦合,采样任务需等待上传任务完成,会破坏 10ms 的采样周期;用队列缓存每次采样结果,上传任务每秒从队列中读取 100 个数据批量上传,可完全解耦两者的时序。

4. 资源共享与冲突避免

嵌入式系统中的共享资源(如串口、Flash、LCD)若被多个任务同时访问,会导致 “资源竞争”(如串口数据错乱、Flash 写入错误)。队列可作为 “资源请求队列”,实现资源的有序分配。

示例:系统中有 “日志打印任务”“参数上传任务” 两个任务需使用串口。设计一个 “串口请求队列”,两个任务需使用串口时,将 “数据 + 操作类型” 放入队列;再创建一个 “串口管理任务”,独占串口资源,循环从队列中读取请求,按顺序处理(先处理日志打印,再处理参数上传),彻底避免资源冲突。

5. 中断服务函数的轻量化处理

中断服务函数(ISR)的核心要求是 “快进快出”,若在 ISR 中执行复杂逻辑(如数据解析、CRC 校验),会延长中断响应时间,甚至阻塞更高优先级的中断。队列可将 “复杂处理” 转移到后台任务。

示例:CAN 总线中断收到一帧数据后,ISR 仅需完成 “数据拷贝”(将 CAN 数据寄存器的值存入缓冲区),再将 “缓冲区地址” 放入队列,随后立即退出;后台 “CAN 数据解析任务” 从队列中取出地址,执行 CRC 校验、协议解析、业务逻辑处理等耗时操作,既保证了 ISR 的轻量化,又不影响数据处理的完整性。

6. 实时性保障与优先级支持

主流 RTOS(如 FreeRTOS、RTX)的队列均支持优先级继承优先级排序,可保障高优先级任务的实时性需求。

  • 优先级读取:当多个任务同时从一个队列读取数据时,RTOS 会优先调度 “高优先级任务”。例如 “紧急故障处理任务”(高优先级)和 “普通数据处理任务”(低优先级)都监听同一个队列,当队列中收到 “故障数据” 时,高优先级的故障任务会优先读取数据并处理,满足实时性要求。

  • 优先级发送:部分 RTOS 的队列支持 “按优先级插入数据”(如 FreeRTOS 的xQueueSendToFront),例如 “紧急报警数据” 可插入队列头部,优先被处理,而 “普通状态数据” 插入队列尾部,确保紧急事件的响应速度。

嵌入式队列的关键特性(与通用队列的区别)

由于嵌入式系统的资源受限性,嵌入式场景中的队列通常具备以下适配特性:

  1. 固定大小:队列创建时需指定 “队列深度”(最大数据个数)和 “每个数据的大小”,避免动态内存分配(减少内存碎片)。

  2. 阻塞机制:任务从空队列读取数据时,可设置 “阻塞时间”(如等待 100ms),期间任务进入阻塞态,不占用 CPU 资源;队列有数据后,任务自动唤醒,提升系统效率。

  3. 中断安全:提供 ISR 专用接口(如 FreeRTOS 的xQueueSendFromISR、RT-Thread 的rt_queue_send_from_isr),确保在中断上下文操作队列时不会破坏数据结构。

总结

队列是嵌入式开发中的 “通信与缓冲核心”,其本质是通过FIFO 规则实现 “数据 / 事件的有序传递”,解决了多任务 / 中断间的通信、数据缓冲、时序解耦、资源冲突等核心痛点。在 RTOS 驱动开发、外设管理、业务逻辑设计中,队列几乎是不可或缺的工具,直接影响嵌入式系统的稳定性、实时性和可维护性。

代码实例:

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <windows.h> typedef int qDataType;typedef struct queueNode {int data;struct queueNode *next;
}qNode;typedef struct {qNode *head;qNode *tail;int size;
}queue;void queueInit(queue *q)
{q->head = NULL;q->tail = NULL;q->size = 0;
}bool queueEmpty(queue *q)
{if (q->size == 0){return true;}else {return false;}
}void queueDestroy(queue *q)
{while (q->size != 0){qNode* tmp = q->head;q->head->next = q->head;free(tmp);q->size--;}
}int getQueueSize(queue *q)
{assert(q);return q->size;
}qDataType getQueueHead(queue *q)
{assert(q);assert(!queueEmpty(q));return q->head->data;
}qDataType getQueueTail(queue *q)
{assert(q);assert(!queueEmpty(q));return q->tail->data;
}void queuePush(queue *q, qDataType iData)
{assert(q);qNode* newNode = (qNode*)malloc(sizeof(qNode));if (newNode==NULL){printf("malloc failed\n");return;}else {newNode->data = iData;newNode->next = NULL;if (queueEmpty(q)){q->head = newNode;q->tail = newNode;}else {q->tail->next = newNode;q->tail = q->tail->next;}q->size++;}
}void queuePop(queue *q)
{assert(q);assert(!queueEmpty(q));if (q->size=1&&(q->head)==(q->tail)){qNode* tmp = q->head;q->head = NULL;q->tail = NULL;free(tmp);}else {qNode* tmp = q->head;q->head = q->head->next;free(tmp);}q->size--;
}
void qPrintFromHead(queue *q)
{if (q == NULL || q->head == NULL) {printf("队列是空的,无数据可输出\n");return;}qNode* current = q->head;  printf("队列从头至尾的输出:");while (current != NULL) {printf("%d ", current->data);  current = current->next;      }printf("\n");  
}int main()
{queue* qPTR = (queue*)malloc(sizeof(queue));queueInit(qPTR);for (int i = 0; i < 5; i++) {queuePush(qPTR, i);}qPrintFromHead(qPTR);Sleep(1000);queuePop(qPTR);qPrintFromHead(qPTR);return 0;
}

http://www.dtcms.com/a/610671.html

相关文章:

  • 网页设计个人网站建设工程交易中心是什么机构
  • Docker 核心命令速查表(精细分类版)
  • leetcode 2536 子矩阵元素加1
  • 如何做企业网站建设怎么清空wordpress媒体库
  • 做网站流程内容美食网站建设总结
  • 面对网络攻击告警 IP地址如何实现自动化封禁
  • 专栏介绍:AMD KFD BO设计深度剖析——解锁GPU存储核心技术
  • Kimi K2 Thinking:兼顾Agent和推理的六边形战士
  • 打字游戏——测一测你的反应速度
  • SpringBoot17-addresourcehandler()方法
  • 网站模版建设教程贵阳网站建设哪家公司好
  • 设计师配色网站中国建设部官方网站绿色建筑
  • 11.14作业
  • 建设银行苏州网站网站推广服务具体内容包括哪些
  • 第四章深度解析:智能体经典范式实战指南——从ReAct到Reflection的全流程拆解
  • 购物网站后台模板南京的网站建设公司哪家好
  • 构建手写数字识别Web应用:前后端完整解决方案
  • 网站制作过程简介网络规划设计师如何复习
  • 从 Chat Completions 到 Responses:不仅仅是更改了接口这么简单
  • (ICLR 2019)APPNP传播用 PageRank,不用神经网络!
  • 解决 Mac 迁移数据后用户目录无权限问题
  • 长春网站制作价格网站空间要备案吗
  • C#1114 枚举
  • 语义分割中上采样Up-sampling的原理
  • 如何建设局域网网站江苏强荣建设有限公司 网站
  • Android Neon支持
  • 合肥专业手机网站制作价格vs中的网站导航怎么做
  • 上海市建设工程质监站网站网站里怎么做301指向
  • 带数据库的网站模板下载wordpress章节分页
  • adb之系统工具—dumpsys 命令