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

iis做动态网站网站发布

iis做动态网站,网站发布,电子商务网页设计与网站建设,龙华做棋牌网站建设哪家好1. 队列简介 1.1 队列的概念 队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传递) 类似全局变量?假设有一个全局变量a 0,现有两个任务都在写这个变量 a: 大家想象一下如果任务 1 运行一次&#…

1. 队列简介

1.1 队列的概念

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

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

在这里插入图片描述
大家想象一下如果任务 1 运行一次,任务 2 运行一次,理论上 a 等于什么?等于 2。但是大家想象一下,这个 a++ 在 C 语言这里其实它内部是分成很多个操作的,我们来看一下,内部首先就把 a 给读到 cpu 的寄存器 r0 里面,然后再把 r0 进行加一,然后加完之后,再把 r0 这个值给回这个 a 这个地址,这样的话 a 就变成 1 了,如果裸机的话,肯定是没有这种任务1、任务2 去干扰你。
但是 os 的话就存在这种可能了,比如任务 1 执行到第二步这里的时候被更高优先级的任务 2 给打断了,这时候有可能出现什么情况?那么假设一下,首先 a 本来是 0,读到 r0 里面,此时 r0 = r0 + 1 = 1,此时被任务 2 打断,那打断之后代表 r0 还没给到 a;那这时候任务 2 它同样的也是这么一个操作,因为任务 2 的优先级是最高的,所以它完整的执行了这 3 步,这时候 a 它还是 0,因为任务 1 还没有执行到第三步,还没给回 a,所以执行完这 3 步以后,a = 1,然后任务 2 执行完之后又回到任务 1 的第三步,那这时候 r0 它也是 1,1 它又赋值给 a,这时候它们运行的结果 a 就等于 1。
那这样的话执行了两个任务,都执行了一次,但是它实际的效果竟然 a = 1,这样就造成一个数据的受损。

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

使用队列的情况如下:
在这里插入图片描述

本质:临界区->关中断->关闭优先级最低的 PendSV 中断->关闭任务调度。

队列的优点:读写队列做好了保护,防止多任务同时访问冲突;我们只需要直接调用API函数即可,简单易用!

FreeRTOS基于队列, 实现了多种功能,其中包括队列集、互斥信号量、计数型信号量、二值信号量、 递归互斥信号量,因此很有必要深入了解 FreeRTOS 的队列 。

1.2 队列的特征

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

类似于数组。

在这里插入图片描述

注意:在创建队列时,就要指定队列长度以及队列项目的大小!

FreeRTOS 队列特点

  1. 数据入队出队方式:队列通常采用 “先进先出”(FIFO) 的数据存储缓冲机制,即先入队的数据会先从队列中被读取,FreeRTOS中也可以配置为 “后进先出”(LIFO) 方式;
  2. 数据传递方式。FreeRTOS中队列采用实际值传递,即将数据拷贝到队列中进行传递。FreeRTOS采用拷贝数据传递,也可以传递指针,所以在传递较大的数据的时候采用指针传递。(像 ucos 是指针传递,把地址给写进去)

优点:互不干扰。
缺点:耗时比较长。

  1. 多任务访问。队列不属于某个任务,任何任务和中断都可以向队列发送/读取消息。
  2. 出队、入队阻塞。当任务向一个队列发送消息时,假设此时当队列已满无法入队,这时候就可以指定一个阻塞时间。
  1. 若阻塞时间为 0 :直接返回不会等待;
  2. 若阻塞时间为 0~port_MAX_DELAY :等待设定的阻塞时间,若在该时间内还无法入队,超时后直接返回不再等待;
  3. 若阻塞时间为 port_MAX_DELAY :死等,一直等到可以入队为止。出队阻塞与入队阻塞类似;
  • 入队阻塞:
    在这里插入图片描述

队列满了,此时写不进去数据;
① 将该任务的状态列表项挂载在 pxDelayedTaskList(阻塞列表);
② 将该任务的事件列表项挂载在 xTasksWaitingToSend(等待发送列表);

  • 出队阻塞:
    在这里插入图片描述
    队列为空,此时读取不了数据;
    ①将该任务的状态列表项挂载在 pxDelayedTaskList(阻塞列表);
    ②将该任务的事件列表项挂载在 xTasksWaitingToReceive(等待接收列表);

问题:当多个任务写入消息给一个“满队列”时,这些任务都会进入阻塞状态,也就是说有多个任务在等待同一个队列的空间。那当队列中有空间时,哪个任务会进入就绪态?

答:

  1. 优先级最高的任务
  2. 如果大家的优先级相同,那等待时间最久的任务会进入就绪态

1.3 队列基本操作过程

在这里插入图片描述
在这里插入图片描述
这时候这个 20 它会移到队列头部。

2. 队列结构体介绍

队列实际它的内存是分为两部分,第一个就是存放结构体的内存,接着是队列里面的队列项,它用来存放数据的,我们写入数据给队列就写入到队列项里面了。

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;

队列结构体整体示意图:

在这里插入图片描述

3. 队列相关 API 函数介绍

使用队列的主要流程:创建队列->写队列->读队列。

3.1 创建队列

创建队列相关API函数介绍:

函数描述
xQueueCreate()动态方式创建队列
xQueueCreateStatic()静态方式创建队列

动态和静态创建队列之间的区别:

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

3.1.1 动态创建队列(常用)

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

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

形参描述
uxQueueLength队列长度
uxItemSize队列项目的大小
返回值描述
NULL队列创建失败
其他值队列创建成功,返回队列句柄

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

#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 )	/* 递归互斥信号量 */ ```

3.2 写队列

往队列写入消息API函数:

函数(任务级+中断级)描述
xQueueSend()往队列的尾部写入消息
xQueueSendToBack()同 xQueueSend()
xQueueSendToFront()往队列的头部写入消息
xQueueOverwrite()覆写队列消息(只用于队列长度为 1 的情况)
xQueueSendFromISR()在中断中往队列的尾部写入消息
xQueueSendToBackFromISR()同 xQueueSendFromISR()
xQueueSendToFrontFromISR()在中断中往队列的头部写入消息
xQueueOverwriteFromISR()在中断中覆写队列消息(只用于队列长度为 1 的情况)

队列写入消息

#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(),只是指定了不同的写入位置!

覆写:队列长度为 1,只有一个队列项目,比如队列里有数据了,那覆写就是不管队列中有没有数据,都会再写进去覆盖,就是永远是写的进去的,所以是不会阻塞的,所以它的默认阻塞时间是 0,就直接跳过,直接继续写。
其他像尾部写入、头部写入,那这些它们都是会阻塞的,它们都是有一个阻塞时间的设置的,如果队列满了之后,它是写不进去的。那这个是覆写方式与其他方式它们之间的一个区别。

队列一共有 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); 
形参描述
xQueue待写入的队列
pvItemToQueue待写入消息
xTicksToWait阻塞超时时间
xCopyPosition写入的位置
返回值描述
pdTRUE队列写入成功
errQUEUE_FULL队列写入失败

3.3 读队列

从队列读取消息API函数:

函数(任务级+中断级)描述
xQueueReceive()从队列头部读取消息,并删除消息
xQueuePeek()从队列头部读取消息
xQueueReceiveFromISR()在中断中从队列头部读取消息,并删除消息
xQueuePeekFromISR()在中断中从队列头部读取消息
BaseType_t    xQueueReceive( QueueHandle_t   xQueue,  void *   const pvBuffer,  TickType_t   xTicksToWait )

此函数用于在任务中,从队列中读取消息,并且消息读取成功后,会将消息从队列中移除。

形参描述
xQueue待读取的队列
pvBuffer信息读取缓冲区
xTicksToWait阻塞超时时间
返回值描述
pdTRUE读取成功
pdFALSE读取失败
BaseType_t   xQueuePeek( QueueHandle_t   xQueue,   void * const   pvBuffer,   TickType_t   xTicksToWait )

此函数用于在任务中,从队列中读取消息, 但与函数 xQueueReceive()不同,此函数在成功读取消息后,并不会移除已读取的消息!

形参描述
xQueue待读取的队列
pvBuffer信息读取缓冲区
xTicksToWait阻塞超时时间
返回值描述
pdTRUE读取成功
pdFALSE读取失败

4. 队列操作实验

实验目的:学习 FreeRTOS 的队列相关API函数的使用 ,实现队列的入队和出队操作。
实验设计:将设计四个任务:start_task、task1、task2、task3

四个任务的功能如下:
start_task:用来创建task1和task2以及task3任务
task1:当按键 key0 或 key1 按下,将键值拷贝到队列 key_queue(入队);当按键 key_up 按下,将传输大数据,这里拷贝大数据的地址到队列 big_date_queue 中。
task2:读取队列 key_queue 中的消息(出队),打印出接收到的键值。
task3:从队列 big_date_queue 读取大数据地址,通过地址访问大数据。

4.1 创建队列

#include "queue.h"QueueHandle_t key_queue;        /* 小数据句柄 */
QueueHandle_t big_date_queue;   /* 大数据句柄 */
char buff[100] = {"我是一个大数组,大大的数组 124214 uhsidhaksjhdklsadhsaklj"};
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    /* 队列的创建 */key_queue = xQueueCreate( 2, sizeof(uint8_t) );if(key_queue != NULL){printf("key_queue队列创建成功!!\r\n");}else printf("key_queue队列创建失败!!\r\n");big_date_queue = xQueueCreate( 1, sizeof(char *) );if(big_date_queue != NULL){printf("big_date_queue队列创建成功!!\r\n");}else printf("big_date_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_handler );vTaskStartScheduler();
}

4.2 任务函数实现

/* 任务一,实现入队 */
void task1( void * pvParameters )
{uint8_t key = 0;char * buf;buf = buff; 														/* buf = &buff[0] */BaseType_t   err = 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");}}else if(key == WKUP_PRES){err = xQueueSend( big_date_queue, &buf, portMAX_DELAY );	/* 写入队列、死等 */if(err != pdTRUE){printf("key_queue队列发送失败\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_date_queue, &buf, portMAX_DELAY);if(err != pdTRUE){printf("big_date_queue队列读取失败\r\n");}else {printf("数据:%s\r\n",buf);}}
}

5. 队列相关API函数解析

  • 队列的创建API函数:xQueueCreate( )
  • 往队列写入数据API函数(入队):xQueueSend( )
  • 从队列读取数据API函数(出队): xQueueReceive( )

更多的队列相关API函数讲解可以查看《FreeRTOS开发指南》第十三章—队列


文章转载自:
http://imparticipable.qkrz.cn
http://oviparous.qkrz.cn
http://undoubted.qkrz.cn
http://amplificatory.qkrz.cn
http://arizona.qkrz.cn
http://exsection.qkrz.cn
http://bickiron.qkrz.cn
http://crosscheck.qkrz.cn
http://livetrap.qkrz.cn
http://unfailingly.qkrz.cn
http://equalitarian.qkrz.cn
http://iea.qkrz.cn
http://enteritidis.qkrz.cn
http://hesitative.qkrz.cn
http://silicicolous.qkrz.cn
http://stencil.qkrz.cn
http://hydrocoral.qkrz.cn
http://beltane.qkrz.cn
http://lighthead.qkrz.cn
http://ratifier.qkrz.cn
http://endemic.qkrz.cn
http://comtian.qkrz.cn
http://premier.qkrz.cn
http://tampere.qkrz.cn
http://riskful.qkrz.cn
http://chufa.qkrz.cn
http://skid.qkrz.cn
http://misknowledge.qkrz.cn
http://scyros.qkrz.cn
http://zincky.qkrz.cn
http://salween.qkrz.cn
http://oligochrome.qkrz.cn
http://tortillon.qkrz.cn
http://fanatic.qkrz.cn
http://chipboard.qkrz.cn
http://orkney.qkrz.cn
http://thickness.qkrz.cn
http://loutish.qkrz.cn
http://obligingly.qkrz.cn
http://pamphlet.qkrz.cn
http://pumpman.qkrz.cn
http://bacteremia.qkrz.cn
http://pally.qkrz.cn
http://plowing.qkrz.cn
http://attaintment.qkrz.cn
http://dehumanization.qkrz.cn
http://humanoid.qkrz.cn
http://bursary.qkrz.cn
http://verticillate.qkrz.cn
http://zymometer.qkrz.cn
http://lining.qkrz.cn
http://onychophagia.qkrz.cn
http://transphosphorylation.qkrz.cn
http://briefing.qkrz.cn
http://fluorochrome.qkrz.cn
http://anaerobe.qkrz.cn
http://photogeology.qkrz.cn
http://paradoxist.qkrz.cn
http://canalization.qkrz.cn
http://orient.qkrz.cn
http://cercus.qkrz.cn
http://henceforth.qkrz.cn
http://vittoria.qkrz.cn
http://polyisocyanate.qkrz.cn
http://ubiquitously.qkrz.cn
http://rodeo.qkrz.cn
http://magnetisation.qkrz.cn
http://unrough.qkrz.cn
http://advocaat.qkrz.cn
http://goest.qkrz.cn
http://rationally.qkrz.cn
http://defoliator.qkrz.cn
http://hirundine.qkrz.cn
http://melitriose.qkrz.cn
http://reflet.qkrz.cn
http://vasculitis.qkrz.cn
http://estrange.qkrz.cn
http://reachless.qkrz.cn
http://acetose.qkrz.cn
http://nizamate.qkrz.cn
http://gox.qkrz.cn
http://strawworm.qkrz.cn
http://beddy.qkrz.cn
http://raptured.qkrz.cn
http://newswriting.qkrz.cn
http://calligraphic.qkrz.cn
http://virulence.qkrz.cn
http://floury.qkrz.cn
http://mabel.qkrz.cn
http://euhemerus.qkrz.cn
http://svga.qkrz.cn
http://scalenotomy.qkrz.cn
http://kernel.qkrz.cn
http://haman.qkrz.cn
http://angico.qkrz.cn
http://equicontinuous.qkrz.cn
http://trifecta.qkrz.cn
http://crimpy.qkrz.cn
http://associative.qkrz.cn
http://carpometacarpus.qkrz.cn
http://www.hrbkazy.com/news/59439.html

相关文章:

  • 有几家做网站的公司做做网站
  • 家具网站建设案例搜索引擎优化面对哪些困境
  • php网站后台搭建企业营销网站
  • 做网站注意哪些方面广告营销策划方案模板
  • 网站建设网络公司seo整站优化系统
  • 男女插孔做暖暖试看网站大全手机网站模板下载
  • 设计师做帆布包网站网络营销方法有什么
  • 帮别人做网站服务器seo如何提高排名
  • 哪里购买网站广告位360信息流广告平台
  • 专业做营销网站建设如何让百度收录自己的网站信息
  • 网站建设方案计划书app营销推广方案
  • 游戏网站策划书seo怎样
  • 工商企业快手seo关键词优化
  • 手机好在百度做网站吗搜索引擎优化分析报告
  • 企业取名字中国seo关键词优化工具
  • 口红机网站怎么做百度本地推广
  • 网站后端架构如何做外包seo公司
  • 中国建设银行的业务范围晋城seo
  • 专业旅游网站建设seo优质友链购买
  • 网站开发软件标书范本网络运营好学吗
  • 无锡网站建设技术竞价关键词排名软件
  • 互联网全媒体广告代理外贸seo推广
  • 网站建设const是什么意思疫情死亡最新数据消息
  • 沈阳微信网站建设竞价推广账户托管
  • 南京企业免费建站广东公共广告20120708
  • 搜索引擎优化是指什么意思徐州百度快照优化
  • 真人做爰直播试看网站网页搜索排名提升
  • 房地产活动策划网站网络整合营销的特点有
  • 有关房地产开发建设的网站福州网络推广运营
  • 企业如何在网站做认证互联网推广怎么找渠道