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

安阳网站建设公司网站建站哪家公司好

安阳网站建设公司,网站建站哪家公司好,做修图网站电脑配置,忻州网站制作一、简介 1、队列简介: 队列:是任务到任务,任务到中断、中断到任务数据交流的一种机制(消息传递)。 FreeRTOS基于队列,实现了多种功能,其中包括队列集、互斥信号量、计数型信号量、二值信号量…

一、简介

1、队列简介:

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

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

(中断一关闭,就不会出现任务切换,以防多个任务同时操作队列) 

2、FreeRTOS队列特点:

                        1.数据入队出队方式:先进先出

                        2.数据传递方式:实际值

                        3.多任务访问

                        4. 出队、入队堵塞

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

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

注:我始终认为自己不是一个很聪明的人,所以这些理论知识,我都是浅尝辄止,量力而行。

3、往队列写入消息API函数 :

4、从队列读取消息API函数: 

 二、实验

1、实验步骤

2、代码: 

main.c

#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h"
#include "freertos_demo.h"
#include "Delay.h"
#include "sys.h"
#include "usart.h"
#include "LED.h"
#include "Key.h"int main(void){	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4 uart_init(115200);	 delay_init();Key_Init();LED_Init();// 创建任务FrrrRTOS_Demo();}

freertos_demo.c 

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO					1
//任务堆栈大小	
#define START_TASK_STACK_SIZE 	128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define TASK1_PRIO							2
//任务堆栈大小	
#define TASK1_STACK_SIZE 				128  
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);//任务优先级
#define TASK2_PRIO							3
//任务堆栈大小	
#define TASK2_STACK_SIZE 				128  
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);//任务优先级
#define TASK3_PRIO							4
//任务堆栈大小	
#define TASK3_STACK_SIZE 				128  
//任务句柄
TaskHandle_t Task3_Handler;
//任务函数
void task3(void *pvParameters);char  task_buffer[500]; 							//用于存储系统中任务信息表格/******************************************************************任务函数****************************************************/
QueueHandle_t		key_queue; 						//小数据句柄
QueueHandle_t		big_data_queue; 			//大数据	句柄
char buff[100] = {"苍天已死,黄天当立;岁在甲子,天下大吉"};
void FrrrRTOS_Demo(void)
{key_queue = xQueueCreate(2, sizeof(uint8_t));if(key_queue != NULL){printf("\r\nkey_queue队列创建成功!!!\r\n");}else{ printf("key_queue队列创建失败!!!\r\n");	}big_data_queue = xQueueCreate(1, sizeof(char *));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",          			//任务名称(uint16_t       )START_TASK_STACK_SIZE, 			//任务堆栈大小(void*          )NULL,                  			//传递给任务函数的参数(UBaseType_t    )START_TASK_PRIO,       			//任务优先级(TaskHandle_t*  )&StartTask_Handler);   			//任务句柄 // 启动任务调度vTaskStartScheduler();}void start_task(void *pvParameters)
{taskENTER_CRITICAL();           //进入临界区//创建1任务xTaskCreate((TaskFunction_t )task1,     	(const char*    )"task1",   	(uint16_t       )TASK1_STACK_SIZE, (void*          )NULL,				(UBaseType_t    )TASK1_PRIO,	(TaskHandle_t*  )&Task1_Handler); //创建2任务xTaskCreate((TaskFunction_t )task2,     (const char*    )"task2",   (uint16_t       )TASK2_STACK_SIZE, (void*          )NULL,(UBaseType_t    )TASK2_PRIO,(TaskHandle_t*  )&Task2_Handler);    //创建3任务xTaskCreate((TaskFunction_t )task3,     (const char*    )"task3",   (uint16_t       )TASK3_STACK_SIZE, (void*          )NULL,(UBaseType_t    )TASK3_PRIO,(TaskHandle_t*  )&Task3_Handler);  								vTaskDelete(NULL); 							//删除开始任务taskEXIT_CRITICAL();            //退出临界区
}//1 任务函数
void task1(void *pvParameters)
{uint8_t 	 key = 0;BaseType_t err;char *buf;buf = &buff[0];while(1){key = Key_GetNum();if(key == 1 || key == 2){err = xQueueSend( key_queue, &key, portMAX_DELAY );if(err != pdTRUE){printf("key_queue队列发送失败\r\n");}}else if(key == 3){err = xQueueSend( big_data_queue, &buf, portMAX_DELAY );if(err != pdTRUE){printf("key_queue队列发送失败\r\n");}}vTaskDelay(50);}
}// 任务2 小数据出队函数
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 = %d\r\n",key);};}
}//不调用系统延时函数,因为xQueueReceive()函数如果读取完队列里面的数据,就会由就绪态转变为阻塞态;// 任务3 大数据出队函数
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("key = %s\r\n",buf);};}
}

 key.c

#include "stm32f10x.h"                  // Device header
#include "FreeRTOS.h"
#include "task.h"
#include "usart.h"
#include "Delay.h"/*** 函    数:按键初始化* 参    数:无* 返 回 值:无* 按键:PB4/PB12/PB14*/
void Key_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟/*GPIO初始化*/GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_4 | GPIO_Pin_12 | GPIO_Pin_14;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);					}/*** 函    数:按键获取键码* 参    数:无* 返 回 值:按下按键的键码值,范围:0~3,返回0代表没有按键按下* 注意事项:此函数是阻塞式操作,当按键按住不放时,函数会卡住,直到按键松手*/
uint8_t Key_GetNum(void)
{uint8_t KeyNum = 0;																				//定义变量,默认键码值为0if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 0)			  //读PB4输入寄存器的状态,如果为0,则代表按键1按下{KeyNum= GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4);printf("KeyNum = %d\r\n",KeyNum);delay_xms(20);																					//延时消抖while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 0);	//等待按键松手delay_xms(20);																					//延时消抖KeyNum = 1;																							//置键码为1}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) == 0)			{KeyNum= GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);printf("KeyNum = %d\r\n",KeyNum);delay_xms(20);											while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) == 0);	delay_xms(20);									KeyNum = 2;											}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)			{KeyNum= GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14);printf("KeyNum = %d\r\n",KeyNum);delay_xms(20);											while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0);	delay_xms(20);									KeyNum = 3;											}return KeyNum;																						//返回键码值,如果没有按键按下,所有if都不成立,则键码为默认值0
}

 3、实验结果解析

开始运行:

按下按键1(PB4):

按下按键1,就会往队列key_queue里面写入key值(1),然后任务切换到task2将队列key_queue里面的数据读取出来;;

按下按键2(PB12):

按下按键2,就会往队列key_queue里面写入key值(2),然后任务切换到task2将队列key_queue里面的数据读取出来;

按下按键3(PB14) :

按下按键2,就会往队列big_data_queue里面写入key值(3),然后任务切换到task3将队列big_data_queue里面的数据读取出来;

三、重点 

使用队列相关函数时需要将下面宏置1(默认是1):

    #define configSUPPORT_DYNAMIC_ALLOCATION    1

 队列创建函数:

xQueueCreate( uxQueueLength, uxItemSize ) ;               //uxQueueLength:队列长度;uxItemSize 队列参数的大小

队列写入消息函数:

xQueueSend( xQueue, pvItemToQueue, xTicksToWait );        //xQueue:待写入的队列;pvItemToQueue:待写入的消息;xTicksToWait:阻塞超时时间

队列读取消息函数:

xQueueReceive( QueueHandle_t xQueue,void * const pvBuffer,TickType_t xTicksToWait ) ;          //xQueue:待读取的队列;pvBuffer:信息读取缓冲区;xTicksToWait:阻塞超时时间

问题:任务2(task2)和任务3(task3)没有系统延时函数(xTaskDelay()),按优先级来说应该一直执行任务3(task3),复位后却先执行了任务1(task1)?

答:因为xQueueReceive()和xQueueSend()函数,如果读取完或写入完队列里面的数据,自动会使任务由就绪态转变为阻塞态,知道队列里面有数据可以写入或者读出;

http://www.dtcms.com/wzjs/464499.html

相关文章:

  • 关于政府网站建设的讲话郑州网络推广厂家
  • 南山区网站建设公司长尾关键词挖掘爱站网
  • 网站建设的风险windows优化大师会员
  • 中国城乡住房建设部网站百度客服在线咨询电话
  • 做网站需要注册公司吗中国国家培训网靠谱吗
  • 新疆模板网站建设seo关键词搜索和优化
  • 自媒体人专用网站苏州seo网站优化软件
  • 外贸公司网站源码外贸建站平台
  • 长沙装修公司排名十强seo是什么字
  • 自己做网站买竞价推广外包托管
  • 网站设计好不好社群营销
  • 手机wap网站制作扬州百度推广公司
  • 淘客建站程序40个免费靠谱网站
  • 微商城开发小程序开发seo81
  • 公司网站域名实名认证怎么做怎么在百度上推广
  • 一元购网站怎么做竞价防恶意点击
  • 5个在线设计网站广州seo网站排名
  • wordpress培训机构主题宁波seo推广外包公司
  • 我的世界是怎么做的视频网站拉新推广怎么做
  • 有人做几个蝎子养殖门户网站怎么做网络营销推广
  • nginx设置wordpress伪静态seo短视频保密路线
  • vs2017 网站开发环境站长工具站长之家官网
  • 网站攻击市场调研的重要性
  • 做一下网站需要什么条件广告联盟怎么加入
  • 免费建手机网站后台免费做网站推广的软件
  • 化妆品 网站建设案例google搜索引擎
  • 做美食网站的项目背景seo教程免费
  • wordpress 好主题哦seo网上培训课程
  • 网站上线有什么线上活动可以做公司网站推广方案
  • 官方网站、门户网站是什么意思?腾讯企点注册