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基础五:软件定时器

    软件定时器简介 软件定时器的作用 在指定的时间到来时执行指定的函数 或者以某个频率周期性地执行某个函数 被执行的函数叫做软件定时器回调函数 软件定时器由FreeRTOS内核实现 不需要硬件支持 软件定时器只有在软件定时器回调函数被调用时才需
  • 【RabbitMQ】Consumer之消费模式、消息确认与拒绝 - 基于AMQP 0-9-1

    这篇文章主要和大家分享RabbitMQ Consumer端的知识点 主要包括Consumer的消费模式 消息是如何确认以及如何拒绝的 当消息拒绝之后 如何让消息重新进入队列 推模式 RabbitMQ支持推和拉两种消费模式 推模式就是由Bro
  • FreeRTOS,串口中断接收中使用xQueueOverwriteFromISR()函数,程序卡死在configASSERT

    原因 UART的中断优先级设置的太高 高于了configMAX SYSCALL INTERRUPT PRIORITY宏定义的安全中断等级 UART的中断等级小于等于宏定义的优先等级即可
  • php消息队列的应用

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

    异常现象 监控日志展示如下 2019 10 30 14 31 23 339 INFO ConsumeMessageThread 7 com xxx service mq MQConsumerService 93 消费消息 msgId 0A0
  • FreeRTOS之事件

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

    打开啊哈C 新建一个程序输出hello world include
  • 代码技巧——如何关闭订单?延迟任务的实现方案【建议收藏】

    先思考个问题 为什么要关闭订单 业务上 1 提供待付款时间 而不是简单的 一次付款机会 提高业务指标之一的成单率 成单率 成功下单的人数 发起支付的人数 2 下单成功意味着这个商品被当前订单占用 库存已经预扣减 如果迟迟不支付则需要回收库存
  • FreeRTOS笔记(十)中断

    中断 当CPU在执行某一事件A时 发生另外一个更重要紧急的事件B请求CPU去处理 产生了中断 于是CPU暂时中断当前正在执行的事件A任务而对对事件B进行处理 CPU处理完事件B后再返回之前中断的位置继续执行原来的事件A 这一过程统称为中断
  • FreeRTOS学习笔记(8)---- 软件定时器

    使用FreeRTOS软件定时器需要在文件FreeRTOSConfig h先做如下配置 1 configUSE TIMERS 使能软件定时器 2 configTIMER TASK PRIORITY 定时器任务优先级 3 configTIMER
  • 秒杀系统中常见问题及解决方案

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

    简介 RocketMQ是由阿里捐赠给Apache的一款低延迟 高并发 高可用 高可靠的分布式消息中间件 经历了淘宝双十一的洗礼 RocketMQ既可为分布式应用系统提供异步解耦和削峰填谷的能力 同时也具备互联网应用所需的海量消息堆积 高吞吐
  • FreeRTOS笔记(二)

    FreeRTOS笔记 二 静态任务 文章目录 FreeRTOS笔记 二 静态任务 一 任务定义 二 任务创建 2 1 定义任务栈 2 2 定义任务函数 2 3 定义任务控制块 2 4 实现任务创建函数 三 实现就绪列表 3 1 定义就绪列表
  • RocketMQ第四篇 Rocket集群配置

    在实际开发中一般都会使用docker安装rocketMQ docker安装rocketmq如下 docker安装配置rocketmq docker安装rocketmq docker pull foxiswho rocketmq server
  • kafka系列——KafkaProducer源码分析

    实例化过程 在KafkaProducer的构造方法中 根据配置项主要完成以下对象或数据结构的实例化 配置项中解析出 clientId 用于跟踪程序运行情况 在有多个KafkProducer时 若没有配置 client id则clientId
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • 如何更改 FreeRTOS 中任务的最大可用堆大小?

    我通过以下方式在任务中创建元素列表 l dllist pvPortMalloc sizeof dllist dlllist 有 32 字节大 我的嵌入式系统有 60kB SRAM 所以我希望系统可以轻松处理我的 200 个元素列表 我发现在
  • 防止GCC LTO删除函数

    我使用 GCC ARM Embedded 和 FreeRTOS FreeRTOS具有的功能vTaskSwitchContext 仅在某些情况下使用 内联汇编代码 问题是 当我使用LTO时 GCC不考虑内联汇编代码并认为该函数没有被使用 因此
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J

随机推荐

  • 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函数 实验源