【FreeRTOS-消息队列】
参照正点原子以及以下gitee笔记整理本博客,并将实验结果附在文末。
https://gitee.com/xrbin/FreeRTOS_learning/tree/master
一、队列简介
1、FreeRTOS中的消息队列是什么
答:消息队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传递)。
2、消息队列和全局变量的区别
答:消息队列作用有点类似于全局变量,但消息队列在RTOS中比全局变量更安全可靠。
假设有一个全局变量a=0,现在有两个任务都要写这个变量a。
上图中任务1和任务2在RTOS中相互争取修改a的值,a的值容易受损错乱。
下图表示如果使用全局变量,当任务1运行到②时,更高优先级的任务2抢占并完全执行得到r0为1赋给a,然后回到任务1执行③,最终结果执行完任务1和任务2后,a=1
全局变量的弊端:数据无保护,导致数据不安全,当多个任务同时对该变量操作时,数据易受损。
3、使用队列的情况
答:使用队列的情况如下:
读写队列做好了保护,防止多任务或中断同时访问产生冲突。我们只需直接调用API函数即可,简单易用。
注意:FreeRTOS基于队列,实现了多种功能,其中包括队列集、互斥信号量、计数信号量、二值信号量、递归互斥信号量,因此很有必要深入了解FreeRTOS的队列。
补充:任务调度是由于PendSV引起的,他的中断优先级是最低的,关闭中断后,PendSV无法触发,因此任务A在写队列是,任务B是无法打断任务A的执行的。
4、队列项目和队列长度
答:在队列中可以存储数量有限、大小固定的数据。队列中的每个数据就叫做 “队列项目” ,队列能够存储 “队列项目” 的最大数量称为队列的长度。
在创建队列时,就要指定队列长度以及队列项目的大小!
5、FreeRTOS队列特点
答:
-
数据入队出队方式 : 队列通常采用 “先进先出(FIFO)” 的数据存储缓冲机制,即先入队的数据会先从队列中被读取,FreeRTOS中也可以配置为 “后进先出(LIFO)” 方式。
-
数据传递方式 : FreeRTOS中队列采用实际值传递,即将数据拷贝到队列中进行传递,FreeRTOS采用拷贝数据传递,也可以传递指针,所以在传递较大的数据的时候采用指针传递。
-
多任务访问 : 队列不属于某个任务,任何任务和中断都可以向队列写入/读取消息。
-
出队、入队阻塞 : 当任务向一个队列发送/读取消息时,可以指定一个阻塞时间,假设此时当队列已满无法入队。
- 若阻塞时间为0 :直接返回不会等待。
- 若阻塞时间为0~port_MAX_DELAY :等待设定阻塞时间,若在该时间内无法入队/出队,超时后直接返回不再等待。
- 若阻塞时间为port_MAX_DELAY :死等,一直等到可以入队/出队为止。
6、入队/出队阻塞过程
答:
入队阻塞:
队列满了,此时写不进去数据:
-
将该任务的状态列表项(就绪列表)挂载在pxDelayedTaskList(阻塞列表);
-
将该任务的事件列表项挂载在xTasksWaitingToSend(等待发送列表);
出队阻塞:
队列为空,此时读取不了数据:
-
将该任务的状态列表项(就绪列表)挂载在pxDelayedTaskList(阻塞列表);
-
将该任务的事件列表项挂载在xTasksWaitingToReceive(等待读取列表);
(当队列中有数据,那么解除xTasksWaitingToReceive,移除pxDelayedTaskList,放到就绪列表里,此时任务B就能够执行)
7、当多个任务写入消息给一个 “满队列” 时,这些任务都会进入阻塞状态,也就是说有多个任务在等待同一个队列的空间。那当队列有空间时,哪个任务会进入就绪态?
答:
-
优先级最高的任务
-
如果大家的优先级相同,那等待时间最久的任务进入就绪态。
8、队列创建、写入和读出过程
答:
二、队列结构体介绍
1、队列结构体
答:
typedef struct QueueDefinition
{int8_t * pcHead; /* 存储区域的起始地址 */int8_t * pcWriteTo; /* 下一个写入的位置 */union{QueuePointers_t xQueue;SemaphoreData_t xSemaphore; } u ;List_t xTasksWaitingToSend; /* 等待发送列表 */List_t xTasksWaitingToReceive; /* 等待接收列表 */volatile UBaseType_t uxMessagesWaiting; /* 非空闲队列项目的数量 */UBaseType_t uxLength; /* 队列长度 */UBaseType_t uxItemSize; /* 队列项目的大小 */volatile int8_t cRxLock; /* 读取上锁计数器 */volatile int8_t cTxLock; /* 写入上锁计数器 *//* 其他的一些条件编译 */
} xQUEUE;
当用于队列使用时:
typedef struct QueuePointers
{int8_t * pcTail; /* 存储区的结束地址 */int8_t * pcReadFrom; /* 最后一个读取队列的地址 */
} QueuePointers_t;
当用于互斥信号量和递归互斥信号量时:
typedef struct SemaphoreData
{TaskHandle_t xMutexHolder; /* 互斥信号量持有者 */UBaseType_t uxRecursiveCallCount; /* 递归互斥信号量的获取计数器 */
} SemaphoreData_t;
队列结构体示意图:
队列结构体存储区+队列项(消息)存储区
int8_t * pcHead; /* 存储区域的起始地址 */
int8_t * pcWriteTo; /* 下一个写入的位置 */
int8_t * pcTail; /* 存储区的结束地址 */
int8_t * pcReadFrom; /* 最后一个读取队列的地址 */
三、队列相关API函数介绍
1、队列使用流程
答:使用队列的主要流程:创建队列 —> 写队列 —> 读队列。
2、创建队列函数
答:
函数返回值:
3、各种功能所对应的队列
答:
#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) /* 队列 */
#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) /* 队列集 */
#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) /* 互斥信号量 */
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) /* 计数型信号量 */
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) /* 二值信号量 */
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) /* 递归互斥信号量 */
4、队列写入消息函数
答:
任务级+中断级
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait )xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait )xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait )xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )
#define xQueueOverwrite( xQueue, pvItemToQueue )xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE )
可以看到这几个写入函数调用的是同一个函数xQueueGenericSend( ),只是指定了不同的写入位置!
队列一共有3种写入位置:
#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) /* 写入队列尾部 */
#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) /* 写入队列头部 */
#define queueOVERWRITE ( ( BaseType_t ) 2 ) /* 覆写队列*/
注意:==覆写方式写入队列,只有在队列的队列长度为 1 时,才能够使用== 。往队列写入消息函数入口参数解析:
BaseType_t xQueueGenericSend( QueueHandle_t xQueue,const void * const pvItemToQueue,TickType_t xTicksToWait,const BaseType_t xCopyPosition );
函数参数:
函数返回值:
5、队列读出消息函数
答:
BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )
函数参数:
函数返回值:
BaseType_t xQueuePeek( QueueHandle_t xQueue,void * const pvBuffer,TickType_t xTicksToWait )
此函数用于在任务中,从队列中读取消息, 但与函数 xQueueReceive()不同,此函数在成功读取消息后,并不会移除已读取的消息!
函数参数:
函数返回值:
四、队列操作实验
实验简介
实验现象
task2和task3无需调用延时函数,由于调用队列接收函数,如果队列无数据,表明无法接收数据,任务会自动进入阻塞态。
部分代码
/******************************************************************************************************* @file freertos.c* @author 正点原子团队(ALIENTEK)* @version V1.4* @date 2022-01-04* @brief FreeRTOS 移植实验* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司***************************************************************************************************** @attention** 实验平台:正点原子 探索者F407开发板* 在线视频:www.yuanzige.com* 技术论坛:www.openedv.com* 公司网址:www.alientek.com* 购买地址:openedv.taobao.com******************************************************************************************************/#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handle;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handle;
void task1(void * pvParameters);/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/#define TASK2_PRIO 3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handle;
void task2(void * pvParameters);/* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/#define TASK3_PRIO 4
#define TASK3_STACK_SIZE 128
TaskHandle_t task3_handle;
QueueHandle_t key_queue; /* 小数据 */
QueueHandle_t big_data_queue; /* 大数据 */
char big_buff[100] = {"我是大数组,大大的数组 12123dafenhagendasi"};
void task3(void * pvParameters);/******************************************************************************************************//*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{ /* 队列创建 */key_queue = xQueueCreate( 2, sizeof(uint8_t) ); /* 由于有两个按键,因此队列项长度为2 ;按键键值的大小 */if(key_queue != NULL){printf("Key_queue队列创建成功!\r\n");}else{printf("Key_queue队列创建失败!\r\n");}big_data_queue = xQueueCreate( 1, sizeof(char *) ); /* 由于有大数据数组,因此队列项长度为2 ;数组首地址 */if(big_data_queue != NULL){printf("big_data_queue队列创建成功!\r\n");}else{printf("big_data_queue队列创建失败!\r\n");}xTaskCreate( (TaskFunction_t ) start_task,(char * ) "start_task",(configSTACK_DEPTH_TYPE) START_TASK_STACK_SIZE,(void * ) NULL, (UBaseType_t ) START_TASK_PRIO,(TaskHandle_t * ) &start_task_handle);//开启任务调度器vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL(); /*进入临界区,任务切换不会进行*/xTaskCreate( (TaskFunction_t ) task1,(char * ) "task1",(configSTACK_DEPTH_TYPE) TASK1_STACK_SIZE,(void * ) NULL, (UBaseType_t ) TASK1_PRIO,(TaskHandle_t * ) &task1_handle);xTaskCreate( (TaskFunction_t ) task2,(char * ) "task2",(configSTACK_DEPTH_TYPE) TASK2_STACK_SIZE,(void * ) NULL, (UBaseType_t ) TASK2_PRIO,(TaskHandle_t * ) &task2_handle);xTaskCreate( (TaskFunction_t ) task3,(char * ) "task3",(configSTACK_DEPTH_TYPE) TASK3_STACK_SIZE,(void * ) NULL, (UBaseType_t ) TASK3_PRIO,(TaskHandle_t * ) &task3_handle);vTaskDelete( NULL );taskEXIT_CRITICAL(); /*退出临界区,才会开始任务切换*//*简单而言,临界区保护,就是保护那些不想被打断的从程序段 */ }/* 任务一,实现入队 */
void task1(void * pvParameters)
{uint8_t key_value = 0;char * buf;BaseType_t err = 0;buf = big_buff; /* buf = &buff[0] */while(1){ key_value = key_scan(0);if(key_value == KEY0_PRES || key_value == KEY1_PRES){err = xQueueSend(key_queue, &key_value, portMAX_DELAY);if(err != pdTRUE){printf("队列发送失败\r\n");}}else if(key_value == WKUP_PRES){err = xQueueSend(big_data_queue, &buf, portMAX_DELAY);if(err != pdTRUE){printf("队列发送失败\r\n");}}vTaskDelay(10);}
}/* 任务二,实现小数据出队 */
void task2(void * pvParameters)
{uint8_t key = 0;BaseType_t err = 0;while(1){err = xQueueReceive(key_queue,&key,portMAX_DELAY); /* 即使没有调用延时函数,由于队列接收函数接收不了数据而变为阻塞态 */if(err != pdTRUE){printf("key_queue队列读取失败\r\n");}else{printf("key_queue读取对列成功,数据%d\r\n",key);}}
}/* 任务二,实现大数据出队 */
void task3(void * pvParameters)
{char * buf;BaseType_t err = 0;while(1){err = xQueueReceive(big_data_queue,&buf,portMAX_DELAY);if(err != pdTRUE){printf("big_data_queue队列读取失败\r\n");}else{printf("big_data_queue读取对列成功,数据%s\r\n",buf);}}}
相关文章:
【FreeRTOS-消息队列】
参照正点原子以及以下gitee笔记整理本博客,并将实验结果附在文末。 https://gitee.com/xrbin/FreeRTOS_learning/tree/master 一、队列简介 1、FreeRTOS中的消息队列是什么 答:消息队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传…...
二叉查找树,平衡二叉树(AVL),b树,b+树,红黑树
🌲 一、二叉查找树(Binary Search Tree,简称 BST) 📌 定义 二叉查找树是一棵二叉树,它满足这样的特性: 每个节点最多有两个子节点(左、右)对于任意一个节点: 它左子树的所有节点值都比它小它右子树的所有节点值都比它大📈 举个例子 复制代码 10/ \5 20/ \ …...
可执行文件格式(ELF格式)以及进程地址空间第二讲【Linux操作系统】
文章目录 可执行文件的格式可执行文件中存储了什么可执行文件中的虚拟地址以及加载 进程地址空间第二讲CPU如何执行进程的代码再谈进程地址空间的区域划分 可执行文件的格式 源文件被编译器编译之后的可执行文件,并不是只有代码和数据,还有一定的格式&a…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】8.1 基础图表绘制(折线图/柱状图/散点图)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL数据分析实战:基础图表绘制(折线图/柱状图/散点图)8.1 基础图表绘制8.1.1 折线图:展现数据趋势数据准备图表绘制步…...
Yii2.0 模型规则(rules)详解
一、基本语法结构 public function rules() {return [// 规则1[[attribute1, attribute2], validator, options > value, ...],// 规则2[attribute, validator, options > value, ...],// 规则3...]; }二、规则类型分类 1、核心验证器(内置验证器࿰…...
Notepad++中XML格式化插件介绍
Notepad++中XML格式化插件介绍 背景安装指南安装步骤验证安装成功安装失败可尝试使用说明XML文件格式正确时格式化错误格式检查XML Tools插件核心功能盘点常见问题格式化后没变化中文显示乱码拯救杂乱XML格式!Notepad++这个神器插件,必须接收!背景 接手别人写的XML,缩进乱成…...
在 R 中,清除包含 NA(缺失值)的数据
在 R 中,清除包含 NA(缺失值)的数据可以通过多种方式实现,具体取决于你希望如何处理这些缺失值。以下是几种常见的方法,包括删除包含 NA 的行、删除包含 NA 的列,或者用特定值填充 NA。 1. 删除包含 NA 的…...
Linux复习笔记(一)基础命令和操作
遇到的问题,都有解决方案,希望我的博客能为你提供一点帮助。 一、Linux中的基础命令和操作(约30%-40%) 1.用户和组(5%左右) 1.1用户简介(了解) 要求:了解,知道有三个用户…...
多线程的出现解决了什么问题?深入解析多线程的核心价值
多线程的出现解决了什么问题?深入解析多线程的核心价值 1. 引言 在计算机科学中,多线程(Multithreading) 是一种重要的并发编程技术,它允许一个进程同时执行多个任务,从而提高程序的性能和响应能力。那么,多线程究竟是为了解决哪些问题而诞生的?它的核心价值是什么?…...
java集合菜鸟教程
1、Java集合的分类 1Java中的集合类可以分为两大类: (1)实现Collection接口,Collection是一个基本的集合接口,Collection中可以容纳一组集合元素(Element),图1是Collection与子类的…...
体育培训的实验室管理痛点 质检LIMS如何重构体育检测价值链
在竞技体育与全民健身并行的时代背景下,体育培训机构正面临双重挑战:既要通过科学训练提升学员竞技水平,又需严格把控运动安全风险。作为实验室数字化管理的核心工具,质检LIMS系统凭借其标准化流程管控与智能化数据分析能力&#…...
3、食品包装控制系统 - /自动化与控制组件/food-packaging-control
76个工业组件库示例汇总 食品包装线控制系统 这是一个用于食品包装线控制系统的自定义组件,提供了食品包装生产线的可视化监控与控制界面。组件采用工业风格设计,包含生产流程控制、实时数据监控和逻辑编程三个主要功能区域。 功能特点 工业风格UI设…...
AbMole的Calcein-AM/PI细胞双染试剂盒,精准区分细胞活死状态
在细胞生物学研究中,细胞活性检测是基础且关键的实验环节。然而,传统方法在检测活细胞和死细胞时常常面临诸多挑战:例如,检测过程复杂、耗时,容易受到细胞类型和实验条件的限制;荧光信号不稳定,…...
力扣刷题Day 37:LRU 缓存(146)
1.题目描述 2.思路 方法1:直接用Python封装好的数据结构OrderedDict(兼具哈希表与双向链表的数据结构)。 方法2:哈希表辅以双向链表。 3.代码(Python3) 方法1: class LRUCache(collections…...
动态规划之01背包——三道题助你理解01背包
目录 二维数组实现 一维数组实现 例一P1164 小A点菜 P1048 [NOIP 2005 普及组] 采药 P1802 5 倍经验日 首先做动规很好的一个办法就是卡哥提出的动规五部曲个人觉得很好用 确定dp数组(dp table)以及下标的含义 确定递推公式 dp数组如何初始化 确定遍…...
【前端笔记】CSS 选择器的常见用法
目录 1. CSS 的基本语法规范2. CSS 的引入方式3. CSS 选择器的种类3.1 标签选择器3.2 类选择器3.3 id 选择器3.4 复合选择器3.5 通配符选择器 4. 补充内容 1. CSS 的基本语法规范 选择器 {1 条 / n 条声明} 选择器决定的是修改谁声明决定的是怎么修改声明的属性是键值对&…...
电脑桌面悬浮窗便签,好用的电脑桌面便签工具
不知道大家有没有发现,我们每天要处理的事情越来越多:工作会议、项目截止日期、临时灵感、购物清单...光靠大脑记忆显然不够靠谱。你可能试过用手机备忘录,但工作时频繁切换设备又很影响效率。 这时候,一款好用的电脑桌面便签工具…...
Windows环境下maven的安装与配置
1.检查JAVA_HOME环境变量 Maven是使用java开发的,所以必须知道当前系统环境中的JDK的安装目录。 搜索栏直接输入“cmd” 或者 WinR 输入cmd 在打开的终端窗口输入“echo %JAVA_HOME”,就可以看到jdk的位置了。 如果没有的话,请参考我的文章&a…...
PyTorch 中如何针对 GPU 和 TPU 使用不同的处理方式
一个简单的矩阵乘法例子来演示在 PyTorch 中如何针对 GPU 和 TPU 使用不同的处理方式。 这个例子会展示核心的区别在于如何获取和指定计算设备,以及(对于 TPU)可能需要额外的库和同步操作。 示例代码: import torch import tim…...
数据库同步方案:构建企业数据流通的高速通道
在数字经济时代,数据已成为企业核心资产。根据Gartner统计,超过70%的企业因数据孤岛问题导致决策延迟,而高效可靠的数据库同步方案正是破解这一困局的关键技术。本文将深度解析数据库同步的核心逻辑、主流方案及实践策略,助企业构…...
微信小程序开发,登录注册实现
文章目录 1. 官方文档教程2. 注册实现3. 登录实现4. 关于作者其它项目视频教程介绍 1. 官方文档教程 https://developers.weixin.qq.com/miniprogram/dev/framework/路由跳转的几种方式: https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab…...
VSCode怎么同时打开多个页面
VSCode中打开一个文件会把另一个文件覆盖,始终保持打开一个文件的状态,相对于其他IDE是不太习惯的,如果同时打开两个文件页面怎么去设置呢 1、禁用预览模式 2、快速分屏快捷键: Ctrl\ (Windows/Linux) 或 Cmd\ (macOS)...
【多种不同提交方式】通过springboot实现与前端网页数据交互(非常简洁快速)
【多种不同提交方式】通过springboot实现与前端网页数据交互 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有:学习and理解的关联性。【帮帮志系列文章】&am…...
Web 架构之负载均衡全解析
文章目录 一、引言二、思维导图三、负载均衡的定义与作用定义作用1. 提高可用性2. 增强性能3. 实现扩展性 四、负载均衡类型硬件负载均衡代表设备优缺点 软件负载均衡应用层负载均衡代表软件优缺点 网络层负载均衡代表软件优缺点 五、负载均衡算法轮询算法(Round Ro…...
猫咪如厕检测与分类识别系统系列~进阶【一】视频流推流及网页实时展示
前情提要 家里养了三只猫咪,其中一只布偶猫经常出入厕所。但因为平时忙于学业,没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关,频繁如厕可能是泌尿问题,停留过久也可能是便秘或不适。为了更科学地了解牠的如…...
DeepSeek全域智能革命:从量子纠缠到星际文明的认知跃迁引言:认知边界的坍缩与重构
一、认知架构的技术基石 1.1 混合专家系统的流形蒸馏 DeepSeek-R2的MoE架构采用微分流形蒸馏技术,将6710亿参数的教师模型(如DeepSeek-Prover-V2)的知识嵌入到动态路由网络中。通过辛几何约束下的参数投影,模型在保留数学证明能…...
Mkdocs页面如何嵌入PDF
嵌入PDF 嵌入PDF代码 ,注意PDF的相对地址 <iframe src"../个人简历.pdf (相对地址)" width"100%" height"800px" style"border: 1px solid #ccc; overflow: auto;"></iframe>我的完整代码: <d…...
JS进阶DAY2 构造函数数据常用函数
深入对象 1.创建对象的三种方式 1.利用对象字面量创建对象 const o{ name:佩奇 } 2.利用 new Object 创建对象 const onew Object({ name:佩奇}) console.log(o) //{name:佩奇} 3.利用构造函数创建对象 2.构造函数 构造函数:是一种特殊的函数,主要用来初始…...
【ARM AMBA AHB 入门 3 -- AHB 总线介绍】
请阅读【ARM AMBA 总线 文章专栏导读】 文章目录 AHB Bus 简介AHB Bus 构成AHB BUS 工作机制AHB 传输阶段 AHB InterfacesAHB仲裁信号 AHB 数据访问零等待传输(no waitstatetransfer)等待传输(transfers with wait states)多重传送(multipletransfer)--Pipeline AHB 控制信号 A…...
计划评审技术PERT
计划评审技术(Program Evaluation and Review Technique,PERT)是一种用于项目管理和分析的工具,主要用于估算项目完成时间、识别关键路径以及评估项目进度风险。它最初是在20世纪50年代由美国海军开发的,用于管理复杂的…...
【Leetcode 每日一题 - 扩展】3342. 到达最后一个房间的最少时间 II
问题背景 有一个地窖,地窖中有 n m n \times m nm 个房间,它们呈网格状排布。 给你一个大小为 n m n \times m nm 的二维数组 m o v e T i m e moveTime moveTime,其中 m o v e T i m e [ i ] [ j ] moveTime[i][j] moveTime[i][j] 表…...
Linux57配置MYSQL YUM源
错了,弄错了下载地址 显示没MYSQL 刚才YUM包弄错了 下的是rpm文件 应该安装 通过yum install安装 .repo中的enabled需要修改 哪些能修改 哪些不改 配置特定软件的YUM仓库 nginx看教程有官方文档 将官方文档中YUM配置写入.repo文件然后yum clean all yum ma…...
Kafka是什么?典型应用场景有哪些? (消息队列、流处理平台;日志收集、实时分析、事件驱动架构等)
Kafka 核心解析与场景代码示例 一、Kafka核心概念 Apache Kafka 是分布式流处理平台,具备以下核心能力: 发布-订阅模型:支持多生产者/消费者并行处理持久化存储:消息默认保留7天(可配置)分区机制&#x…...
数据实验分析
数据分析数据分类与绘图数据分类方法:通过指定列名和函数(如SUM)来分类数据,确保数据集中包含所需列,否则会报错。嵌套柱形图应用:嵌套柱形图用于展示多层次分类的数据,如按店名和化妆品类别分类…...
PostgreSQL中“参数默认值实现伪重载“详解
什么是伪重载? "伪重载"指的是通过单一函数定义配合参数默认值和条件逻辑来模拟传统编程语言中方法重载的效果。与真正的函数重载(PostgreSQL支持的多同名函数不同参数实现)不同,伪重载是在一个函数内部处理不同参数组…...
在IDEA中编写Spark程序并运行
Spark是基于scala的,当然它也可以支持java和scala还有python语言,我们这里会使用scala。 1.在Idea中安装插件,使得Idea中可以编写scala代码。 2.使用Maven创建项目,并在pom.xml文件中配置相关的依赖。 3.设置maven依赖项。修改po…...
知识图谱:AI大脑中的“超级地图”如何炼成?
人类看到“苹果”一词,会瞬间联想到“iPhone”“乔布斯”“牛顿”,甚至“维生素C”——这种思维跳跃的背后,是大脑将概念连结成网的能力。而AI要模仿这种能力,需要一张动态的“数字地图”来存储和链接知识,这就是知识…...
Facebook隐私设置详解:如何保护你的个人信息
在这个数字化时代,个人信息安全变得尤为重要。Facebook 作为全球最大的社交网络平台之一,拥有数十亿用户。然而,随着用户数量的增加,隐私问题也日益凸显。本文将详细介绍 Facebook 的隐私设置,帮助你更好地保护个人信息…...
【Hive入门】Hive数据导入与导出:批量操作与HDFS数据迁移完全指南
目录 引言 1 Hive数据导入概述 1.1 Hive数据导入方式分类 1.2 Hive数据模型与存储结构 2 LOAD DATA命令详解 2.1 基本语法与参数 2.2 LOAD DATA执行流程 2.3 案例分析 3 HDFS数据迁移技术 3.1 HDFS文件操作与Hive集成 3.2 外部表技术应用 3.3 分区表动态加载 4 性…...
深入浅出JSON:现代数据交换的基石
JSON(JavaScript Object Notation)已经成为当今互联网上最流行的数据交换格式之一。无论是Web API、配置文件还是NoSQL数据库,JSON都扮演着至关重要的角色。本文将带你全面了解JSON,从基础概念到高级应用。 什么是JSON࿱…...
C++ 日志系统实战第四步:设计与代码实现详解
全是通俗易懂的讲解,如果你本节之前的知识都掌握清楚,那就速速来看我的项目笔记吧~ 本文将加入项目代码编写! 目录 日志系统框架设计 模块划分 模块关系图 代码设计 实用类设计 日志等级设计 日志消息类 日志输出格式 日志落地(L…...
DeepSeek API接口调用示例(开发语言C#,替换其中key值为自己的key值即可)
示例: DeepSeek官方接口说明文档:对话补全 | DeepSeek API Docs 官网暂未提供C#代码实现:(以下为根据CURL接口C#代码调用) using System; using System.Collections.Generic; using System.Linq; using System.Text; …...
PyTorch常用命令(可快速上手PyTorch的核心功能,涵盖从数据预处理到模型训练的全流程)
以下是PyTorch常用命令的分类整理,涵盖张量操作、模型构建、数据加载、训练流程等核心内容: 1. 张量操作 创建张量 x torch.tensor([1, 2, 3]) # 从数据创建 x torch.zeros(3, 3) # 全零张量 x torch.ones(3, 3) …...
软开错题(二)
SNMP的传输层协议是UDP Linux操作系统中通常使用apache作为web服务器,其默认的web站点的目录是 /var/www/html 归并排序不是原地排序 邻接表:包含n个头节点和e个表节点,其广度和深度遍历的时间复杂度都是O(ne) grant使用方式 grant 权限 …...
拉削丝锥,螺纹类加工的选择之一
在我们的日常生活中,螺纹连接无处不在,从简单的螺丝钉到复杂的机械设备,都离不开螺纹的精密加工。今天,给大家介绍一种的螺纹刀具——拉削丝锥: 一、拉削丝锥的工作原理 拉削丝锥,听起来有点陌生吧&#…...
【Python Number(数字)】
Python 中的数字类型是编程的基础元素,用于表示数值数据并进行数学运算。以下是 Python 数字类型的核心知识点: 一、基础数字类型 整数(int) 表示整数值,例如 42, -7, 0支持任意精度(无大小限制)…...
大疆无人机SDR 链路
在大疆无人机或通信技术领域,SDR 是 Software-Defined Radio(软件定义无线电) 的缩写,而 SDR 链路 指的是一种通过软件编程实现无线通信功能的技术链路。其核心是通过软件动态调整通信参数&#…...
linux基础学习--linux磁盘与文件管理系统
linux磁盘与文件管理系统 1.认识linux系统 1.1 磁盘组成与分区的复习 首先了解磁盘的物理组成,主要有: 圆形的碟片(主要记录数据的部分)。机械手臂,与在机械手臂上的磁头(可擦写碟片上的内容)。主轴马达,可以转动碟片,让机械手臂的磁头在碟片上读写数据。 数据存储…...
【Qt】Qt 构建系统详解:qmake 入门到项目实战
Qt 构建系统详解:qmake 入门到项目实战 本文将系统介绍 Qt 构建工具 qmake 的用法,并通过一个完整的项目结构示例,帮助你掌握 .pro 文件编写、子项目管理、模块依赖等核心技能。 🧭 一、什么是 qmake? qmake 是 Qt 提…...
Laravel 12 实现验证码功能
Laravel 12 实现验证码功能 在 Laravel 12 中实现验证码功能可以通过多种方式,以下是几种常见的方法: 方法一:使用 Captcha 包(推荐) 首先安装 mews/captcha 包: composer require mews/captcha发布配置…...