13_FreeRTOS消息队列

2023-05-16

目录

队列简介

FreeRTOS队列特点

队列操作基本过程 

队列结构体介绍

队列结构体整体示意图

队列相关API函数介绍

创建队列相关API函数介绍

往队列写入消息API函数

往队列写入消息函数入口参数解析 

从队列读取消息API函数

实验源码


队列简介

队列是任务到任务任务到中断、中断到任务数据交流的一种机制(消息传递)

类似全局变量?假设有一个全局变量a = 0,现有两个任务都在写这个变量a

假设在任务1完成2步骤修改数据的时候,此时任务2优先级高打断任务1,a还是0因为任务a还没有写数据,任务2执行了加1,在回到任务1时,下一步是执行写数据此时r0是任务2执行完时候的1,任务1在吧R0赋值给a,相当于r0等于1在给a,并没有等于2。这样就照成了数据的受损。

全局变量的弊端:数据无保护,导致数据不安全,当多个任务同时对该变量操作时,数据易受损

使用队列的情况如下:

 读写队列做好了保护,防止多任务同时访问冲突;FreeRTOS基于队列,实现了多种功能,其中包括队列集、互斥信号量、计数型信号量、二值信号量、递归互斥信号量,因此很有必要深入了解 FreeRTOS的队列。

在队列中可以存储数量有限、大小固定的数据。队列中的每一个数据叫做“队列项目” ,队列能够存储“队列项目”的最大数量称为队列的长度

 队列长度为:5个

队列项目大小为:10字节

队列长度和队列项目不是固定的是创建的时候自己指定的。

FreeRTOS队列特点

1.数据入队出队方式:队列通常采用“先进先出”(FIFO)的数据存储缓冲机制,即先入队的数据会先从队列中被读取,FreeRTOS中也可以配置为“后进先出”LIFO方式

2.数据传递方式:FreeRTOS中队列采用实际值传递,即将数据拷贝到队列中进行传递,FreeRTOS采用拷贝数据传递,也可以传递指针,所以在传递较大的数据的时候采用指针传递

3.多任务访问:队列不属于某个任务,任何任务和中断都可以向队列发送/读取消息

4.出队入队阻塞:当任务向一个队列发送消息时,可以指定一个阻塞时间,假设此时当队列已满无法入队

        ①若阻塞时间为:0直接返回不会等待;

        ②若阻塞时间为0~port_MAX_DELAY:等待设定的阻塞时间,若在该时间内还无法入队, 超时后直接返回不再等待;

        ③若阻塞时间为port_MAX_DELAY:死等,一直等到可以入队为止。出队阻塞与入队阻塞 类似;

入队阻塞:

队列满了,此时写不进去数据;

①将该任务的状态列表项挂载在pxDelayedTaskList;(阻塞列表)

②将该任务的事件列表项挂载在xTasksWaitingToSend;(等待发送列表)

出队阻塞:

 队列为空,此时读取不了数据;

①将该任务的状态列表项挂载在pxDelayedTaskList;(阻塞列表)

②将该任务的事件列表项挂载在xTasksWaitingToReceive;(等待接收列表)

当多个任务写入消息给一个“满队列”时,这些任务都会进入阻塞状态,也就是说有多个任务在等待同一 个队列的空间。那当队列中有空间时,优先级最高的任务会进入就绪态,如果优先级相同,那等待时间最久的任务回进入就绪态。

队列操作基本过程 

1.创建队列

2.往队列写入第一个消息

 3.往队列写入第二个消息

4.从队列读取第一个消息

队列结构体介绍

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  uxltemSize;		/*队列项目的大小*/
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;

队列结构体整体示意图

队列相关API函数介绍

创建队列相关API函数介绍

 动态和静态创建队列之间的区别:队列所需的内存空间由FreeRTOS从FreeRTOS管理的堆中分配,而静态创建需要用户自行分配内存。

#define xQueueCreate ( uxQueueLength, uxltemSize)
xQueueGenericCreate( ( uxQueueLength ), ( uxltemSize ), (queueQUEUE_TYPE_BASE ))

此函数用于使用动态方式创建队列,队列所需的内存空间由 FreeRTOS 从 FreeRTOS 管理的堆中分配

 FreeRTOS 基于队列实现了多种功能,每一种功能对应一种队列类型,队列类型的 queue.h 文件中有定义:

#define queueQUEUE_TYPE_BASE    ((uint8_t) OU)/* 队列 */
#define queueQUEUE_TYPE_SET	  ((uint8_t) OU)/* 队列集*/
#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)/* 递归互斥信号量*/

往队列写入消息API函数

 任务级往队列写入消息

/*往队列的尾部写入消息*/
#define xQueueSend( xQueue, pvltemToQueue, xTicksToWait)
xQueueGenericSend( (xQueue ), ( pvltemToQueue ), (xTicksToWait), queueSEND_TO_BACK)

/*往队列的尾部写入消息*/
#define xQueueSendToBack( xQueue, pvltemToQueue, xTicksToWait)
xQueueGenericSend((×Queue ), ( pvltemToQueue ), (xTicksToWait), queueSEND_TO_BACK)



/*往队列的头部写入消息*/
#define xQueueSendToFront( xQueue, pvltemToQueue, xTicksToWait)
xQueueGenericSend((xQueue), (pvltemToQueue), (xTicksToWait), queueSEND_TO_FRONT)

/*覆写队列消息(只用于队列长度为1的情况)*/
#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, 
QueueHandle_t  xQueue,
TickType_t xTicksToWait,
const BaseType_t  xCopyPosition );

从队列读取消息API函数

/*从队列头部读取消息,并删除消息*/
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()不同,此函数在成功读取消息后,并不会移除已读取的消息!

实验源码

start_task  用来创建task1和task2以及task3任务

task1 当按键key0或key1按下,将键值拷贝到队列key_queue(入队)当按键kev_up按  下,将传输大数据,这里拷贝大数据的地址到队列big_date_queue中

task2 读取队列key_queue中的消息(出队)打印出接收到的键值

task3 从队列big_date_queue读取大数据地址,通过地址访问大数据

/**
  ******************************************************************************
  * @file           : user_mian.h
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdbool.h>
#include "user_gpio.h"
#include "user_delay.h"
#include "user_rcc_config.h"
#include "user_uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "user_key.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/ 

QueueHandle_t  key_queue;  		/*小数据句柄*/
QueueHandle_t  big_date_queue;  /*大数据句柄*/
char buff[100] = {" 大数组 12324164985465484684866"};
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);


//任务优先级
#define TASK1_PRIO			2
//任务堆栈大小	
#define TASK1_STK_SIZE 		100  
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);


//任务优先级
#define TASK2_PRIO			2
//任务堆栈大小	
#define TASK2_STK_SIZE 		100  
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);



//任务优先级
#define TASK3_PRIO			2
//任务堆栈大小	
#define TASK3_STK_SIZE 		100  
//任务句柄
TaskHandle_t Task3_Handler;
//任务函数
void task3(void *pvParameters);

 int main(void)
 {	

	/*配置系统中断分组为4位抢占*/
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	 /*延时函数初始化*/
	 delay_init();
	/*RCC配置*/
	 Rcc_config();
	/*GPIO初始化*/ 
	 Gpio_Init();
	/*USART1初始化*/
	 Uart1_Init(9600);
	 /*创建小数据队列*/ 
	 key_queue = xQueueCreate(2,sizeof(uint8_t));
	 if(key_queue != NULL)
	 {
		printf("key_queue队列创建!!\r\n\r\n");
	 }else 
	 {
		printf("key_queue队列创建失败!!\r\n\r\n");	 
	 }
	 /*创建大数据队列*/	 
	 big_date_queue = xQueueCreate(1,sizeof(char *));
	 if(key_queue != NULL)
	 {
		printf("big_date_queue队列创建!!\r\n\r\n");
	 }else 
	 {
		printf("big_date_queue队列创建失败!!\r\n\r\n");	 
	 }	 
	 
	 /*创建开始任务*/
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
		

}
 

/*!
	\brief		开始任务函数
	\param[in]	传递形参,创建任务时用户自己传入
	\param[out]	none
	\retval 	none
*/
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建任务1
    xTaskCreate((TaskFunction_t )task1,     	
                (const char*    )"task1",   	
                (uint16_t       )TASK1_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )TASK1_PRIO,	
                (TaskHandle_t*  )&Task1_Handler);   
    //创建任务2
    xTaskCreate((TaskFunction_t )task2,     
                (const char*    )"task2",   
                (uint16_t       )TASK2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&Task2_Handler); 
	//创建任务3
    xTaskCreate((TaskFunction_t )task3,     
                (const char*    )"task3",   
                (uint16_t       )TASK3_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )TASK3_PRIO,
                (TaskHandle_t*  )&Task3_Handler);

				
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}


/*!
	\brief		task1实现入队
	\param[in]	传递形参,创建任务时用户自己传入
	\param[out]	none
	\retval 	none
*/
void task1(void *pvParameters)
{
	uint8_t key = 0;
	BaseType_t err = 0;
	char * buf;
	buf = &buff[0];
	
    while(1)
    {	
		/*获取按键值*/
		key = Key_Scan(0);
		/*写入小数据*/
		if(key == KEY0_PRES || key == KEY1_PRES)
		{
			/*写入按键值,队列满就死等*/
			err = xQueueSend(key_queue,&key,portMAX_DELAY);
			
			if(err != pdTRUE)
			{
				printf("key_queue队列小数据发送失败\r\n\r\n");
			}
		}else if(key == WKUP_PRES)
		{	
			/*写入大数据,队列满就死等*/
			err = xQueueSend(big_date_queue,&buf,portMAX_DELAY);
			
			if(err != pdTRUE)
			{
				printf("big_date_queue队列大数据发送失败\r\n\r\n");
			}
		}
		vTaskDelay(100);
    }
} 


/*!
	\brief		task2实现小数据出队
	\param[in]	传递形参,创建任务时用户自己传入
	\param[out]	none
	\retval 	none
*/
void task2(void *pvParameters)
{
	uint8_t key = 0;
	uint8_t err = 0;
    while(1)
    {
		/*接受小数据,队列空死等*/	
		err = xQueueReceive(key_queue,&key,portMAX_DELAY);
		
		if(err != pdTRUE)
		{
			printf("key_queue队列小数据读取失败\r\n\r\n");
		}else
		{
			printf("读取key_queue队列成功,数据:%d\r\n\r\n",key);
		}
    }
}

/*!
	\brief		task3实现大数据出队
	\param[in]	传递形参,创建任务时用户自己传入
	\param[out]	none
	\retval 	none
*/
void task3(void *pvParameters)
{
	char * buf;
	uint8_t err = 0;
    while(1)
    {
		/*接受大数据,队列空死等*/	
		err = xQueueReceive(big_date_queue,&buf,portMAX_DELAY);
		
	 	if(err != pdTRUE)
		{
			printf("big_date_queue队列大数据读取失败\r\n\r\n");
		}else
		{
			printf("读取big_date_queue队列成功,数据:%s\r\n\r\n",buf);
		}		
    }
}

 /************************************************************** END OF FILE ****/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

13_FreeRTOS消息队列 的相关文章

  • FreeRTOS+CubeMX系列第一篇——初识FreeRTOS

    文章目录 一 关于FreeRTOS 二 FreeRTOS的特点 三 如何在CubeMX上配置FreeRTOS 四 FreeRTOS文档资料 五 同系列博客 一 关于FreeRTOS 1 什么是FreeRTOS FreeRTOS是一个迷你的实
  • FreeRTOS临界区

    FreeRTOS临界区是指那些必须完整运行 不能被打断的代码段 比如有的外设的初始化需要严格的时序 初始化过程中不能被打断 FreeRTOS 在进入临界区代码的时候需要关闭中断 当处理完临界区代码以后再打开中断 FreeRTOS 系统本身就
  • FreeRTOS_中断

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • 非阻塞的connect使用方式

    connect 函数的调用涉及到3次握手 默认connect函数为阻塞连接状态 通常connect 会阻塞到三次握手的完成和失败 而这个connect阻塞超时时间会依赖于系统 一般为75s到几分钟时间 一种方式可以通过该系统配置 proc
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • Rabbitmq入门到进阶看这篇就够了!

    安装前提 安装 erlang windows用户名非中文 可以关注我的公众号 知识追寻者 回复 rabbitmq 获取已经下载好的安装包和配套源码地址 本套教程对应知识追寻者网址 windows安装rabbitmq zszxz com Ra
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • php消息队列的应用

    欢迎加入 新群号码 99640845 最近打算开发一个新功能 计划应用消息队列 以前对消息队列都是简单的理论了解 真正应用之后把自己的感觉和一些理解整理下来 说正事分割线 具体的业务场景如下 用户下单 生成订单 支付 返回支付信息 就是正常
  • FreeRTOS之事件

    FreeRTOS之事件 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 一 事件定义 事件 事件集 与高数上的集合意义差不多 事件啊 其实是实现任务间通信的机制 主要用于实现多任务间的同步 但是事件类型
  • Arduino IDE将FreeRTOS用于STM32

    介绍 适用于STM32F103C8的FreeRTOS STM32F103C是一种能够使用FreeRTOS的ARM Cortex M3处理器 我们直接在Arduino IDE中开始使用STM32F103C8的FreeRTOS 我们也可以使用K
  • FreeRTOS死机原因

    1 中断回调函数中没有使用中断级API xxFromISR 函数 xSemaphoreGiveFromISR uart busy HighterTask 正确 xSemaphoreGive uart busy 错误 2 比configMAX
  • [FreeRTOS入门学习笔记]定时器

    定时器的使用步骤 1 定义一个handle xTimerCreate创建 2 启动定时器 在Task1中调用 通过队列通知守护任务来执行定时器任务 要再config头文件中定义守护任务相关配置 虽然定时器是在task1中启动 但是定时器的任
  • 秒杀系统中常见问题及解决方案

    秒杀中的常见问题的解决 1 解决超卖的问题 1 Redis预减库存 有一个下单请求过来时预减库存 若减完后的redis库存小于0说明已经卖完 此时直接返回客户端已经卖完 后续使用内存标记 减少Redis访问 若预减库存成功 则异步下单 请求
  • FreeRTOS学习---“定时器”篇

    总目录 FreeRTOS学习 任务 篇 FreeRTOS学习 消息队列 篇 FreeRTOS学习 信号量 篇 FreeRTOS学习 事件组 篇 FreeRTOS学习 定时器 篇 FreeRTOS提供了一种软件定时器 用来快速实现一些周期性的
  • 【FreeRTOS 事件】任务通知事件

    普通任务通知事件创建创建及运行 参阅安富莱电子demo define BIT 0 1 lt lt 0 define BIT 1 1 lt lt 1 static TaskHandle t xHandleTaskUserIF NULL sta
  • freeRTOS出现任务卡死的情况。

    最近在做一个产品二代升级的项目 代码是上一任工程师留下的 很多BUG 而且融合了HAL库和LL库 以及github上下载的GSM源码 很不好用 我这边是将2G模块换成了4G 且添加了单独的BLE模块 因此只在源码的基础上 去除2G和BLE代
  • docker安装rocketmq4.6.1(精简版)

    一 创建文件 mkdir p usr local rocketmq server logs usr local rocketmq server store usr local rocketmq broker logs usr local r
  • RabbitMQ(四):RabbitMQ高级特性

    消息队列在使用过程中 面临着很多实际问题需要思考 消息可靠性问题 如何确保发送的消息至少被消费 次 延迟消息问题 如何实现消息的延迟投递 消息堆积问题 如何解决数百万消息堆积 无法及时消费的问题 高可用问题 如何避免单点的MQ故障而导致的不
  • 再论FreeRTOS中的configTOTAL_HEAP_SIZE

    关于任务栈和系统栈的基础知识 可以参考之前的随笔 FreeRTOS 任务栈大小确定及其溢出检测 这里再次说明 define configTOTAL HEAP SIZE size t 17 1024 这个宏 官方文档解释 configTOTA

随机推荐

  • Linux下VNC Server的配置

    1 xff09 安装vnc server xff1a rpm ivh tigervnc server 1 1 0 5 el6 x86 64 rpm 2 修改配置文件 xff0c 1 表示第1号桌面 xff0c 对应端口号5901 2 表示2
  • WIN10_GTX1650_深度学习环境搭建

    这篇博客总结的非常好 xff0c 但安装过程中可能会碰到一些问题 在这记录 xff0c 分享一下解决方案 https blog csdn net weixin 45755980 article details 105397874 Tenso
  • Linux面试必备20个常用命令

    文章目录 第一章 什么是linux第二章 linux的基础命令1 pwd 命令2 ls 命令3 cd 命令4 man 命令5 grep 命令6 find 命令7 chmod 命令8 ps 命令9 kill 命令10 tail 命令11 ne
  • Python爬虫实战(一):翻页爬取数据存入SqlServer

    目录 前言爬取目标准备工作代码分析1 设置翻页2 获取代理ip3 发送请求4 获取详情页地址5 提取详情信息6 存入数据库7 循环实现翻页8 启动 前言 x1f525 x1f525 本文已收录于Python爬虫实战100例专栏 xff1a
  • 已解决error: subprocess-exited-with-error

    已解决 xff08 pip安装第三方模块lxml模块报错 xff09 Building wheels for collected packages lxml Building wheel for lxml setup py error er
  • 已解决此处缺少‘,‘, ‘]‘字符, 实际上是一个 ‘EOF‘

    已解决Python解析JSON xff0c 抛出此处缺少 39 39 39 字符 实际上是一个 39 EOF 异常的解决方法 xff0c 亲测有效 文章目录 报错问题报错原因解决方法千人全栈VIP答疑群联系博主帮忙解决报错 报错问题 粉丝群
  • 已解决E: Unable to locate package ros-kinetic-desktop-full

    已解决Ubuntu安装ros xff0c 抛出异常E Unable to locate package ros kinetic desktop full的正确解决方法 xff0c 亲测有效 xff0c 文末附上Ubuntu系统对应ros系统
  • 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn ) 概论思想(perfect shuffle 算法)

    perfect shuffle 算法 今天又发现一个关于完美洗牌的算法 这个比较简单一些 xff0c 由 microsoft的Peiyush Jain提出 原论文 xff1a A Simple In Place Algorithm for
  • Linux操作系统之命令

    Linux操作系统指令有很多 xff0c 这里就先介绍一些最最基础的吧 首先就是将操作界面显示 xff1a Ctrl 43 alt 43 t 显示当前目录内容 xff1a ls ls l xff1a 将目录内容使用列表显示 ls a xff
  • [操作系统]学习操作系统的经典书籍

    http blog chinaunix net u1 43966 showart 396940 html 介绍了一些操作系统学习的经典书籍 xff0c 包括理论上的 具体操作系统的 Abraham Silberschatz的两本书 xff1
  • 原创:史上最全最通俗易懂的,索引最左前缀匹配原则(认真脸)

    索引最左前缀匹配原则 对于最左前缀匹配原则居然没有百度百科 xff0c 实在是让我感觉不可思议 最左前缀匹配原则 xff0c 用几句话来概述就是 xff1a 顾名思义 xff0c 就是最左优先 xff0c 在创建多列索引时 xff0c 要根
  • MATLAB从文件读取数据

    一 从filename文件读取数据 1 readtable函数 语法 xff1a t 61 readtable xff08 filename xff09 支持的扩展名 xff1a txt csv xls xlsm xlsx xlsm xlt
  • 前端进阶之TS总结

    知识点 高频面试题TS装饰器axios二次封装 1 高频面试题 1 1 类型推论 amp 可赋值性 什么是类型推论 xff1f TypeScript 会在没有明确的指定类型的时候推测出一个类型 xff0c 这就是类型推论如果定义的时候没有赋
  • 岁月清浅,邀你入梦

    这世间本应美好 xff0c 怎无奈痛苦缠身 xff0c 卿心亦真 xff0c 免世人之苦 xff0c 乐自身之本 卿之容 xff0c 多沉醉 xff0c 于心赞 xff0c 日夜思 淡若微风的陪伴 xff0c 奈何情深缘浅 只相识 xff0
  • 记一次解BUG的心得感受

    今天遇到 了 一个 STP的问题 xff0c 从测试 现象 来看与之前一个FR的验证过程中表现出来的特征很相似 这种相似性将我引入了一种歧途 xff1a 怀疑原来的修改有问题 假设你知道第N次修改有潜在的case无法验证 那么这种潜在的风险
  • 02_Keil5报错 error: #5: cannot open source input file “XXX.h”: No such file or directory解决方法

    Keil5 error 5 cannot open source input file led h No such file or directory 是找不到包含文件 解决办法1 包含文件可以解决 解决办法2 如果包含了还是报 5找不到文
  • 05_FreeRTOS中断管理

    目录 什么是中断 中断相关寄存器 源码实验 什么是中断 简介 让CPU打断正常运行的程序 转而去处理紧急的事件 程序 就叫中断 举例 上课可以比做CPU正常运行的程序 上厕所可以比做中断程序 中断执行机制 可简单概括为三步 中断请求 外设产
  • 07_FreeRTOS任务调度器的挂起和恢复

    任务调度器的挂起和恢复 挂起任务调度器 调用此函数不需要关闭中断 使用格式示例 1 与临界区不一样的是 挂起任务调度器 未关闭中断 2 它仅仅是防止 xff1b 任务之间的资源争夺 中断照样可以直接响应 3 挂起调度器的方式 适合于临界区位
  • 09_FreeRTOS任务调度器

    目录 开启任务调度器vTaskStartScheduler函数 xPortStartScheduler开启任务调度器函数 启动第一个任务 prvStartFirstTask开启第一个任务函数 vPortSVCHandler SVC中断服务函
  • 13_FreeRTOS消息队列

    目录 队列简介 FreeRTOS队列特点 队列操作基本过程 队列结构体介绍 队列结构体整体示意图 队列相关API函数介绍 创建队列相关API函数介绍 往队列写入消息API函数 往队列写入消息函数入口参数解析 从队列读取消息API函数 实验源